mqext: use @command for declaring commands (bug 1255931); r?dminor draft
authorGregory Szorc <gps@mozilla.com>
Fri, 11 Mar 2016 16:32:06 -0800
changeset 7486 64fded23bc4ffa69ab11110717034477e567d99b
parent 7485 204d12da50b30d9cd6a8ce4516bf96506581c7d4
child 7487 29308a2c06b9a218511d86c93b3637de194903cb
push id694
push usergszorc@mozilla.com
push dateSat, 12 Mar 2016 00:42:16 +0000
reviewersdminor
bugs1255931
mqext: use @command for declaring commands (bug 1255931); r?dminor Populating the cmdtable dict directly is no longer supported in Mercurial 3.8. MozReview-Commit-ID: BDrl54AiI03
hgext/mqext/__init__.py
--- a/hgext/mqext/__init__.py
+++ b/hgext/mqext/__init__.py
@@ -70,17 +70,17 @@ Alternatively, if you only want a subset
 the -Q option to all relevant commands in your ~/.hgrc::
 
   [defaults]
   qnew = -Q
   qdelete = -Q
   qimport = -Q
 '''
 
-testedwith = '3.2 3.3 3.3 3.4 3.5'
+testedwith = '3.4 3.5 3.6 3.7'
 
 import os
 import re
 import json
 import urllib2
 
 from mercurial.i18n import _
 from mercurial.node import short
@@ -101,18 +101,24 @@ except:
     try:
         # hg 1.9+
         from mercurial.scmutil import canonpath
     except:
         from mercurial.util import canonpath
 
 buglink = 'https://bugzilla.mozilla.org/enter_bug.cgi?product=Developer%20Services&component=General'
 
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
 bugzilla_jsonrpc_url = "https://bugzilla.mozilla.org/jsonrpc.cgi"
 
+@command('qshow', [
+    ('', 'stat', None, 'output diffstat-style summary of changes')],
+    ('hg qshow [patch]'))
 def qshow(ui, repo, patchspec=None, **opts):
     '''display a patch
 
     If no patch is given, the top of the applied stack is shown.'''
     q = repo.mq
 
     patchf = None
     if patchspec is None:
@@ -246,16 +252,22 @@ def patch_changes(ui, repo, patchfile=No
             break
         left -= 1
         yield repo[ctx.rev()]
 
 fileRe = re.compile(r"^\+\+\+ (?:b/)?([^\s]*)", re.MULTILINE)
 suckerRe = re.compile(r"[^s-]r=(\w+)")
 supersuckerRe = re.compile(r"sr=(\w+)")
 
+@command('reviewers', [
+    ('f', 'file', [], 'see reviewers for FILE', 'FILE'),
+    ('r', 'rev', [], 'see reviewers for revisions', 'REVS'),
+    ('l', 'limit', 200, 'how many revisions back to scan', 'LIMIT'),
+    ('', 'brief', False, 'shorter output')],
+    _('hg reviewers [-f FILE1 -f FILE2...] [-r REVS] [-l LIMIT] [PATCH]'))
 def reviewers(ui, repo, patchfile=None, **opts):
     '''Suggest a reviewer for a patch
 
     Scan through the last LIMIT commits to find candidate reviewers for a
     patch (or set of files).
 
     The patch may be given as a file or a URL. If no patch is specified,
     the changes in the working directory will be used. If there are no
@@ -358,16 +370,22 @@ def fetch_bugs(url, ui, bugs):
                 bs = list(bugs)
                 parts = [ bs[i:len(bugs):nparts] for i in range(0,nparts) ]
             return reduce(lambda bs,p: bs + fetch_bugs(url, ui, p), parts, [])
 
         raise util.Abort("Failed to retrieve bugs, last buginfo=%r" % (buginfo,))
 
     return buginfo['result']['bugs']
 
+@command('components', [
+    ('f', 'file', [], 'see components for FILE', 'FILE'),
+    ('r', 'rev', [], 'see reviewers for revisions', 'REVS'),
+    ('l', 'limit', 25, 'how many revisions back to scan', 'LIMIT'),
+    ('', 'brief', False, 'shorter output')],
+    _('hg components [-f FILE1 -f FILE2...] [-r REVS] [-l LIMIT] [PATCH]'))
 def bzcomponents(ui, repo, patchfile=None, **opts):
     '''Suggest a bugzilla product and component for a patch
 
     Scan through the last LIMIT commits to find bug product/components that
     touch the same files.
 
     The patch may be given as a file or a URL. If no patch is specified,
     the changes in the working directory will be used. If there are no
@@ -410,16 +428,20 @@ def bzcomponents(ui, repo, patchfile=Non
 
     ui.write("Potential components:\n")
     if len(components) == 0:
         ui.write("  none found in range (try higher --limit?)\n")
     else:
         for (comp, count) in components.most_common(5):
             ui.write("  %s: %d\n" % (comp, count))
 
+@command('bugs', [
+    ('f', 'file', [], 'see bugs for FILE', 'FILE'),
+    ('l', 'limit', 100, 'how many revisions back to scan', 'LIMIT')],
+    _('hg bugs [-f FILE1 -f FILE2...] [-l LIMIT] [PATCH]'))
 def bzbugs(ui, repo, patchfile=None, **opts):
     '''List the bugs that have modified the files in a patch
 
     Scan through the last LIMIT commits to find bugs that touch the same files.
 
     The patch may be given as a file or a URL. If no patch is specified,
     the changes in the working directory will be used. If there are no
     changes, the topmost applied patch in your mq repository will be used.
@@ -435,16 +457,20 @@ def bzbugs(ui, repo, patchfile=None, **o
             bugs.add(m.group(2))
 
     if bugs:
         for bug in bugs:
             ui.write("bug %s\n" % bug)
     else:
         ui.write("No bugs found\n")
 
+@command('qtouched', [
+    ('a', 'applied', None, 'only consider applied patches'),
+    ('p', 'patch', '', 'restrict to given patch')],
+    _('hg touched [-a] [-p PATCH] [FILE]'))
 def touched(ui, repo, sourcefile=None, **opts):
     '''Show what files are touched by what patches
 
     If no file is given, print out a series of lines containing a
     patch and a file changed by that patch, for all files changed by
     all patches. This is mainly intended for easy grepping.
 
     If a file is given, print out the list of patches that touch that file.'''
@@ -467,16 +493,17 @@ def touched(ui, repo, sourcefile=None, *
             if sourcefile is None:
                 ui.write(patchname + "\t" + filename + "\n")
             elif sourcefile == filename:
                 ui.write(patchname + "\n")
 
 qparent_re = re.compile('^qparent: (\S+)$', re.M)
 top_re = re.compile('^top: (\S+)$', re.M)
 
+@command('qrevert', [], _('hg qrevert REV'))
 def qrevert(ui, repo, rev, **opts):
     '''
     Revert to a past mq state. This updates both the main checkout as well as
     the patch directory, and leaves either or both at a non-head revision.
     '''
     q = repo.mq
     if not q or not q.qrepo():
         raise util.Abort(_("No revisioned patch queue found"))
@@ -681,16 +708,22 @@ def qdelete_wrapper(orig, self, repo, *p
 
     if mqcommit and mqmessage:
         mqmessage = substitute_mqmessage(mqmessage, repo,
                                          { 'a': 'DELETE',
                                            'P': '%d patches - %s' % (len(patches), " ".join(patchnames)),
                                            '[]': patchnames })
         commands.commit(r.ui, r, message=mqmessage)
 
+@command('urls', [
+    ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
+    ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
+    ('u', 'user', [], _('revisions committed by user'), _('USER')),
+    ] + commands.logopts,
+    _('hg urls [-l LIMIT] [NAME]'))
 def urls(ui, repo, *paths, **opts):
     '''Display a list of urls for the last several commits.
     These are merely heuristic guesses and are intended for pasting into
     bugs after landing. If that makes no sense to you, then you are probably
     not the intended audience. It's mainly a Mozilla thing.
 
     Note that this will display the URL for your default repo, which may very
     well be something local. So you may need to give your outbound repo as
@@ -753,68 +786,16 @@ def qcrecord_wrapper(orig, self, repo, p
     if ret:
         return ret
 
     if mqcommit and mqmessage:
         mqmessage = substitute_mqmessage(mqmessage, repo, { 'p': patchfn,
                                                             'a': 'NEW' })
         commands.commit(r.ui, r, message=mqmessage)
 
-cmdtable = {
-    'qshow': (qshow,
-              [('', 'stat', None, 'output diffstat-style summary of changes'),
-               ],
-              ('hg qshow [patch]')),
-
-    'reviewers':
-        (reviewers,
-         [('f', 'file', [], 'see reviewers for FILE', 'FILE'),
-          ('r', 'rev', [], 'see reviewers for revisions', 'REVS'),
-          ('l', 'limit', 200, 'how many revisions back to scan', 'LIMIT'),
-          ('', 'brief', False, 'shorter output'),
-          ],
-         ('hg reviewers [-f FILE1 -f FILE2...] [-r REVS] [-l LIMIT] [PATCH]')),
-
-    'bugs':
-        (bzbugs,
-         [('f', 'file', [], 'see bugs for FILE', 'FILE'),
-          ('l', 'limit', 100, 'how many revisions back to scan', 'LIMIT')
-          ],
-         ('hg bugs [-f FILE1 -f FILE2...] [-l LIMIT] [PATCH]')),
-
-    'components':
-        (bzcomponents,
-         [('f', 'file', [], 'see components for FILE', 'FILE'),
-          ('r', 'rev', [], 'see reviewers for revisions', 'REVS'),
-          ('l', 'limit', 25, 'how many revisions back to scan', 'LIMIT'),
-          ('', 'brief', False, 'shorter output'),
-          ],
-         ('hg components [-f FILE1 -f FILE2...] [-r REVS] [-l LIMIT] [PATCH]')),
-
-    'qtouched':
-        (touched,
-         [('a', 'applied', None, 'only consider applied patches'),
-          ('p', 'patch', '', 'restrict to given patch')
-          ],
-         ('hg touched [-a] [-p PATCH] [FILE]')),
-
-    'urls':
-        (urls,
-         [('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
-          ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
-          ('u', 'user', [], _('revisions committed by user'), _('USER')),
-          ] + commands.logopts,
-         ('hg urls [-l LIMIT] [NAME]')),
-
-    'qrevert':
-        (qrevert,
-         [],
-         ('hg qrevert REV')),
-}
-
 def uisetup(ui):
     try:
         mq = extensions.find('mq')
         if mq is None:
             ui.warn("mqext extension is mostly disabled when mq is disabled")
             return
     except KeyError:
         ui.warn("mqext extension is mostly disabled when mq is not installed")