Bug 1396582 - Move Python version checking to moz.configure; r?Build draft
authorGregory Szorc <gps@mozilla.com>
Mon, 08 Jan 2018 15:46:35 -0800
changeset 717445 57d85edf605daeedadd47efd24f7be4c754fcb12
parent 717422 05fed903f40f05fd923ba2137696ecc1fa0bafe6
child 717446 c2e3eb36c17a889f741eac5ca9db782e13ed69c5
push id94676
push userbmo:gps@mozilla.com
push dateMon, 08 Jan 2018 23:49:47 +0000
reviewersBuild
bugs1396582
milestone59.0a1
Bug 1396582 - Move Python version checking to moz.configure; r?Build The Python version validation in virtualenv.py is only called in 2 locations: `python -m mozbuild.virtualenv` and in moz.configure. I believe that nobody calls `python -m mozbuild.virtualenv` any more. That means that moz.configure is the only caller of verify_python_version(). That means we can inline the logic into moz.configure. It makes sense for version checking to live in moz.configure because the role of moz.configure is to evaluate the sanity of the environment. So this commit does just that. MozReview-Commit-ID: 7FLL0cGblFS
build/moz.configure/init.configure
python/mozbuild/mozbuild/virtualenv.py
--- a/build/moz.configure/init.configure
+++ b/build/moz.configure/init.configure
@@ -198,17 +198,16 @@ option(env='PYTHON', nargs=1, help='Pyth
 
 
 @depends('PYTHON', check_build_environment, mozconfig, '--help')
 @imports('os')
 @imports('sys')
 @imports('subprocess')
 @imports(_from='mozbuild.configure.util', _import='LineIO')
 @imports(_from='mozbuild.virtualenv', _import='VirtualenvManager')
-@imports(_from='mozbuild.virtualenv', _import='verify_python_version')
 @imports('distutils.sysconfig')
 def virtualenv_python(env_python, build_env, mozconfig, help):
     if help:
         return
 
     python = env_python[0] if env_python else None
 
     # Ideally we'd rely on the mozconfig injection from mozconfig_options,
@@ -219,18 +218,38 @@ def virtualenv_python(env_python, build_
             python = mozconfig['env']['added']['PYTHON']
         elif 'PYTHON' in mozconfig['env']['modified']:
             python = mozconfig['env']['modified']['PYTHON'][1]
         elif 'PYTHON' in mozconfig['vars']['added']:
             python = mozconfig['vars']['added']['PYTHON']
         elif 'PYTHON' in mozconfig['vars']['modified']:
             python = mozconfig['vars']['modified']['PYTHON'][1]
 
-    with LineIO(lambda l: log.error(l)) as out:
-        verify_python_version(out)
+    minimum_version = Version('2.7.3')
+    major, minor, micro = sys.version_info[:3]
+    our_version = Version('%d.%d.%d' % (major, minor, micro))
+
+    if major != 2 or our_version < minimum_version:
+        msg = ('Python %s or greater (but not Python 3) is required to build. '
+              'You are running Python %s. ' % (minimum_version, our_version))
+
+        if os.name == 'nt':
+            msg += ('Please upgrade to the latest MozillaBuild development '
+                   'environment. See https://developer.mozilla.org/en-US/docs/Developer_Guide/Build_Instructions/Windows_Prerequisites')
+        else:
+            msg += ('Run `mach bootstrap` to ensure your system is up to date. '
+                   'If you still receive this error afterwards, your shell '
+                   'environment is likely detecting another Python version. '
+                   'Ensure a modern Python can be found in the paths defined '
+                   'by the $PATH environment variable. Or set the PYTHON '
+                   'environment or mozconfig variable to specify which Python '
+                   'interpreter to use.')
+
+        die(msg)
+
     topsrcdir, topobjdir = build_env.topsrcdir, build_env.topobjdir
     if topobjdir.endswith('/js/src'):
         topobjdir = topobjdir[:-7]
 
     with LineIO(lambda l: log.info(l), 'replace') as out:
         manager = VirtualenvManager(
             topsrcdir, topobjdir,
             os.path.join(topobjdir, '_virtualenv'), out,
--- a/python/mozbuild/mozbuild/virtualenv.py
+++ b/python/mozbuild/mozbuild/virtualenv.py
@@ -15,34 +15,16 @@ import sys
 import warnings
 
 from distutils.version import LooseVersion
 
 IS_NATIVE_WIN = (sys.platform == 'win32' and os.sep == '\\')
 IS_MSYS2 = (sys.platform == 'win32' and os.sep == '/')
 IS_CYGWIN = (sys.platform == 'cygwin')
 
-# Minimum version of Python required to build.
-MINIMUM_PYTHON_VERSION = LooseVersion('2.7.3')
-MINIMUM_PYTHON_MAJOR = 2
-
-
-UPGRADE_WINDOWS = '''
-Please upgrade to the latest MozillaBuild development environment. See
-https://developer.mozilla.org/en-US/docs/Developer_Guide/Build_Instructions/Windows_Prerequisites
-'''.lstrip()
-
-UPGRADE_OTHER = '''
-Run |mach bootstrap| to ensure your system is up to date.
-
-If you still receive this error, your shell environment is likely detecting
-another Python version. Ensure a modern Python can be found in the paths
-defined by the $PATH environment variable and try again.
-'''.lstrip()
-
 
 class VirtualenvManager(object):
     """Contains logic for managing virtualenvs for building the tree."""
 
     def __init__(self, topsrcdir, topobjdir, virtualenv_path, log_handle,
         manifest_path):
         """Create a new manager.
 
@@ -520,42 +502,21 @@ class VirtualenvManager(object):
         # against the executing interpreter. By creating a new process, we
         # force the virtualenv's interpreter to be used and all is well.
         # It /might/ be possible to cheat and set sys.executable to
         # self.python_path. However, this seems more risk than it's worth.
         subprocess.check_call([os.path.join(self.bin_path, 'pip')] + args,
             stderr=subprocess.STDOUT)
 
 
-def verify_python_version(log_handle):
-    """Ensure the current version of Python is sufficient."""
-    major, minor, micro = sys.version_info[:3]
-
-    our = LooseVersion('%d.%d.%d' % (major, minor, micro))
-
-    if major != MINIMUM_PYTHON_MAJOR or our < MINIMUM_PYTHON_VERSION:
-        log_handle.write('Python %s or greater (but not Python 3) is '
-            'required to build. ' % MINIMUM_PYTHON_VERSION)
-        log_handle.write('You are running Python %s.\n' % our)
-
-        if os.name in ('nt', 'ce'):
-            log_handle.write(UPGRADE_WINDOWS)
-        else:
-            log_handle.write(UPGRADE_OTHER)
-
-        sys.exit(1)
-
-
 if __name__ == '__main__':
     if len(sys.argv) < 5:
         print('Usage: populate_virtualenv.py /path/to/topsrcdir /path/to/topobjdir /path/to/virtualenv /path/to/virtualenv_manifest')
         sys.exit(1)
 
-    verify_python_version(sys.stdout)
-
     topsrcdir, topobjdir, virtualenv_path, manifest_path = sys.argv[1:5]
     populate = False
 
     # This should only be called internally.
     if sys.argv[1] == 'populate':
         populate = True
         topsrcdir, topobjdir, virtualenv_path, manifest_path = sys.argv[2:]