configwizard: prompt to install the firefoxtree extension (bug 1277406); r=glob
authorGregory Szorc <gps@mozilla.com>
Wed, 01 Jun 2016 14:50:26 -0700
changeset 4356 b5404e1a302819301c8285733af7a99b80464419
parent 4355 66b6c9b10287b8c634e2ae5a746952d999087738
child 4357 ea492a3340434d311cbe37ed95cba9e8f7e64516
push id1875
push usergszorc@mozilla.com
push dateThu, 09 Jun 2016 19:26:34 +0000
treeherderversion-control-tools@2bd23fbed26f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglob
bugs1277406
configwizard: prompt to install the firefoxtree extension (bug 1277406); r=glob MozReview-Commit-ID: AxalQDZQXFk
hgext/configwizard/__init__.py
hgext/configwizard/hgsetup/wizard.py
hgext/configwizard/tests/test-firefoxtree.t
--- a/hgext/configwizard/__init__.py
+++ b/hgext/configwizard/__init__.py
@@ -1,16 +1,18 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
 """Manage Mercurial configuration in a Mozilla-tailored way."""
 
 import difflib
 import io
 import os
+import subprocess
+import sys
 import uuid
 
 from mercurial import (
     cmdutil,
     error,
     scmutil,
     util,
 )
@@ -87,29 +89,54 @@ Newer versions of Mercurial have built-i
 filesystem watching services to make common operations faster.
 
 This integration is STRONGLY RECOMMENDED when using the Firefox
 repository.
 
 Please upgrade to Mercurial 3.8+ so this feature is available.
 '''.lstrip()
 
+FIREFOXTREE_INFO = '''
+The firefoxtree extension makes interacting with the multiple Firefox
+repositories easier:
+
+* Aliases for common trees are pre-defined. e.g. `hg pull central`
+* Pulling from known Firefox trees will create "remote refs" appearing as
+  tags. e.g. pulling from fx-team will produce a "fx-team" tag.
+* The `hg fxheads` command will list the heads of all pulled Firefox repos
+  for easy reference.
+* `hg push` will limit itself to pushing a single head when pushing to
+  Firefox repos.
+* A pre-push hook will prevent you from pushing multiple heads to known
+  Firefox repos. This acts quicker than a server-side hook.
+
+The firefoxtree extension is *strongly* recommended if you:
+
+a) aggregate multiple Firefox repositories into a single local repo
+b) perform head/bookmark-based development (as opposed to mq)
+
+(Relevant config option: extensions.firefoxtree)
+
+Would you like to activate firefoxtree (Yn)? $$ &Yes $$ &No
+'''.strip()
+
 testedwith = '3.5 3.6 3.7 3.8'
 buglink = 'https://bugzilla.mozilla.org/enter_bug.cgi?product=Developer%20Services&component=General'
 
 cmdtable = {}
 command = cmdutil.command(cmdtable)
 
 wizardsteps = {
     'hgversion',
     'username',
     'diff',
     'color',
     'historyediting',
     'fsmonitor',
+    'firefoxtree',
     'configchange',
 }
 
 @command('configwizard', [
     ('s', 'statedir', '', _('directory to store state')),
     ], _('hg configwizard'), optionalrepo=True)
 def configwizard(ui, repo, statedir=None, **opts):
     """Ensure your Mercurial configuration is up to date."""
@@ -143,16 +170,19 @@ def configwizard(ui, repo, statedir=None
         _promptnativeextension(ui, cw, 'color', 'Enable color output to your terminal')
 
     if 'historyediting' in runsteps:
         _checkhistoryediting(ui, cw)
 
     if 'fsmonitor' in runsteps:
         _checkfsmonitor(ui, cw, hgversion)
 
+    if 'firefoxtree' in runsteps:
+        _promptvctextension(ui, cw, 'firefoxtree', FIREFOXTREE_INFO)
+
     if 'configchange' in runsteps:
         return _handleconfigchange(ui, cw)
 
     return 0
 
 
 def _checkhgversion(ui, hgversion):
     if hgversion >= OLDEST_NON_LEGACY_VERSION:
@@ -234,16 +264,42 @@ def _promptnativeextension(ui, cw, ext, 
 
     if not uipromptchoice(ui, '%s (Yn) $$ &Yes $$ &No' % msg):
         if 'extensions' not in cw.c:
             cw.c['extensions'] = {}
 
         cw.c['extensions'][ext] = ''
 
 
+def _promptvctextension(ui, cw, ext, msg):
+    if ui.hasconfig('extensions', ext):
+        return
+
+    here = os.path.dirname(os.path.abspath(__file__))
+    ext_dir = os.path.normpath(os.path.join(here, '..'))
+    ext_path = os.path.join(ext_dir, ext)
+
+    # Verify the extension loads before prompting to enable it. This is
+    # done out of paranoia.
+    result = subprocess.check_output([sys.argv[0],
+                                      '--config', 'extensions.testmodule=%s' % ext_path,
+                                      '--config', 'ui.traceback=true'],
+                                     stderr=subprocess.STDOUT)
+    if 'Traceback' in result:
+        return
+
+    if uipromptchoice(ui, '%s (Yn) $$ &Yes $$ &No' % msg):
+        return
+
+    if 'extensions' not in cw.c:
+        cw.c['extensions'] = {}
+
+    cw.c['extensions'][ext] = ext_path
+
+
 def _checkhistoryediting(ui, cw):
     if all(ui.hasconfig('extensions', e) for e in ('histedit', 'rebase')):
         return
 
     if ui.promptchoice('Enable history rewriting commands (Yn)? $$ &Yes $$ &No'):
         return
 
     if 'extensions' not in cw.c:
--- a/hgext/configwizard/hgsetup/wizard.py
+++ b/hgext/configwizard/hgsetup/wizard.py
@@ -81,42 +81,16 @@ LEGACY_BUGZILLA_CREDENTIALS_DETECTED = '
 Your existing Mercurial config uses a legacy method for defining Bugzilla
 credentials. Bugzilla API Keys are the most secure and preferred method
 for defining Bugzilla credentials. Bugzilla API Keys are also required
 if you have enabled 2 Factor Authentication in Bugzilla.
 
 All consumers formerly looking at these options should support API Keys.
 '''.lstrip()
 
-FIREFOXTREE_MINIMUM_VERSION = LooseVersion('3.5')
-
-FIREFOXTREE_INFO = '''
-The firefoxtree extension makes interacting with the multiple Firefox
-repositories easier:
-
-* Aliases for common trees are pre-defined. e.g. `hg pull central`
-* Pulling from known Firefox trees will create "remote refs" appearing as
-  tags. e.g. pulling from fx-team will produce a "fx-team" tag.
-* The `hg fxheads` command will list the heads of all pulled Firefox repos
-  for easy reference.
-* `hg push` will limit itself to pushing a single head when pushing to
-  Firefox repos.
-* A pre-push hook will prevent you from pushing multiple heads to known
-  Firefox repos. This acts quicker than a server-side hook.
-
-The firefoxtree extension is *strongly* recommended if you:
-
-a) aggregate multiple Firefox repositories into a single local repo
-b) perform head/bookmark-based development (as opposed to mq)
-
-(Relevant config option: extensions.firefoxtree)
-
-Would you like to activate firefoxtree
-'''.strip()
-
 PUSHTOTRY_MINIMUM_VERSION = LooseVersion('3.5')
 
 PUSHTOTRY_INFO = '''
 The push-to-try extension generates a temporary commit with a given
 try syntax and pushes it to the try server. The extension is intended
 to be used in concert with other tools generating try syntax so that
 they can push to try without depending on mq or other workarounds.
 
@@ -205,19 +179,16 @@ class MercurialSetupWizard(object):
                 self.prompt_external_extension(c, 'reviewboard',
                     'Would you like to enable the reviewboard extension so '
                     'you can easily initiate code reviews against Mozilla '
                     'projects',
                     path=p)
 
         self.prompt_external_extension(c, 'bzexport', BZEXPORT_INFO)
 
-        if hg_version >= FIREFOXTREE_MINIMUM_VERSION:
-            self.prompt_external_extension(c, 'firefoxtree', FIREFOXTREE_INFO)
-
         if hg_version >= PUSHTOTRY_MINIMUM_VERSION:
             self.prompt_external_extension(c, 'push-to-try', PUSHTOTRY_INFO)
 
         if not c.have_wip():
             if self._prompt_yn(WIP_INFO):
                 c.install_wip_alias()
 
         if 'reviewboard' in c.extensions:
new file mode 100644
--- /dev/null
+++ b/hgext/configwizard/tests/test-firefoxtree.t
@@ -0,0 +1,92 @@
+  $ . $TESTDIR/hgext/configwizard/tests/helpers.sh
+
+Rejecting firefoxtree doesn't enable it
+
+  $ hg --config ui.interactive=true --config configwizard.steps=firefoxtree,configchange configwizard << EOF
+  > 
+  > n
+  > EOF
+  This wizard will guide you through configuring Mercurial for an optimal
+  experience contributing to Mozilla projects.
+  
+  The wizard makes no changes without your permission.
+  
+  To begin, press the enter/return key.
+   <RETURN>
+  The firefoxtree extension makes interacting with the multiple Firefox
+  repositories easier:
+  
+  * Aliases for common trees are pre-defined. e.g. `hg pull central`
+  * Pulling from known Firefox trees will create "remote refs" appearing as
+    tags. e.g. pulling from fx-team will produce a "fx-team" tag.
+  * The `hg fxheads` command will list the heads of all pulled Firefox repos
+    for easy reference.
+  * `hg push` will limit itself to pushing a single head when pushing to
+    Firefox repos.
+  * A pre-push hook will prevent you from pushing multiple heads to known
+    Firefox repos. This acts quicker than a server-side hook.
+  
+  The firefoxtree extension is *strongly* recommended if you:
+  
+  a) aggregate multiple Firefox repositories into a single local repo
+  b) perform head/bookmark-based development (as opposed to mq)
+  
+  (Relevant config option: extensions.firefoxtree)
+  
+  Would you like to activate firefoxtree (Yn)?  n
+
+No prompt if extensions already enabled
+
+  $ hg --config configwizard.steps=firefoxtree --config extensions.firefoxtree=$TESTDIR/hgext/firefoxtree configwizard
+  This wizard will guide you through configuring Mercurial for an optimal
+  experience contributing to Mozilla projects.
+  
+  The wizard makes no changes without your permission.
+  
+  To begin, press the enter/return key.
+   <RETURN>
+
+firefoxtree enabled when requested
+
+  $ hg --config configwizard.steps=firefoxtree,configchange configwizard
+  This wizard will guide you through configuring Mercurial for an optimal
+  experience contributing to Mozilla projects.
+  
+  The wizard makes no changes without your permission.
+  
+  To begin, press the enter/return key.
+   <RETURN>
+  The firefoxtree extension makes interacting with the multiple Firefox
+  repositories easier:
+  
+  * Aliases for common trees are pre-defined. e.g. `hg pull central`
+  * Pulling from known Firefox trees will create "remote refs" appearing as
+    tags. e.g. pulling from fx-team will produce a "fx-team" tag.
+  * The `hg fxheads` command will list the heads of all pulled Firefox repos
+    for easy reference.
+  * `hg push` will limit itself to pushing a single head when pushing to
+    Firefox repos.
+  * A pre-push hook will prevent you from pushing multiple heads to known
+    Firefox repos. This acts quicker than a server-side hook.
+  
+  The firefoxtree extension is *strongly* recommended if you:
+  
+  a) aggregate multiple Firefox repositories into a single local repo
+  b) perform head/bookmark-based development (as opposed to mq)
+  
+  (Relevant config option: extensions.firefoxtree)
+  
+  Would you like to activate firefoxtree (Yn)?  y
+  Your config file needs updating.
+  Would you like to see a diff of the changes first (Yn)?  y
+  --- hgrc.old
+  +++ hgrc.new
+  @@ -0,0 +1,2 @@
+  +[extensions]
+  +firefoxtree = */hgext/firefoxtree (glob)
+  
+  Write changes to hgrc file (Yn)?  y
+
+  $ cat .hgrc
+  [extensions]
+  firefoxtree = */hgext/firefoxtree (glob)