[PATCH 4 of 5 STABLE RFC] dispatch: ignore --early-bool-option that might not be a flag (BC)
Augie Fackler
raf at durin42.com
Fri Nov 17 17:41:04 EST 2017
On Wed, Nov 15, 2017 at 09:54:23PM +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya at tcha.org>
> # Date 1510321154 -32400
> # Fri Nov 10 22:39:14 2017 +0900
> # Branch stable
> # Node ID c2c34cf080aefbd983320bdaca111ebbd0826ff3
> # Parent 5838a6130d07b588e4640542865e3c175a124bff
> dispatch: ignore --early-bool-option that might not be a flag (BC)
This one worries me less. Maybe we can land it?
>
> The basic idea is if the preceding arg doesn't look like a flag taking a
> value, the current arg can be parsed as a flag.
>
> hg ci -m --foo --config # bad: --foo may be a flag
> hg ci -m --verbose --config # good: --verbose known to take no value
> # whether it is a value for -m or a flag
>
> --debugger/--profile/--traceback are all for developers. They don't need to
> be any fancy. So let's turn it to safer side.
>
> diff --git a/mercurial/commands.py b/mercurial/commands.py
> --- a/mercurial/commands.py
> +++ b/mercurial/commands.py
> @@ -106,6 +106,22 @@ globalopts = [
> # TODO: perhaps --debugger should be included
> earlyoptflags = ("--cwd", "-R", "--repository", "--repo", "--config")
>
> +# core options known to be always boolean type (i.e. takes no value)
> +corebooloptflags = {
> + '-y', '--noninteractive',
> + '-q', '--quiet',
> + '-v', '--verbose',
> + '--debug',
> + '--debugger',
> + '--traceback',
> + '--time',
> + '--profile',
> + '--version',
> + '-h', '--help',
> + '--hidden',
> + '--mq', # mostly global as mqopt is inserted into all repo commands
> +}
> +
> 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
> @@ -644,6 +644,13 @@ def _parseconfig(ui, config):
>
> return configs
>
> +def _argmaytakevalue(arg):
> + """True if the given arg looks like an option flag taking the next item
> + as its value"""
> + return (arg.startswith('-')
> + and not (arg.startswith('--') and '=' in arg) # --opt=val
> + and arg not in commands.corebooloptflags)
> +
> def _earlygetopt(aliases, args, strip=True):
> """Return list of values for an option (or aliases).
>
> @@ -751,17 +758,48 @@ def _earlyreqoptbool(req, name, aliases)
>
> >>> req = request([b'x', b'--', b'--debugger'])
> >>> _earlyreqoptbool(req, b'debugger', [b'--debugger'])
> +
> + Options can't appear immediately after any option-like flag:
> +
> + >>> req = request([b'x', b'-z', b'--debugger'])
> + >>> _earlyreqoptbool(req, b'debugger', [b'--debugger'])
> +
> + >>> req = request([b'x', b'-z', b'--zzz', b'--debugger'])
> + >>> _earlyreqoptbool(req, b'debugger', [b'--debugger'])
> +
> + unless the preceding flag is known to be a boolean:
> +
> + >>> req = request([b'x', b'-v', b'--debugger'])
> + >>> _earlyreqoptbool(req, b'debugger', [b'--debugger'])
> + True
> +
> + >>> req = request([b'x', b'--debug', b'--debugger'])
> + >>> _earlyreqoptbool(req, b'debugger', [b'--debugger'])
> + True
> +
> + >>> req = request([b'x', b'-z', b'--debugger', b'--debugger'])
> + >>> _earlyreqoptbool(req, b'debugger', [b'--debugger'])
> + True
> +
> + or it takes an immediate value:
> +
> + >>> req = request([b'x', b'--foo=bar', b'--debugger'])
> + >>> _earlyreqoptbool(req, b'debugger', [b'--debugger'])
> + True
> """
> try:
> argcount = req.args.index("--")
> except ValueError:
> argcount = len(req.args)
> value = None
> + inopt = False
> pos = 0
> while pos < argcount:
> arg = req.args[pos]
> - if arg in aliases:
> + if arg in aliases and not inopt:
> value = True
> + else:
> + inopt = _argmaytakevalue(arg)
> pos += 1
> req.earlyoptions[name] = value
> return value
> @@ -897,7 +935,8 @@ def _dispatch(req):
> "option -R has to be separated from other options (e.g. not "
> "-qR) and --repository may only be abbreviated as --repo!"))
> if options["debugger"] != req.earlyoptions["debugger"]:
> - raise error.Abort(_("option --debugger may not be abbreviated!"))
> + raise error.Abort(_("option --debugger may not be abbreviated "
> + "and should come very first!"))
> # don't validate --profile/--traceback, which can be enabled from now
>
> if options["encoding"]:
> diff --git a/tests/test-dispatch.t b/tests/test-dispatch.t
> --- a/tests/test-dispatch.t
> +++ b/tests/test-dispatch.t
> @@ -54,7 +54,12 @@ Parsing of early options should stop at
> Unparsable form of early options:
>
> $ hg cat --debugg
> - abort: option --debugger may not be abbreviated!
> + abort: option --debugger may not be abbreviated and should come very first!
> + [255]
> + $ hg log -T --debugger
> + --debugger (no-eol)
> + $ hg log -T -T --debugger
> + abort: option --debugger may not be abbreviated and should come very first!
> [255]
>
> Parsing failure of early options should be detected before executing the
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
More information about the Mercurial-devel
mailing list