[PATCH] commands: add 'setup' command to allow automatic hgrc configuration

Mathias De Maré mathias.demare at gmail.com
Thu Mar 12 12:07:25 CDT 2015


# HG changeset patch
# User Mathias De Maré <mathias.demare at gmail.com>
# Date 1426162870 -3600
#      Thu Mar 12 13:21:10 2015 +0100
# Node ID 0de0fc66a20a5f0658a6c6f1f5de20d4705f3de1
# Parent  7cf9a9e0cf893e7ae82dc576a03c843fd6640438
commands: add 'setup' command to allow automatic hgrc configuration

This is a proposal meant to easily set up new users with
a good hgrc file. It's very basic (a combination of
'release early' and 'I don't have a lot of time').
Comments are very much welcome.

I wasn't too sure about using the first path
listed in the userhgrc, not sure if that's the best approach.

Some other ideas to throw out there:
- Running 'setup' by default if a user does not have a .hgrc
      and is using the terminal (possibly falls under moot?)
- Perhaps having a global 'do you want to have a lot of sensible defaults set'
  question could be useful as well.
- Popping up a merge window in case a user already has a .hgrc.
  This could allow the user to do the merge,
  and avoids us having to mess with editing configs
  (this was a very good idea by smf).

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -19,10 +19,12 @@
 import merge as mergemod
 import minirst, revset, fileset
 import dagparser, context, simplemerge, graphmod, copies
+import query
 import random
 import setdiscovery, treediscovery, dagutil, pvec, localrepo
 import phases, obsolete, exchange, bundle2
 import ui as uimod
+import config as configmod
 
 table = {}
 
@@ -5615,6 +5617,50 @@
         self.httpd.serve_forever()
 
 
+ at command('setup', [])
+def setup(ui, repo):
+    """run a setup to generate a Mercurial configuration
+
+    Answer a few questions to generate a basic Mercurial configuration.
+
+    Returns 0 on success.
+    """
+
+    paths = scmutil.userrcpath()
+    if os.path.isfile(paths[0]):
+        if not query.binaryquery(repo,
+                _('WARNING: you already have a ' \
+                'Mercurial configuration file!\n' \
+                'Are you sure you want to overwrite it ' \
+                'with a new configuration?'),
+            False):
+            return
+
+    userconfig = configmod.config()
+
+    if query.binaryquery(repo,
+            _('Would you like to configure your username? '), True):
+        name = query.textquery(repo, _('Please enter your name: '))
+        email = query.textquery(repo, _('Please enter your email adress: '))
+        userconfig.set('ui', 'username', '%s <%s>' % (name, email))
+    if query.binaryquery(repo, _('Would you like to enable ' \
+            'some useful extensions by default, ' \
+            'enhancing your experience?\n' \
+            'The extensions to be enabled are: ' \
+            'color, pager, progress'), True):
+        userconfig.set('extensions', 'color', '')
+        userconfig.set('extensions', 'pager', '')
+        userconfig.set('pager', 'pager', 'less -FRX')
+        userconfig.set('extensions', 'progress', '')
+    if query.binaryquery(repo,
+            'Would you like to use an extended diff format? ' \
+            'If you are viewing changes, ' \
+            'this allows you to easily see added/removed files.',
+            True):
+        userconfig.set('diff', 'git', True)
+    userconfig.write(paths[0])
+
+
 @command('^status|st',
     [('A', 'all', None, _('show status of all files')),
     ('m', 'modified', None, _('show only modified files')),
diff --git a/mercurial/config.py b/mercurial/config.py
--- a/mercurial/config.py
+++ b/mercurial/config.py
@@ -157,3 +157,13 @@
         if not fp:
             fp = util.posixfile(path)
         self.parse(path, fp.read(), sections, remap, self.read)
+
+    def write(self, path, fp=None):
+        if not fp:
+            fp = util.posixfile(path, 'w')
+        for section in self:
+            d = self[section]
+            fp.write('[%s]\n' % section)
+            for key in d:
+                fp.write('%s = %s\n' % (key, d[key]))
+            fp.write('\n')
diff --git a/mercurial/query.py b/mercurial/query.py
new file mode 100644
--- /dev/null
+++ b/mercurial/query.py
@@ -0,0 +1,42 @@
+# query.py - user querying for mercurial
+#
+# Copyright 2015 Mathias De Maré <mathias.demare at gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+def _generateresponsestr(responses, default):
+    defaultidx = responses.index(default)
+    if defaultidx >= 0 and len(responses[defaultidx]) > 0:
+        responses[defaultidx] = responses[defaultidx].title()
+    return '(%s)' % '/'.join(responses)
+
+def textquery(repo, question, emptyallowed=False):
+    """Query the user using an open question"""
+    repo.ui.write('%s\n' % question)
+    while True:
+        res = raw_input()
+        if emptyallowed or len(res):
+            return res
+
+def optionquery(repo, question, responses, default):
+    """Query the user using question and a given set of parameters.
+    Once a valid response is given, the query returns
+    the match from the list of responses."""
+    repo.ui.write('%s %s\n' % (question, _generateresponsestr(responses, default)))
+    while True:
+        res = raw_input()
+        if not len(res) and default:
+            return default
+        for response in responses:
+            if response.startswith(res):
+                return response
+
+def binaryquery(repo, question, default=True):
+    """Query the user using question and 'yes/no'"""
+    if default:
+        default = 'yes'
+    else:
+        default = 'no'
+    res = optionquery(repo, question, ['yes', 'no'], default)
+    return res == 'yes'


More information about the Mercurial-devel mailing list