[PATCH 2 of 2 RFC] dispatch: look up command by [<space>:]<cmdname> syntax (PoC)

Yuya Nishihara yuya at tcha.org
Thu Feb 22 09:54:47 EST 2018


# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1516798904 -32400
#      Wed Jan 24 22:01:44 2018 +0900
# Node ID cb9e1cad42a9a13f17c4c75d350cd509b08f4a21
# Parent  e2030eaec92b1ed12577cbe48cd0495d106818a9
dispatch: look up command by [<space>:]<cmdname> syntax (PoC)

This allows us to run the show command without giving up our show alias.
The separator ':' is copied from the merge-tools syntax, ":<internal-tool>".

  [alias]
  show = log -pvr
  work = show:show work

  $ hg work

So, do we like it?

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -707,6 +707,19 @@ def findcmd(cmd, table, strict=True):
 
     raise error.UnknownCommand(cmd, allcmds)
 
+def findcmdspace(name, commands, strict=True):
+    """Look up (aliases, command table entry) from commands module"""
+    # TODO: ':' vs '.'
+    ns, sep, cmd = name.partition(':')
+    if not sep:
+        return findcmd(name, commands.table, strict=strict)
+    table = commands.namespace.get(ns)
+    if table is None:
+        raise error.UnknownCommand(name)
+    # TODO: wrap Ambiguous/UnknownCommand exception to return a full name?
+    # TODO: might want to require strict=True for namespaced name
+    return findcmd(cmd, table, strict=strict)
+
 def changebranch(ui, repo, revs, label):
     """ Change the branch name of given revs to label """
 
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -234,7 +234,7 @@ def _runcatch(req):
         try:
             cmdargs = fancyopts.fancyopts(req.args[:], commands.globalopts, {})
             cmd = cmdargs[0]
-            aliases, entry = cmdutil.findcmd(cmd, commands.table, False)
+            aliases, entry = cmdutil.findcmdspace(cmd, commands, strict=False)
             realcmd = aliases[0]
         except (error.UnknownCommand, error.AmbiguousCommand,
                 IndexError, getopt.GetoptError):
@@ -602,8 +602,8 @@ def _parse(ui, args):
 
     if args:
         cmd, args = args[0], args[1:]
-        aliases, entry = cmdutil.findcmd(cmd, commands.table,
-                                         ui.configbool("ui", "strict"))
+        aliases, entry = cmdutil.findcmdspace(cmd, commands,
+                                              ui.configbool("ui", "strict"))
         cmd = aliases[0]
         args = aliasargs(entry[0], args)
         defaults = ui.config("defaults", cmd)
diff --git a/mercurial/help.py b/mercurial/help.py
--- a/mercurial/help.py
+++ b/mercurial/help.py
@@ -322,8 +322,8 @@ def help_(ui, commands, name, unknowncmd
 
     def helpcmd(name, subtopic=None):
         try:
-            aliases, entry = cmdutil.findcmd(name, commands.table,
-                                             strict=unknowncmd)
+            aliases, entry = cmdutil.findcmdspace(name, commands,
+                                                  strict=unknowncmd)
         except error.AmbiguousCommand as inst:
             # py3k fix: except vars can't be used outside the scope of the
             # except block, nor can be used inside a lambda. python issue4617
@@ -524,7 +524,7 @@ def help_(ui, commands, name, unknowncmd
             indicateomitted(rst, omitted)
 
         try:
-            cmdutil.findcmd(name, commands.table)
+            cmdutil.findcmdspace(name, commands)
             rst.append(_("\nuse 'hg help -c %s' to see help for "
                        "the %s command\n") % (name, name))
         except error.UnknownCommand:
diff --git a/tests/test-dispatch.t b/tests/test-dispatch.t
--- a/tests/test-dispatch.t
+++ b/tests/test-dispatch.t
@@ -11,6 +11,24 @@ Redundant options used to crash (issue43
   $ hg ci -Ama
   adding a
 
+Look up command by canonical name:
+
+  $ hg :log
+  changeset:   0:cb9a9f314b8b
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     a
+  
+  $ hg --config alias.log='log -G' :log
+  changeset:   0:cb9a9f314b8b
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     a
+  
+  $ hg --config extensions.purge= purge:purge
+
 Missing arg:
 
   $ hg cat
diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -496,6 +496,14 @@ Test ambiguous command help
   
   (use 'hg help -v ad' to show built-in aliases and global options)
 
+  $ hg help :ad
+  list of commands:
+  
+   add           add the specified files on the next commit
+   addremove     add all new files, delete all missing files
+  
+  (use 'hg help -v :ad' to show built-in aliases and global options)
+
 Test command without options
 
   $ hg help verify
@@ -670,6 +678,13 @@ Test command without options
   (use 'hg help' for the full list of commands or 'hg -v' for details)
   [255]
 
+Look up command by canonical name:
+
+  $ hg --config alias.status=log help status | grep 'alias for'
+  alias for: hg log
+  $ hg --config alias.status=log help :status | grep 'alias for'
+  [1]
+
 Typoed command gives suggestion
   $ hg puls
   hg: unknown command 'puls'


More information about the Mercurial-devel mailing list