configwizard: initial Mercurial extension implementation (bug 1277406); r?glob draft
authorGregory Szorc <gps@mozilla.com>
Wed, 01 Jun 2016 14:33:32 -0700
changeset 8491 0d4bbbd1a8425e7f2c7a2d7b1b43c1c73364a9cb
parent 8490 29d3dc704982ac84a1b40df10316d080cdab5939
child 8492 4d7c84e5d04f5b007ebbb2c707b8d3b5c6cb16c4
push id918
push userbmo:gps@mozilla.com
push dateThu, 09 Jun 2016 19:23:31 +0000
reviewersglob
bugs1277406
configwizard: initial Mercurial extension implementation (bug 1277406); r?glob We move the introduction message and basic version detection from the old wizard to the extension. A basic test has been added. The wizard has support for running a specific list of steps. This is to facilitate testing. (It would be difficult to test every step in every test.) MozReview-Commit-ID: Kt8XQNtjVuH
hgext/configwizard/__init__.py
hgext/configwizard/hgsetup/wizard.py
hgext/configwizard/tests/helpers.sh
hgext/configwizard/tests/test-legacy-version.t
new file mode 100644
--- /dev/null
+++ b/hgext/configwizard/__init__.py
@@ -0,0 +1,108 @@
+# 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 os
+
+from mercurial import (
+    cmdutil,
+    error,
+    util,
+)
+from mercurial.i18n import _
+
+OUR_DIR = os.path.dirname(__file__)
+execfile(os.path.join(OUR_DIR, '..', 'bootstrap.py'))
+
+INITIAL_MESSAGE = '''
+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.
+'''.lstrip()
+
+MINIMUM_SUPPORTED_VERSION = (3, 5, 0)
+
+OLDEST_NON_LEGACY_VERSION = (3, 7, 3)
+
+VERSION_TOO_OLD = '''
+Your version of Mercurial is too old to run `hg configwizard`.
+
+Mozilla's Mercurial support policy is to support at most the past
+1 year of Mercurial releases (or 4 major Mercurial releases).
+'''.lstrip()
+
+LEGACY_MERCURIAL_MESSAGE = '''
+You are running an out of date Mercurial client (%s).
+
+For a faster and better Mercurial experience, we HIGHLY recommend you
+upgrade.
+
+Legacy versions of Mercurial have known security vulnerabilities. Failure
+to upgrade may leave you exposed. You are highly encouraged to upgrade in
+case you aren't running a patched version.
+'''.lstrip()
+
+
+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',
+}
+
+@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."""
+    runsteps = set(wizardsteps)
+    if ui.hasconfig('configwizard', 'steps'):
+        runsteps = set(ui.configlist('configwizard', 'steps'))
+
+    hgversion = util.versiontuple(n=3)
+
+    if hgversion < MINIMUM_SUPPORTED_VERSION:
+        ui.warn(VERSION_TOO_OLD)
+        raise error.Abort('upgrade Mercurial then run again')
+
+    uiprompt(ui, INITIAL_MESSAGE, default='<RETURN>')
+
+    if 'hgversion' in runsteps:
+        if _checkhgversion(ui, hgversion):
+            return 1
+
+
+def _checkhgversion(ui, hgversion):
+    if hgversion >= OLDEST_NON_LEGACY_VERSION:
+        return
+
+    ui.warn(LEGACY_MERCURIAL_MESSAGE % util.version())
+    ui.warn('\n')
+
+    if os.name == 'nt':
+        ui.warn('Please upgrade to the latest MozillaBuild to upgrade '
+                'your Mercurial install.\n\n')
+    else:
+        ui.warn('Please run `mach bootstrap` to upgrade your Mercurial '
+                'install.\n\n')
+
+    if ui.promptchoice('Would you like to continue using an old Mercurial version (Yn)? $$ &Yes $$ &No'):
+        return 1
+
+
+def uiprompt(ui, msg, default=None):
+    """Wrapper for ui.prompt() that only renders the last line of text as prompt.
+
+    This prevents entire prompt text from rendering as a special color which
+    may be hard to read.
+    """
+    lines = msg.splitlines(True)
+    ui.write(''.join(lines[0:-1]))
+    return ui.prompt(lines[-1], default=default)
--- a/hgext/configwizard/hgsetup/wizard.py
+++ b/hgext/configwizard/hgsetup/wizard.py
@@ -23,44 +23,16 @@ from mozversioncontrol import get_hg_pat
 from .update import MercurialUpdater
 from .config import (
     config_file,
     MercurialConfig,
     ParseException,
 )
 
 
-INITIAL_MESSAGE = '''
-I'm going to help you ensure your Mercurial is configured for optimal
-development on Mozilla projects.
-
-If your environment is missing some recommended settings, I'm going to prompt
-you whether you want me to make changes: I won't change anything you might not
-want me changing without your permission!
-
-If your config is up-to-date, I'm just going to ensure all 3rd party extensions
-are up to date and you won't have to do anything.
-
-To begin, press the enter/return key.
-'''.strip()
-
-# This should match MODERN_MERCURIAL_VERSION in
-# python/mozboot/mozboot/base.py.
-OLDEST_NON_LEGACY_VERSION = LooseVersion('3.7.3')
-LEGACY_MERCURIAL = '''
-You are running an out of date Mercurial client (%s).
-
-For a faster and better Mercurial experience, we HIGHLY recommend you
-upgrade.
-
-Legacy versions of Mercurial have known security vulnerabilities. Failure
-to upgrade may leave you exposed. You are highly encouraged to upgrade
-in case you aren't running a patched version.
-'''.strip()
-
 MISSING_USERNAME = '''
 You don't have a username defined in your Mercurial config file. In order to
 send patches to Mozilla, you'll need to attach a name and email address. If you
 aren't comfortable giving us your full name, pseudonames are acceptable.
 
 (Relevant config option: ui.username)
 '''.strip()
 
@@ -294,36 +266,17 @@ class MercurialSetupWizard(object):
         except ParseException as e:
             print('Error importing existing Mercurial config: %s\n' % config_path)
             print('Line %d: %s' % (e.line, e.message))
 
             return 1
 
         self.updater.update_all()
 
-        print(INITIAL_MESSAGE)
-        raw_input()
-
         hg_version = get_hg_version(hg)
-        if hg_version < OLDEST_NON_LEGACY_VERSION:
-            print(LEGACY_MERCURIAL % hg_version)
-            print('')
-
-            if os.name == 'nt':
-                print('Please upgrade to the latest MozillaBuild to upgrade '
-                    'your Mercurial install.')
-                print('')
-            else:
-                print('Please run |mach bootstrap| to upgrade your Mercurial '
-                    'install.')
-                print('')
-
-            if not self._prompt_yn('Would you like to continue using an old '
-                'Mercurial version'):
-                return 1
 
         if not c.have_valid_username():
             print(MISSING_USERNAME)
             print('')
 
             name = self._prompt('What is your name?')
             email = self._prompt('What is your email address?')
             c.set_username(name, email)
new file mode 100755
--- /dev/null
+++ b/hgext/configwizard/tests/helpers.sh
@@ -0,0 +1,4 @@
+cat >> $HGRCPATH << EOF
+[extensions]
+configwizard = $TESTDIR/hgext/configwizard
+EOF
new file mode 100644
--- /dev/null
+++ b/hgext/configwizard/tests/test-legacy-version.t
@@ -0,0 +1,89 @@
+  $ . $TESTDIR/hgext/configwizard/tests/helpers.sh
+
+Should not get legacy version message when running on supported version
+
+  $ cat > fakeversion.py << EOF
+  > from mercurial import util
+  > util.version = lambda: '3.7.3'
+  > EOF
+
+  $ FAKEVERSION='--config extensions.fakeversion=fakeversion.py'
+
+  $ hg $FAKEVERSION --config configwizard.steps=hgversion 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>
+
+
+Old version will print legacy message and prompt
+
+  $ rm fakeversion.pyc
+  $ cat >> fakeversion.py << EOF
+  > util.version = lambda: '3.7.2'
+  > EOF
+
+  $ hg $FAKEVERSION --config configwizard.steps=hgversion 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>
+  You are running an out of date Mercurial client (3.7.2).
+  
+  For a faster and better Mercurial experience, we HIGHLY recommend you
+  upgrade.
+  
+  Legacy versions of Mercurial have known security vulnerabilities. Failure
+  to upgrade may leave you exposed. You are highly encouraged to upgrade in
+  case you aren't running a patched version.
+  
+  Please run `mach bootstrap` to upgrade your Mercurial install.
+  
+  Would you like to continue using an old Mercurial version (Yn)?  y
+
+  $ hg --config ui.interactive=true --config configwizard.steps=hgversion $FAKEVERSION 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>
+  You are running an out of date Mercurial client (3.7.2).
+  
+  For a faster and better Mercurial experience, we HIGHLY recommend you
+  upgrade.
+  
+  Legacy versions of Mercurial have known security vulnerabilities. Failure
+  to upgrade may leave you exposed. You are highly encouraged to upgrade in
+  case you aren't running a patched version.
+  
+  Please run `mach bootstrap` to upgrade your Mercurial install.
+  
+  Would you like to continue using an old Mercurial version (Yn)?  n
+  [1]
+
+
+Too old version will fail outright
+
+  $ rm fakeversion.pyc
+  $ cat >> fakeversion.py << EOF
+  > util.version = lambda: '3.4.2'
+  > EOF
+
+  $ hg $FAKEVERSION --config configwizard.steps=hgversion configwizard
+  Your version of Mercurial is too old to run `hg configwizard`.
+  
+  Mozilla's Mercurial support policy is to support at most the past
+  1 year of Mercurial releases (or 4 major Mercurial releases).
+  abort: upgrade Mercurial then run again
+  [255]