Bug 1279563 - Offer to clone Firefox source repo during bootstrap; r=glandium
authorGregory Szorc <gps@mozilla.com>
Thu, 16 Jun 2016 09:42:32 +0100
changeset 301984 ffd61bc024b24d5d1c4e8cf1c7671a27cd06944d
parent 301945 6b40db1565705c392042da04396d1ca83c0d017d
child 301985 b9f4f38063951cd5a8b249911aea61869f40fd1f
push id78533
push usercbook@mozilla.com
push dateFri, 17 Jun 2016 00:03:15 +0000
treeherdermozilla-inbound@759277e45f04 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium
bugs1279563
milestone50.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 1279563 - Offer to clone Firefox source repo during bootstrap; r=glandium I've always been bothered that the one-line bootstrap configures your system then leaves you on the hook to clone source code and configure the build system. I'd like the bootstrap wizard to guide you through end-to-end. This commit addresses part of the disconnect by offering to clone the Mercurial source repository at the end of bootstrap. We only offer to clone if we aren't running from a Firefox source checkout (likely the one-line bootstrap invocation) and if we are in interactive mode. I'd like to eventually offer Git support here. Mercurial is the canonical repo, so it makes sense to start with that. MozReview-Commit-ID: 6TSZwxB3702
python/mozboot/mozboot/bootstrap.py
--- a/python/mozboot/mozboot/bootstrap.py
+++ b/python/mozboot/mozboot/bootstrap.py
@@ -77,18 +77,21 @@ Would you like to create this directory?
 
   1. Yes
   2. No
 
 Your choice:
 '''
 
 FINISHED = '''
-Your system should be ready to build %s! If you have not already,
-obtain a copy of the source code by running:
+Your system should be ready to build %s!
+'''
+
+SOURCE_ADVERTISE = '''
+Source code can be obtained by running
 
     hg clone https://hg.mozilla.org/mozilla-central
 
 Or, if you prefer Git, you should install git-cinnabar, and follow the
 instruction here to clone from the Mercurial repository:
 
     https://github.com/glandium/git-cinnabar/wiki/Mozilla:-A-git-workflow-for-Gecko-development
 
@@ -104,16 +107,25 @@ experience with it.
 Would you like to run a configuration wizard to ensure Mercurial is
 optimally configured?
 
   1. Yes
   2. No
 
 Please enter your reply: '''.lstrip()
 
+CLONE_MERCURIAL = '''
+If you would like to clone the canonical Mercurial repository, please
+enter the destination path below.
+
+(If you prefer to use Git, leave this blank.)
+
+Destination directory for Mercurial clone (leave empty to not clone): '''.lstrip()
+
+
 DEBIAN_DISTROS = (
     'Debian',
     'debian',
     'Ubuntu',
     # Most Linux Mint editions are based on Ubuntu. One is based on Debian.
     # The difference is reported in dist_id from platform.linux_distribution.
     # But it doesn't matter since we share a bootstrapper between Debian and
     # Ubuntu.
@@ -243,16 +255,33 @@ class Bootstrapper(object):
                 if choice == 1:
                     configure_hg = True
             else:
                 configure_hg = self.hg_configure
 
             if configure_hg:
                 configure_mercurial(self.instance.which('hg'), state_dir)
 
+        # Offer to clone if we're not inside a clone.
+        checkout_type = current_firefox_checkout(check_output=self.instance.check_output,
+                                                 hg=self.instance.which('hg'))
+        have_clone = False
+
+        if checkout_type:
+            have_clone = True
+        elif hg_installed and not self.instance.no_interactive:
+            dest = raw_input(CLONE_MERCURIAL)
+            dest = dest.strip()
+            if dest:
+                dest = os.path.expanduser(dest)
+                have_clone = clone_firefox(self.instance.which('hg'), dest)
+
+        if not have_clone:
+            print(SOURCE_ADVERTISE)
+
         print(self.finished % name)
 
         # Like 'suggest_browser_mozconfig' or 'suggest_mobile_android_mozconfig'.
         getattr(self.instance, 'suggest_%s_mozconfig' % application)()
 
 
 def update_vct(hg, root_state_dir):
     """Ensure version-control-tools in the state directory is up to date."""
@@ -308,8 +337,66 @@ def update_mercurial_repo(hg, url, dest,
     print('=' * 80)
     print('Ensuring %s is up to date at %s' % (url, dest))
 
     try:
         subprocess.check_call(args, cwd=cwd)
         subprocess.check_call([hg, 'update', '-r', revision], cwd=dest)
     finally:
         print('=' * 80)
+
+
+def clone_firefox(hg, dest):
+    """Clone the Firefox repository to a specified destination."""
+    print('Cloning Firefox Mercurial repository to %s' % dest)
+
+    args = [
+        hg,
+        'clone',
+        'https://hg.mozilla.org/mozilla-central',
+        dest,
+    ]
+
+    res = subprocess.call(args)
+    print('')
+    if res:
+        print('error cloning; please try again')
+        return False
+    else:
+        print('Firefox source code available at %s' % dest)
+        return True
+
+
+def current_firefox_checkout(check_output, hg=None):
+    """Determine whether we're in a Firefox checkout.
+
+    Returns one of None, ``git``, or ``hg``.
+    """
+    HG_ROOT_REVISIONS = set([
+        # From mozilla-central.
+        '8ba995b74e18334ab3707f27e9eb8f4e37ba3d29',
+    ])
+
+    path = os.getcwd()
+    while path:
+        hg_dir = os.path.join(path, '.hg')
+        git_dir = os.path.join(path, '.git')
+        if hg and os.path.exists(hg_dir):
+            # Verify the hg repo is a Firefox repo by looking at rev 0.
+            try:
+                node = check_output([hg, 'log', '-r', '0', '-T', '{node}'], cwd=path)
+                if node in HG_ROOT_REVISIONS:
+                    return 'hg'
+                # Else the root revision is different. There could be nested
+                # repos. So keep traversing the parents.
+            except subprocess.CalledProcessError:
+                pass
+
+        # TODO check git remotes or `git rev-parse -q --verify $sha1^{commit}`
+        # for signs of Firefox.
+        elif os.path.exists(git_dir):
+            return 'git'
+
+        path, child = os.path.split(path)
+        if child == '':
+            break
+
+    return None