[PATCH 1 of 1 RFC] dispatch: run "hg --help", "hg --version", and "hg" through runcommand()
Brodie Rao
brodie at sf.io
Fri May 18 17:57:42 CDT 2012
On Fri, May 18, 2012 at 2:26 PM, Matt Mackall <mpm at selenic.com> wrote:
> On Sun, 2012-05-13 at 22:08 +0200, Brodie Rao wrote:
>> # HG changeset patch
>> # User Brodie Rao <brodie at sf.io>
>> # Date 1336924194 -7200
>> # Node ID cdfd3ed7d957ff3b4aecf029313100b5a494e2cc
>> # Parent d947e1da12597090d71c3d97ec224b7aa5513330
>> dispatch: run "hg --help", "hg --version", and "hg" through runcommand()
>>
>> This fires pre- and post- command hooks and allows pager to work.
>>
>> diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
>> --- a/mercurial/dispatch.py
>> +++ b/mercurial/dispatch.py
>> @@ -645,15 +645,22 @@ def _dispatch(req):
>> for ui_ in uis:
>> ui_.setconfig('web', 'cacerts', '')
>>
>> - if options['version']:
>> - return commands.version_(ui)
>> - if options['help']:
>> - return commands.help_(ui, cmd)
>> - elif not cmd:
>> - return commands.help_(ui, 'shortlist')
>> -
>> repo = None
>> cmdpats = args[:]
>> +
>> + if options['version']:
>> + d = lambda: commands.version_(ui)
>> + return runcommand(lui, repo, 'version', fullargs, ui, options, d,
>> + cmdpats, cmdoptions)
>> + if options['help']:
>> + d = lambda: commands.help_(ui, cmd, **cmdoptions)
>> + return runcommand(lui, repo, 'help', fullargs, ui, options, d,
>> + cmdpats, cmdoptions)
>> + elif not cmd:
>> + d = lambda: commands.help_(ui, 'shortlist', **cmdoptions)
>> + return runcommand(lui, repo, 'help', fullargs, ui, options, d,
>> + cmdpats, cmdoptions)
>
> This is a bit hairy. I went through a few iterations and came up with:
>
> diff -r 9acb5cd19162 -r 803431bdeaea mercurial/dispatch.py
> --- a/mercurial/dispatch.py Thu May 17 15:52:14 2012 -0500
> +++ b/mercurial/dispatch.py Fri May 18 15:56:59 2012 -0500
> @@ -684,11 +684,14 @@
> ui_.setconfig('web', 'cacerts', '')
>
> if options['version']:
> - return commands.version_(ui)
> + cmd, args, cmdoptions = 'version', [], {}
> + func = cmdutil.findcmd(cmd, commands.table, True)[1][0]
> if options['help']:
> - return commands.help_(ui, cmd)
> + cmd, args, cmdoptions = 'help', [cmd], {}
> + func = cmdutil.findcmd(cmd, commands.table, True)[1][0]
> elif not cmd:
> - return commands.help_(ui, 'shortlist')
> + cmd, args, cmdoptions = 'help', ['shortlist'], {}
> + func = cmdutil.findcmd(cmd, commands.table, True)[1][0]
>
> repo = None
> cmdpats = args[:]
>
> But sadly, this only does half the job. We've got five other places in
> dispatch that are calling commands.help_ directly, and those are pretty
> nasty as they're deep in error-handling paths.
>
> So I'm beginning to think we should find a tidier way to handle this
> special case. Perhaps add a gethelp function that all of dispatch uses
> and pager can wrap. But then we have to deal with cases like:
>
> * command was supposed to be paged, but had too few args, help not
> supposed to be paged
> * command had --pager false, too few args, help invoked without access
> to global args
>
> Ugh!
I don't think we need to worry about the other callers. I think the
pager should get invoked when a) you specifically ask for help[1], and
b) when the help output is in its full/long form. I think it's fine
for dispatch to bypass its own machinery when presenting help in
exceptional cases.
[1]: Going by those rules, my patch shouldn't page "hg", but it does
at the moment.
More information about the Mercurial-devel
mailing list