Bug 1321292 - mozboot: Don't suggest non-existent .cargo.env. r?gps draft
authorRalph Giles <giles@mozilla.com>
Mon, 05 Dec 2016 20:53:00 -0800
changeset 448307 9c0b9ed890c6bae85e01cbc5803a1f8d9d1b6f5c
parent 448298 f16df6dcd002c0bfabc989471e877616cfc2336d
child 539262 e5fb63918edf99d9f1338271c26d6659acd3ef59
push id38312
push userbmo:giles@thaumas.net
push dateFri, 09 Dec 2016 20:28:09 +0000
reviewersgps
bugs1321292
milestone53.0a1
Bug 1321292 - mozboot: Don't suggest non-existent .cargo.env. r?gps On Windows, the rustup installer doesn't create ~/.cargo/env but instead pokes .cargo/bin into the path in the Windows registry. This doesn't necessarily propagate to the msys evironment however, so some PATH manipulation may still be necessary. Split our path advice to be clear in both the new install and unconfigured path cases, and amend our path update advice to not mention .cargo/env if it isn't present. MozReview-Commit-ID: 9IHhS6UYCqq
python/mozboot/mozboot/base.py
--- a/python/mozboot/mozboot/base.py
+++ b/python/mozboot/mozboot/base.py
@@ -68,26 +68,43 @@ the $PATH environment variable.
 
 We recommend the following tools for installing Python:
 
     pyenv   -- https://github.com/yyuu/pyenv)
     pythonz -- https://github.com/saghul/pythonz
     official installers -- http://www.python.org/
 '''
 
-RUST_NOT_IN_PATH = '''
-You have some rust files in %(cargo_bin)s, but they're not part of the
-standard PATH.'''
+RUST_INSTALL_COMPLETE = '''
+Rust installation complete. You should now have rustc and cargo
+in %(cargo_bin)s
+
+The installer tries to add these to your default shell PATH, so
+restarting your shell and running this script again may work.
+If it doesn't, you'll need to add the new command location
+manually.
+
+If restarting doesn't work, edit your shell initialization
+script, which may be called ~/.bashrc or ~/.bash_profile or
+~/.profile, and add the following line:
 
-RUST_PATH_ADVICE = '''
-To make these available, please add this directory to the PATH variable
-in your shell initialization script, which may be called ~/.bashrc or
-~/.bash_profile or ~/.profile. Edit this and add the following line:
+    %(cmd)s
+
+Then restart your shell and run the bootstrap script again.
+'''
 
-    source %(cargo_home)s/env
+RUST_NOT_IN_PATH = '''
+You have some rust files in %(cargo_bin)s
+but they're not part of this shell's PATH.
+
+To add these to the PATH, edit your shell initialization
+script, which may be called ~/.bashrc or ~/.bash_profile or
+~/.profile, and add the following line:
+
+    %(cmd)s
 
 Then restart your shell and run the bootstrap script again.
 '''
 
 RUSTUP_OLD = '''
 We found an executable called `rustup` which we normally use to install
 and upgrade Rust programming language support, but we didn't understand
 its output. It may be an old version, or not be the installer from
@@ -103,18 +120,17 @@ We attempted to upgrade Rust to a modern
 However, you appear to still have version %s.
 
 It's possible rustup failed. It's also possible the new Rust is not being
 installed in the search path for this shell. Try creating a new shell and
 run this bootstrapper again.
 
 If this continues to fail and you are sure you have a modern Rust on your
 system, ensure it is on the $PATH and try again. If that fails, you'll need to
-install Rust manually and ensure the path with the rustc and cargo  binaries
-are listed in the $PATH environment variable.
+install Rust manually.
 
 We recommend the installer from https://rustup.rs/ for installing Rust,
 but you may be able to get a recent enough version from a software install
 tool or package manager on your system, or directly from https://rust-lang.org/
 '''
 
 BROWSER_ARTIFACT_MODE_MOZCONFIG = '''
 Paste the lines between the chevrons (>>> and <<<) into your mozconfig file:
@@ -516,36 +532,51 @@ class BaseBootstrapper(object):
         return our >= MODERN_RUST_VERSION, our
 
     def cargo_home(self):
         cargo_home = os.environ.get('CARGO_HOME',
                 os.path.expanduser(os.path.join('~', '.cargo')))
         cargo_bin = os.path.join(cargo_home, 'bin')
         return cargo_home, cargo_bin
 
+    def print_rust_path_advice(self, template, cargo_home, cargo_bin):
+        # Suggest ~/.cargo/env if it exists.
+        if os.path.exists(os.path.join(cargo_home, 'env')):
+            cmd = 'source %s/env' % cargo_home
+        else:
+            # On Windows rustup doesn't write out ~/.cargo/env
+            # so fall back to a manual PATH update. Bootstrap
+            # only runs under msys, so a unix-style shell command
+            # is appropriate there.
+            cmd = 'export PATH=%s:$PATH' % cargo_bin
+        print(template % {
+            'cargo_bin': cargo_bin,
+            'cmd': cmd,
+        })
+
     def ensure_rust_modern(self):
         modern, version = self.is_rust_modern()
 
         if modern:
             print('Your version of Rust (%s) is new enough.' % version)
             return
 
         if not version:
             # Rust wasn't in PATH. Check the standard location.
             cargo_home, cargo_bin = self.cargo_home()
             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 })
-                print(RUST_PATH_ADVICE % { 'cargo_home': cargo_home })
+                self.print_rust_path_advice(RUST_NOT_IN_PATH,
+                        cargo_home, cargo_bin)
                 sys.exit(1)
-
-        print('Your version of Rust (%s) is too old.' % version)
+        else:
+            print('Your version of Rust (%s) is too old.' % version)
 
         rustup = self.which('rustup')
         if rustup:
             rustup_version = self._parse_version(rustup)
             if not rustup_version:
                 print(RUSTUP_OLD)
                 sys.exit(1)
             print('Found rustup. Will try to upgrade.')
@@ -586,19 +617,18 @@ class BaseBootstrapper(object):
             os.chmod(rustup_init, mode | stat.S_IRWXU)
             print('Ok')
             print('Running rustup-init...')
             subprocess.check_call([rustup_init, '-y',
                 '--default-toolchain', 'stable',
                 '--default-host', platform,
             ])
             cargo_home, cargo_bin = self.cargo_home()
-            print('Rust installation complete.')
-            print('You should now have rustc and cargo in %s' % cargo_bin)
-            print(RUST_PATH_ADVICE % { 'cargo_home': cargo_home })
+            self.print_rust_path_advice(RUST_INSTALL_COMPLETE,
+                    cargo_home, cargo_bin)
         finally:
             try:
                 os.remove(rustup_init)
             except OSError as e:
                 if e.errno != errno.ENOENT:
                     raise
 
     def http_download_and_save(self, url, dest, sha256hexhash):