Bug 811812 - Sacrifice virtualenv population output to TBPL gods; r=ted
authorGregory Szorc <gps@mozilla.com>
Tue, 27 Nov 2012 12:25:55 -0800
changeset 114267 0e37dbe22164e4856a8312e3e486c40afa317162
parent 114266 c3d44fd7dce4c609f1e719848d16acb0e556c050
child 114268 93ca9158ae3e2975714630d6a1daeb56fb538292
push id23913
push useremorley@mozilla.com
push dateWed, 28 Nov 2012 17:11:31 +0000
treeherdermozilla-central@17c267a881cf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs811812
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 811812 - Sacrifice virtualenv population output to TBPL gods; r=ted We rewrite an ignorable error message on missing Python headers so TBPL won't misreport as an actual build error.
build/virtualenv/populate_virtualenv.py
--- a/build/virtualenv/populate_virtualenv.py
+++ b/build/virtualenv/populate_virtualenv.py
@@ -236,22 +236,33 @@ class VirtualenvManager(object):
     def call_setup(self, directory, arguments):
         """Calls setup.py in a directory."""
         setup = os.path.join(directory, 'setup.py')
 
         program = [sys.executable, setup]
         program.extend(arguments)
 
         # We probably could call the contents of this file inside the context
-        # of # this interpreter using execfile() or similar. However, if global
+        # of this interpreter using execfile() or similar. However, if global
         # variables like sys.path are adjusted, this could cause all kinds of
         # havoc. While this may work, invoking a new process is safer.
-        result = subprocess.call(program, cwd=directory)
+
+        # TODO Use check_output when we require Python 2.7.
+        fn = getattr(subprocess, 'check_output',
+                VirtualenvManager._check_output)
 
-        if result != 0:
+        try:
+            output = fn(program, cwd=directory, stderr=subprocess.STDOUT)
+            print(output)
+        except subprocess.CalledProcessError as e:
+            if 'Python.h: No such file or directory' in e.output:
+                print('WARNING: Python.h not found. Install Python development headers.')
+            else:
+                print(e.output)
+
             raise Exception('Error installing package: %s' % directory)
 
     def build(self):
         """Build a virtualenv per tree conventions.
 
         This returns the path of the created virtualenv.
         """
 
@@ -278,16 +289,31 @@ class VirtualenvManager(object):
 
         If you run a random Python script and wish to "activate" the
         virtualenv, you can simply instantiate an instance of this class
         and call .ensure() and .activate() to make the virtualenv active.
         """
 
         execfile(self.activate_path, dict(__file__=self.activate_path))
 
+    # TODO Eliminate when we require Python 2.7.
+    @staticmethod
+    def _check_output(*args, **kwargs):
+        """Python 2.6 compatible implementation of subprocess.check_output."""
+        proc = subprocess.Popen(stdout=subprocess.PIPE, *args, **kwargs)
+        output, unused_err = proc.communicate()
+        retcode = proc.poll()
+        if retcode:
+            cmd = kwargs.get('args', args[0])
+            e = subprocess.CalledProcessError(retcode, cmd)
+            e.output = output
+            raise e
+
+        return output
+
 
 def verify_python_version(log_handle):
     """Ensure the current version of Python is sufficient."""
     major, minor = sys.version_info[:2]
 
     if major != MINIMUM_PYTHON_MAJOR or minor < MINIMUM_PYTHON_MINOR:
         log_handle.write('Python %d.%d or greater (but not Python 3) is '
             'required to build. ' %