Bug 1286799 - mozboot: Fix rust detection on windows. r=gps draft
authorRalph Giles <giles@mozilla.com>
Mon, 21 Nov 2016 11:18:59 -0800
changeset 442192 ed30cd49efb39e75c5091b32b280f115827b0c22
parent 442191 d03baa9c20d4049bcb9483d0f23dab8db800327f
child 537732 72ae7eb90e093466086e0d8350e4e0161fffe72d
push id36622
push userbmo:giles@thaumas.net
push dateTue, 22 Nov 2016 01:00:21 +0000
reviewersgps
bugs1286799
milestone53.0a1
Bug 1286799 - mozboot: Fix rust detection on windows. r=gps WindowsBootstrapper overrides BaseBootstrapper.which() to append the Windows 'exe' filename extension, so which() finds rustc.exe and rustup.exe properly. However, our other code which constructs the program name in _parse_version or looks for the files in CARGO_HOME didn't take this into account, making the script think it couldn't find rust. Don't use os.path.join to construct urls, since on windows this inserts the backslash '\' path separator instead of the normal forward slash. MozReview-Commit-ID: HWJjwCDHuNK
python/mozboot/mozboot/base.py
python/mozboot/mozboot/rust.py
--- a/python/mozboot/mozboot/base.py
+++ b/python/mozboot/mozboot/base.py
@@ -377,16 +377,18 @@ class BaseBootstrapper(object):
         different from the basename of the executable.
 
         An optional env argument allows modifying environment
         variable during the invocation to set options, PATH,
         etc.
         '''
         if not name:
             name = os.path.basename(path)
+        if name.endswith('.exe'):
+            name = name[:-4]
 
         info = self.check_output([path, '--version'],
                                  env=env,
                                  stderr=subprocess.STDOUT)
         match = re.search(name + ' ([a-z0-9\.]+)', info)
         if not match:
             print('ERROR! Unable to identify %s version.' % name)
             return None
@@ -501,17 +503,17 @@ class BaseBootstrapper(object):
     def is_rust_modern(self):
         rustc = self.which('rustc')
         if not rustc:
             print('Could not find a Rust compiler.')
             return False, None
 
         cargo = self.which('cargo')
 
-        our = self._parse_version(rust)
+        our = self._parse_version(rustc)
         if not our:
             return False, None
 
         return our >= MODERN_RUST_VERSION, our
 
     def ensure_rust_modern(self):
         modern, version = self.is_rust_modern()
 
@@ -519,18 +521,20 @@ class BaseBootstrapper(object):
             print('Your version of Rust (%s) is new enough.' % version)
             return
 
         if not version:
             # Rust wasn't in PATH. Try the standard path.
             cargo_home = os.environ.get('CARGO_HOME',
                     os.path.expanduser(os.path.join('~', '.cargo')))
             cargo_bin = os.path.join(cargo_home, 'bin')
-            have_rustc = os.path.exists(os.path.join(cargo_bin, 'rustc'))
-            have_cargo = os.path.exists(os.path.join(cargo_bin, 'cargo'))
+            try_rustc = os.path.join(cargo_bin, 'rustc' + rust.exe_suffix())
+            try_cargo = os.path.join(cargo_bin, 'cargo' + rust.exe_suffix())
+            have_rustc = os.path.exists(try_rustc)
+            have_cargo = os.path.exists(try_cargo)
             if have_rustc or have_cargo:
                 print(RUST_NOT_IN_PATH % { 'cargo_bin': cargo_bin,
                                            'cargo_home': cargo_home })
                 sys.exit(1)
 
         rustup = self.which('rustup')
         if rustup:
             rustup_version = self._parse_version(rustup)
--- a/python/mozboot/mozboot/rust.py
+++ b/python/mozboot/mozboot/rust.py
@@ -36,24 +36,21 @@ NO_PLATFORM = '''
 Sorry, we have no installer configured for your platform.
 
 Please try installing rust for your system from https://rustup.rs/
 or from https://rust-lang.org/ or from your package manager.
 '''
 
 def rustup_url(host, version=RUSTUP_VERSION):
     '''Download url for a particular version of the installer.'''
-    ext = ''
-    if 'windows' in host:
-        ext = '.exe'
-    return os.path.join(RUSTUP_URL_BASE,
-        'archive/%(version)s/%(host)s/rustup-init%(ext)s') % {
+    return '%(base)s/archive/%(version)s/%(host)s/rustup-init%(ext)s' % {
+                'base': RUSTUP_URL_BASE,
                 'version': version,
                 'host': host,
-                'ext': ext}
+                'ext': exe_suffix(host)}
 
 def rustup_hash(host):
     '''Look up the checksum for the given installer.'''
     return RUSTUP_HASHES.get(host, None)
 
 def platform():
     '''Determine the appropriate rust platform string for the current host'''
     if sys.platform.startswith('darwin'):
@@ -63,16 +60,23 @@ def platform():
         return 'x86_64-pc-windows-msvc'
     elif sys.platform.startswith('linux'):
         return 'x86_64-unknown-linux-gnu'
     elif sys.platform.startswith('freebsd'):
         return 'x86_64-unknown-freebsd'
 
     return None
 
+def exe_suffix(host=None):
+    if not host:
+        host = platform()
+    if 'windows' in host:
+        return '.exe'
+    return ''
+
 USAGE = '''
 python rust.py [--update]
 
 Pass the --update option print info for the latest release of rustup-init.
 
 When invoked without the --update option, it queries the latest version
 and verifies the current stored checksums against the distribution server,
 but doesn't update the version installed by `mach bootstrap`.