Quantcast

[PATCH 1 of 2] tests: demonstrate `hg show` mapping to showconfig

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 1 of 2] tests: demonstrate `hg show` mapping to showconfig

Gregory Szorc
# HG changeset patch
# User Gregory Szorc <[hidden email]>
# Date 1493333518 25200
#      Thu Apr 27 15:51:58 2017 -0700
# Node ID 706ff3761c606fe127bc4bc3fb5267039e6f9131
# Parent  7040f5131454b0ae9117ec10a9f33352a04746a3
tests: demonstrate `hg show` mapping to showconfig

`hg config` has a "showconfig" alias. In a vanilla installation where
the "show" extension isn't enabled, `hg show` will map to
`hg showconfig`. Add a test demonstrating this confusing behavior.

diff --git a/tests/test-show.t b/tests/test-show.t
--- a/tests/test-show.t
+++ b/tests/test-show.t
@@ -1,3 +1,20 @@
+`hg show` without extension enabled says to enable the extension
+TODO this is broken due to matching with showconfig
+
+  $ hg show
+  defaults.backout=-d "0 0"
+  defaults.commit=-d "0 0"
+  defaults.shelve=--date "0 0"
+  defaults.tag=-d "0 0"
+  devel.all-warnings=true
+  largefiles.usercache=$TESTTMP/.cache/largefiles
+  ui.slash=True
+  ui.interactive=False
+  ui.mergemarkers=detailed
+  ui.promptecho=True
+  web.address=localhost
+  web.ipv6=False
+
   $ cat >> $HGRCPATH << EOF
   > [extensions]
   > show =
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 2 of 2] cmdutil: prevent "show" from matching "showconfig" (BC)

Gregory Szorc
# HG changeset patch
# User Gregory Szorc <[hidden email]>
# Date 1493334106 25200
#      Thu Apr 27 16:01:46 2017 -0700
# Node ID fc33b0dd5feecb4a51e6ef797ff4fffb145a8be7
# Parent  706ff3761c606fe127bc4bc3fb5267039e6f9131
cmdutil: prevent "show" from matching "showconfig" (BC)

cmdutil.findpossible() performs a string prefix match to determine
if a user-provided command/string should map to a command. If there
is an unambiguous match, the mapped command is used.

This causes problems with commands defined by extensions. These
commands aren't in the commands table. So, the command names and
aliases have no opportunity to create a prefix match and prevent
an unambiguous match.

In the case of `hg show`, "show" was being mapped to "showconfig"
because nothing else in core has a "show" prefix.

This commit adds an argument to the @command decorator to define
strings that won't be allowed to partial match the command.
findpossible() has been taught to consult this value. And
`hg config` now doesn't match against "show."

The single test change demonstrates that an out-of-the-box
`hg show` now properly indicates that the command is provided by
an extension.

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -318,8 +318,9 @@ def findpossible(cmd, table, strict=Fals
         if cmd in aliases:
             found = cmd
         elif not strict:
+            nomatch = table[e][0].nomatch
             for a in aliases:
-                if a.startswith(cmd):
+                if a.startswith(cmd) and cmd not in nomatch:
                     found = a
                     break
         if found is not None:
@@ -3363,13 +3364,18 @@ def command(table):
     command line arguments. If True, arguments will be examined for potential
     repository locations. See ``findrepo()``. If a repository is found, it
     will be used.
+
+    ``nomatch`` defines an iterable of command strings that should not result
+    in an alias match. Without this, all string prefixes in ``name`` elements
+    will map to this command.
     """
     def cmd(name, options=(), synopsis=None, norepo=False, optionalrepo=False,
-            inferrepo=False):
+            inferrepo=False, nomatch=None):
         def decorator(func):
             func.norepo = norepo
             func.optionalrepo = optionalrepo
             func.inferrepo = inferrepo
+            func.nomatch = nomatch or []
             if synopsis:
                 table[name] = func, list(options), synopsis
             else:
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1749,7 +1749,9 @@ def _docommit(ui, repo, *pats, **opts):
      ('l', 'local', None, _('edit repository config')),
      ('g', 'global', None, _('edit global config'))] + formatteropts,
     _('[-u] [NAME]...'),
-    optionalrepo=True)
+    optionalrepo=True,
+    # FUTURE can be removed once show extension is moved to core.
+    nomatch=['show'])
 def config(ui, repo, *values, **opts):
     """show combined config settings from all hgrc files
 
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -479,8 +479,12 @@ class cmdalias(object):
         return aliasargs(self.fn, args)
 
     def __getattr__(self, name):
-        adefaults = {r'norepo': True,
-                     r'optionalrepo': False, r'inferrepo': False}
+        adefaults = {
+            'norepo': True,
+            'optionalrepo': False,
+            'inferrepo': False,
+            'nomatch': [],
+        }
         if name not in adefaults:
             raise AttributeError(name)
         if self.badalias or util.safehasattr(self, 'shell'):
diff --git a/tests/test-show.t b/tests/test-show.t
--- a/tests/test-show.t
+++ b/tests/test-show.t
@@ -1,19 +1,14 @@
 `hg show` without extension enabled says to enable the extension
-TODO this is broken due to matching with showconfig
 
   $ hg show
-  defaults.backout=-d "0 0"
-  defaults.commit=-d "0 0"
-  defaults.shelve=--date "0 0"
-  defaults.tag=-d "0 0"
-  devel.all-warnings=true
-  largefiles.usercache=$TESTTMP/.cache/largefiles
-  ui.slash=True
-  ui.interactive=False
-  ui.mergemarkers=detailed
-  ui.promptecho=True
-  web.address=localhost
-  web.ipv6=False
+  hg: unknown command 'show'
+  'show' is provided by the following extension:
+  
+      show          unified command to show various repository information
+                    (EXPERIMENTAL)
+  
+  (use 'hg help extensions' for information on enabling extensions)
+  [255]
 
   $ cat >> $HGRCPATH << EOF
   > [extensions]
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH 2 of 2] cmdutil: prevent "show" from matching "showconfig" (BC)

Yuya Nishihara
On Wed, 17 May 2017 19:13:12 -0700, Gregory Szorc wrote:

> # HG changeset patch
> # User Gregory Szorc <[hidden email]>
> # Date 1493334106 25200
> #      Thu Apr 27 16:01:46 2017 -0700
> # Node ID fc33b0dd5feecb4a51e6ef797ff4fffb145a8be7
> # Parent  706ff3761c606fe127bc4bc3fb5267039e6f9131
> cmdutil: prevent "show" from matching "showconfig" (BC)
>
> cmdutil.findpossible() performs a string prefix match to determine
> if a user-provided command/string should map to a command. If there
> is an unambiguous match, the mapped command is used.
>
> This causes problems with commands defined by extensions. These
> commands aren't in the commands table. So, the command names and
> aliases have no opportunity to create a prefix match and prevent
> an unambiguous match.
>
> In the case of `hg show`, "show" was being mapped to "showconfig"
> because nothing else in core has a "show" prefix.
>
> This commit adds an argument to the @command decorator to define
> strings that won't be allowed to partial match the command.
> findpossible() has been taught to consult this value. And
> `hg config` now doesn't match against "show."
>
> The single test change demonstrates that an out-of-the-box
> `hg show` now properly indicates that the command is provided by
> an extension.
>
> diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
> --- a/mercurial/cmdutil.py
> +++ b/mercurial/cmdutil.py
> @@ -318,8 +318,9 @@ def findpossible(cmd, table, strict=Fals
>          if cmd in aliases:
>              found = cmd
>          elif not strict:
> +            nomatch = table[e][0].nomatch
>              for a in aliases:
> -                if a.startswith(cmd):
> +                if a.startswith(cmd) and cmd not in nomatch:
>                      found = a
>                      break
>          if found is not None:
> @@ -3363,13 +3364,18 @@ def command(table):
>      command line arguments. If True, arguments will be examined for potential
>      repository locations. See ``findrepo()``. If a repository is found, it
>      will be used.
> +
> +    ``nomatch`` defines an iterable of command strings that should not result
> +    in an alias match. Without this, all string prefixes in ``name`` elements
> +    will map to this command.
>      """

The BC seems fine, but I don't think this is a property attached to each
command, but an inter-command thing. I we had "showblahblah" command for
example, it would also have to define the same notmatch list.

Given this is a temporary workaround until "show" gets into the core, I'd
rather make a simple ad-hoc change.
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Loading...