Patchwork [2,of,2,STABLE] dispatch: check shell alias again after loading extensions (issue4355)

login
register
mail settings
Submitter Katsunori FUJIWARA
Date Sept. 9, 2014, 4:32 p.m.
Message ID <b87035951eca955a2961.1410280357@feefifofum>
Download mbox | patch
Permalink /patch/5738/
State Accepted
Headers show

Comments

Katsunori FUJIWARA - Sept. 9, 2014, 4:32 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1410277304 -32400
#      Wed Sep 10 00:41:44 2014 +0900
# Branch stable
# Node ID b87035951eca955a2961da5327e3faf15eee4827
# Parent  da54cba6a073c5cbe04e73ebbfb043c49066d215
dispatch: check shell alias again after loading extensions (issue4355)

Before this patch, the shell alias causes failure when it takes its
specific (= unknown for "hg") options in the command line, because
"_parse()" can't accept them.

This is the regression introduced by 03d345da0579.

It fixed the issue that ambiguity between shell aliases and commands
defined by extensions was ignored. But it also caused that ambiguous
shell alias is handled in "_parse()" even if it takes specific options
in the command line.

To avoid such failure, this patch checks shell alias again after
loading extensions.

All aliases and commands (including ones defined by extensions) are
completely defined before the 2nd (= newly added in this patch)
"_checkshellalias()" invocation, and "cmdutil.findcmd(strict=False)"
can detect ambiguity between them correctly.

For efficiency, this patch does:

  - omit the 2nd "_checkshellalias()" invocation if "[ui] strict= True"

    it causes "cmdutil.findcmd(strict=True)", of which result should
    be equal to one of the 1st invocation before adding aliases

  - avoid removing the 1st "_checkshellalias()" invocation

    it causes "cmdutil.findcmd(strict=True)" invocation preventing
    shell alias execution from loading extensions uselessly
Augie Fackler - Sept. 9, 2014, 5:47 p.m.
On Wed, Sep 10, 2014 at 01:32:37AM +0900, FUJIWARA Katsunori wrote:
> # HG changeset patch
> # User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
> # Date 1410277304 -32400
> #      Wed Sep 10 00:41:44 2014 +0900
> # Branch stable
> # Node ID b87035951eca955a2961da5327e3faf15eee4827
> # Parent  da54cba6a073c5cbe04e73ebbfb043c49066d215
> dispatch: check shell alias again after loading extensions (issue4355)

Thanks for the very thorough log message. Despite my general
discomfort with dispatch code, I've queued this for stable. Thanks!


>
> Before this patch, the shell alias causes failure when it takes its
> specific (= unknown for "hg") options in the command line, because
> "_parse()" can't accept them.
>
> This is the regression introduced by 03d345da0579.
>
> It fixed the issue that ambiguity between shell aliases and commands
> defined by extensions was ignored. But it also caused that ambiguous
> shell alias is handled in "_parse()" even if it takes specific options
> in the command line.
>
> To avoid such failure, this patch checks shell alias again after
> loading extensions.
>
> All aliases and commands (including ones defined by extensions) are
> completely defined before the 2nd (= newly added in this patch)
> "_checkshellalias()" invocation, and "cmdutil.findcmd(strict=False)"
> can detect ambiguity between them correctly.
>
> For efficiency, this patch does:
>
>   - omit the 2nd "_checkshellalias()" invocation if "[ui] strict= True"
>
>     it causes "cmdutil.findcmd(strict=True)", of which result should
>     be equal to one of the 1st invocation before adding aliases
>
>   - avoid removing the 1st "_checkshellalias()" invocation
>
>     it causes "cmdutil.findcmd(strict=True)" invocation preventing
>     shell alias execution from loading extensions uselessly
>
> diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
> --- a/mercurial/dispatch.py
> +++ b/mercurial/dispatch.py
> @@ -644,6 +644,7 @@
>          return
>
>      if precheck:
> +        strict = True
>          norepo = commands.norepo
>          optionalrepo = commands.optionalrepo
>          def restorecommands():
> @@ -652,13 +653,14 @@
>          cmdtable = commands.table.copy()
>          addaliases(lui, cmdtable)
>      else:
> +        strict = False
>          def restorecommands():
>              pass
>          cmdtable = commands.table
>
>      cmd = args[0]
>      try:
> -        aliases, entry = cmdutil.findcmd(cmd, cmdtable)
> +        aliases, entry = cmdutil.findcmd(cmd, cmdtable, strict)
>      except (error.AmbiguousCommand, error.UnknownCommand):
>          restorecommands()
>          return
> @@ -715,6 +717,14 @@
>
>      addaliases(lui, commands.table)
>
> +    if not lui.configbool("ui", "strict"):
> +        # All aliases and commands are completely defined, now.
> +        # Check abbreviation/ambiguity of shell alias again, because shell
> +        # alias may cause failure of "_parse" (see issue4355)
> +        shellaliasfn = _checkshellalias(lui, ui, args, precheck=False)
> +        if shellaliasfn:
> +            return shellaliasfn()
> +
>      # check for fallback encoding
>      fallback = lui.config('ui', 'fallbackencoding')
>      if fallback:
> diff --git a/tests/test-alias.t b/tests/test-alias.t
> --- a/tests/test-alias.t
> +++ b/tests/test-alias.t
> @@ -353,7 +353,7 @@
>    > [extensions]
>    > hgext.rebase =
>    > [alias]
> -  > rebate = !echo this is rebate
> +  > rebate = !echo this is \$HG_ARGS
>    > EOF
>    $ hg reba
>    hg: command 'reba' is ambiguous:
> @@ -361,6 +361,8 @@
>    [255]
>    $ hg rebat
>    this is rebate
> +  $ hg rebat --foo-bar
> +  this is rebate --foo-bar
>
>  invalid arguments
>
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -644,6 +644,7 @@ 
         return
 
     if precheck:
+        strict = True
         norepo = commands.norepo
         optionalrepo = commands.optionalrepo
         def restorecommands():
@@ -652,13 +653,14 @@ 
         cmdtable = commands.table.copy()
         addaliases(lui, cmdtable)
     else:
+        strict = False
         def restorecommands():
             pass
         cmdtable = commands.table
 
     cmd = args[0]
     try:
-        aliases, entry = cmdutil.findcmd(cmd, cmdtable)
+        aliases, entry = cmdutil.findcmd(cmd, cmdtable, strict)
     except (error.AmbiguousCommand, error.UnknownCommand):
         restorecommands()
         return
@@ -715,6 +717,14 @@ 
 
     addaliases(lui, commands.table)
 
+    if not lui.configbool("ui", "strict"):
+        # All aliases and commands are completely defined, now.
+        # Check abbreviation/ambiguity of shell alias again, because shell
+        # alias may cause failure of "_parse" (see issue4355)
+        shellaliasfn = _checkshellalias(lui, ui, args, precheck=False)
+        if shellaliasfn:
+            return shellaliasfn()
+
     # check for fallback encoding
     fallback = lui.config('ui', 'fallbackencoding')
     if fallback:
diff --git a/tests/test-alias.t b/tests/test-alias.t
--- a/tests/test-alias.t
+++ b/tests/test-alias.t
@@ -353,7 +353,7 @@ 
   > [extensions]
   > hgext.rebase =
   > [alias]
-  > rebate = !echo this is rebate
+  > rebate = !echo this is \$HG_ARGS
   > EOF
   $ hg reba
   hg: command 'reba' is ambiguous:
@@ -361,6 +361,8 @@ 
   [255]
   $ hg rebat
   this is rebate
+  $ hg rebat --foo-bar
+  this is rebate --foo-bar
 
 invalid arguments