[PATCH 3 of 5] dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara
yuya at tcha.org
Sat Dec 2 02:00:41 EST 2017
# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1511446736 -32400
# Thu Nov 23 23:18:56 2017 +0900
# Node ID eaa3dd26e7da4b6ab73c9b124697a607324bef36
# Parent fd8f98308ad7cfe10465c21190c8611ad9b3572f
dispatch: replace _earlygetopt(strip=True) with new parser
The execution order in cmdalias.__init__() is adjusted to set stripped args
to self.givenargs, which is no longer updated in place.
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -103,10 +103,6 @@ globalopts = [
_("when to paginate (boolean, always, auto, or never)"), _('TYPE')),
]
-# options which must be pre-parsed before loading configs and extensions
-# TODO: perhaps --debugger should be included
-earlyoptflags = ("--cwd", "-R", "--repository", "--repo", "--config")
-
dryrunopts = cmdutil.dryrunopts
remoteopts = cmdutil.remoteopts
walkopts = cmdutil.walkopts
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -466,16 +466,15 @@ class cmdalias(object):
self.badalias = (_("error in definition for alias '%s': %s")
% (self.name, inst))
return
+ earlyopts, args = _earlysplitopts(args)
+ if earlyopts:
+ self.badalias = (_("error in definition for alias '%s': %s may "
+ "only be given on the command line")
+ % (self.name, '/'.join(zip(*earlyopts)[0])))
+ return
self.cmdname = cmd = args.pop(0)
self.givenargs = args
- for invalidarg in commands.earlyoptflags:
- if _earlygetopt([invalidarg], args):
- self.badalias = (_("error in definition for alias '%s': %s may "
- "only be given on the command line")
- % (self.name, invalidarg))
- return
-
try:
tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
if len(tableentry) > 2:
@@ -651,91 +650,13 @@ def _earlyparseopts(ui, args):
optaliases={'repository': ['repo']})
return options
-def _earlygetopt(aliases, args, strip=True):
- """Return list of values for an option (or aliases).
-
- The values are listed in the order they appear in args.
- The options and values are removed from args if strip=True.
-
- >>> args = [b'x', b'--cwd', b'foo', b'y']
- >>> _earlygetopt([b'--cwd'], args), args
- (['foo'], ['x', 'y'])
-
- >>> args = [b'x', b'--cwd=bar', b'y']
- >>> _earlygetopt([b'--cwd'], args), args
- (['bar'], ['x', 'y'])
-
- >>> args = [b'x', b'--cwd=bar', b'y']
- >>> _earlygetopt([b'--cwd'], args, strip=False), args
- (['bar'], ['x', '--cwd=bar', 'y'])
-
- >>> args = [b'x', b'-R', b'foo', b'y']
- >>> _earlygetopt([b'-R'], args), args
- (['foo'], ['x', 'y'])
-
- >>> args = [b'x', b'-R', b'foo', b'y']
- >>> _earlygetopt([b'-R'], args, strip=False), args
- (['foo'], ['x', '-R', 'foo', 'y'])
-
- >>> args = [b'x', b'-Rbar', b'y']
- >>> _earlygetopt([b'-R'], args), args
- (['bar'], ['x', 'y'])
-
- >>> args = [b'x', b'-Rbar', b'y']
- >>> _earlygetopt([b'-R'], args, strip=False), args
- (['bar'], ['x', '-Rbar', 'y'])
-
- >>> args = [b'x', b'-R=bar', b'y']
- >>> _earlygetopt([b'-R'], args), args
- (['=bar'], ['x', 'y'])
-
- >>> args = [b'x', b'-R', b'--', b'y']
- >>> _earlygetopt([b'-R'], args), args
- ([], ['x', '-R', '--', 'y'])
- """
- try:
- argcount = args.index("--")
- except ValueError:
- argcount = len(args)
- shortopts = [opt for opt in aliases if len(opt) == 2]
- values = []
- pos = 0
- while pos < argcount:
- fullarg = arg = args[pos]
- equals = -1
- if arg.startswith('--'):
- equals = arg.find('=')
- if equals > -1:
- arg = arg[:equals]
- if arg in aliases:
- if equals > -1:
- values.append(fullarg[equals + 1:])
- if strip:
- del args[pos]
- argcount -= 1
- else:
- pos += 1
- else:
- if pos + 1 >= argcount:
- # ignore and let getopt report an error if there is no value
- break
- values.append(args[pos + 1])
- if strip:
- del args[pos:pos + 2]
- argcount -= 2
- else:
- pos += 2
- elif arg[:2] in shortopts:
- # short option can have no following space, e.g. hg log -Rfoo
- values.append(args[pos][2:])
- if strip:
- del args[pos]
- argcount -= 1
- else:
- pos += 1
- else:
- pos += 1
- return values
+def _earlysplitopts(args):
+ """Split args into a list of possible early options and remainder args"""
+ shortoptions = 'R:'
+ # TODO: perhaps 'debugger' should be included
+ longoptions = ['cwd=', 'repository=', 'repo=', 'config=']
+ return fancyopts.earlygetopt(args, shortoptions, longoptions,
+ gnu=True, keepsep=True)
def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
# run pre-hook, and abort if it fails
@@ -804,8 +725,7 @@ def _checkshellalias(lui, ui, args):
if cmd and util.safehasattr(fn, 'shell'):
# shell alias shouldn't receive early options which are consumed by hg
- args = args[:]
- _earlygetopt(commands.earlyoptflags, args, strip=True)
+ _earlyopts, args = _earlysplitopts(args)
d = lambda: fn(ui, *args[1:])
return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d,
[], {})
diff --git a/tests/test-alias.t b/tests/test-alias.t
--- a/tests/test-alias.t
+++ b/tests/test-alias.t
@@ -119,6 +119,12 @@ no closing quotation
$ hg help noclosing
error in definition for alias 'noclosingquotation': No closing quotation
+"--" in alias definition should be preserved
+
+ $ hg --config alias.dash='cat --' -R alias dash -r0
+ abort: -r0 not under root '$TESTTMP/alias'
+ (consider using '--cwd alias')
+ [255]
invalid options
@@ -148,6 +154,12 @@ invalid options
$ hg no--config
abort: error in definition for alias 'no--config': --config may only be given on the command line
[255]
+ $ hg no --config alias.no='--repo elsewhere --cwd elsewhere status'
+ abort: error in definition for alias 'no': --repo/--cwd may only be given on the command line
+ [255]
+ $ hg no --config alias.no='--repo elsewhere'
+ abort: error in definition for alias 'no': --repo may only be given on the command line
+ [255]
optional repository
@@ -351,6 +363,10 @@ shell aliases with global options
$ hg echoall --cwd ..
+"--" passed to shell alias should be preserved
+
+ $ hg --config alias.printf='!printf "$@"' printf '%s %s %s\n' -- --cwd ..
+ -- --cwd ..
repo specific shell aliases
More information about the Mercurial-devel
mailing list