Bug 1177128 - Added bootstrapper for MozillaBuild that installs rustup. r?gps draft
authorNathan Hakkakzadeh <nhakkakzadeh@mozilla.com>
Thu, 07 Jul 2016 16:26:48 -0700
changeset 386465 dd4658202651a9f5ba2d522e0751f0f10439a388
parent 386302 214884d507ee369c1cf14edb26527c4f9a97bf48
child 525118 751388db8dce53390668909a9beffb8b88e5e441
push id22710
push userbmo:nhakkakzadeh@mozilla.com
push dateMon, 11 Jul 2016 22:35:46 +0000
reviewersgps
bugs1177128
milestone50.0a1
Bug 1177128 - Added bootstrapper for MozillaBuild that installs rustup. r?gps MozReview-Commit-ID: D4DuE0Z35Cd
python/mozboot/mozboot/base.py
python/mozboot/mozboot/bootstrap.py
python/mozboot/mozboot/mozillabuild.py
--- a/python/mozboot/mozboot/base.py
+++ b/python/mozboot/mozboot/base.py
@@ -1,18 +1,20 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import print_function, unicode_literals
 
+import hashlib
 import os
 import re
 import subprocess
 import sys
+import urllib2
 
 from distutils.version import LooseVersion
 
 
 NO_MERCURIAL = '''
 Could not find Mercurial (hg) in the current shell's path. Try starting a new
 shell and running the bootstrapper again.
 '''
@@ -400,8 +402,23 @@ class BaseBootstrapper(object):
             sys.exit(1)
 
     def upgrade_python(self, current):
         """Upgrade Python.
 
         Child classes should reimplement this.
         """
         print(PYTHON_UNABLE_UPGRADE % (current, MODERN_PYTHON_VERSION))
+
+    def http_download_and_save(self, url, dest, sha256hexhash):
+        f = urllib2.urlopen(url)
+        h = hashlib.sha256()
+        with open(dest, 'wb') as out:
+            while True:
+                data = f.read(4096)
+                if data:
+                    out.write(data)
+                    h.update(data)
+                else:
+                    break
+        if h.hexdigest() != sha256hexhash:
+            os.remove(dest)
+            raise ValueError('Hash of downloaded file does not match expected hash')
--- a/python/mozboot/mozboot/bootstrap.py
+++ b/python/mozboot/mozboot/bootstrap.py
@@ -2,29 +2,30 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # If we add unicode_literals, Python 2.6.1 (required for OS X 10.6) breaks.
 from __future__ import print_function
 
 import platform
 import sys
-import os.path
+import os
 import subprocess
 
 # Don't forgot to add new mozboot modules to the bootstrap download
 # list in bin/bootstrap.py!
 from mozboot.centosfedora import CentOSFedoraBootstrapper
 from mozboot.debian import DebianBootstrapper
 from mozboot.freebsd import FreeBSDBootstrapper
 from mozboot.gentoo import GentooBootstrapper
 from mozboot.osx import OSXBootstrapper
 from mozboot.openbsd import OpenBSDBootstrapper
 from mozboot.archlinux import ArchlinuxBootstrapper
 from mozboot.windows import WindowsBootstrapper
+from mozboot.mozillabuild import MozillaBuildBootstrapper
 from mozboot.util import (
     get_state_dir,
 )
 
 APPLICATION_CHOICE = '''
 Please choose the version of Firefox you want to build:
 %s
 
@@ -185,17 +186,20 @@ class Bootstrapper(object):
 
         elif sys.platform.startswith('dragonfly') or \
                 sys.platform.startswith('freebsd'):
             cls = FreeBSDBootstrapper
             args['version'] = platform.release()
             args['flavor'] = platform.system()
 
         elif sys.platform.startswith('win32') or sys.platform.startswith('msys'):
-            cls = WindowsBootstrapper
+            if 'MOZILLABUILD' in os.environ:
+                cls = MozillaBuildBootstrapper
+            else:
+                cls = WindowsBootstrapper
 
         if cls is None:
             raise NotImplementedError('Bootstrap support is not yet available '
                                       'for your OS.')
 
         self.instance = cls(**args)
 
     def bootstrap(self):
new file mode 100644
--- /dev/null
+++ b/python/mozboot/mozboot/mozillabuild.py
@@ -0,0 +1,74 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import sys
+import subprocess
+import tempfile
+
+from mozboot.base import BaseBootstrapper
+
+class MozillaBuildBootstrapper(BaseBootstrapper):
+    '''Bootstrapper for MozillaBuild to install rustup.'''
+    def __init__(self, no_interactive=False):
+        BaseBootstrapper.__init__(self, no_interactive=no_interactive)
+        print("mach bootstrap is not fully implemented in MozillaBuild")
+
+    def which(self, name):
+        return BaseBootstrapper.which(self, name + '.exe')
+
+    def install_system_packages(self):
+        self.install_rustup()
+
+    def install_rustup(self):
+        try:
+            rustup_init = tempfile.gettempdir() + '/rustup-init.exe'
+            self.http_download_and_save(
+                    'https://static.rust-lang.org/rustup/archive/0.2.0/i686-pc-windows-msvc/rustup-init.exe',
+                    rustup_init,
+                    'a45ab7462b567dacddaf6e9e48bb43a1b9c1db4404ba77868f7d6fc685282a46')
+            self.run([rustup_init, '--no-modify-path', '--default-host',
+                'x86_64-pc-windows-msvc', '--default-toolchain', 'stable', '-y'])
+            mozillabuild_dir = os.environ['MOZILLABUILD']
+
+            with open(mozillabuild_dir + 'msys/etc/profile.d/profile-rustup.sh', 'wb') as f:
+                f.write('#!/bash/sh\n')
+                f.write('if test -n "$MOZILLABUILD"; then\n')
+                f.write('    WIN_HOME=$(cd "$HOME" && pwd)\n')
+                f.write('    PATH="$WIN_HOME/.cargo/bin:$PATH"\n')
+                f.write('    export PATH\n')
+                f.write('fi')
+        finally:
+            try:
+                os.remove(rustup_init)
+            except FileNotFoundError:
+                pass
+
+    def upgrade_mercurial(self, current):
+        self.pip_install('mercurial')
+
+    def upgrade_python(self, current):
+        pass
+
+    def install_browser_packages(self):
+        pass
+
+    def install_mobile_android_packages(self):
+        pass
+
+    def install_mobile_android_artifact_mode_packages(self):
+        pass
+
+    def _update_package_manager(self):
+        pass
+
+    def run(self, command):
+        subprocess.check_call(command, stdin=sys.stdin)
+
+    def pip_install(self, *packages):
+        pip_dir = os.path.join(os.environ['MOZILLABUILD'], 'python', 'Scripts', 'pip.exe')
+        command = [pip_dir, 'install', '--upgrade']
+        command.extend(packages)
+        self.run(command)
+