Fix #2226 - #2249
Conversation
| var availableHelpOptions = | ||
| parseResult | ||
| .CommandResult | ||
| .Command | ||
| .RecurseWhileNotNull(c => c.Parents.OfType<CliCommand>().FirstOrDefault()) | ||
| .Select(c => c.Options.OfType<HelpOption>().FirstOrDefault()); |
There was a problem hiding this comment.
I feel this recursion should be on CommandResult.Parent rather than CliCommand.Parents. So that if the same CliCommand is reachable as app subcommand1 leafcommand and app subcommand2 leafcommand, then it picks up a HelpOption from either subcommand1 or subcommand2, depending on how the user ran the command.
There was a problem hiding this comment.
I mean something like this, but I did not try compiling:
var availableHelpOptions =
parseResult
.CommandResult
.RecurseWhileNotNull(r => r.Parent as CommandResult)
.Select(r => r.Command.Options.OfType<HelpOption>().FirstOrDefault());There was a problem hiding this comment.
That works. Thanks for the suggestion!
There was a problem hiding this comment.
On second thought, this does not work: if some of the commands in the result hierarchy do not have a HelpOption, then the availableHelpOptions sequence will have null references in the corresponding positions; and if the first item is null (because the leaf command does not have its own HelpOption) then the subsequent availableHelpOptions.FirstOrDefault() call will return that null and ignore any HelpOption references later on in the sequence. So you need something to filter the nulls out too.
There was a problem hiding this comment.
Thanks. I added a test and fixed this in the latest commit.
| private static void WriteHelp(ParseResult parseResult) | ||
| { | ||
| new HelpAction().Invoke(parseResult); | ||
| var availableHelpOptions = |
There was a problem hiding this comment.
I have fixed this bug once: #2211, how is it possible that it's back? Some merge issue?
Since ParseResult exposes RootCommandResult and RootCommand should be the only command having it, we can simplify it to:
HelpOption helpOption = parseResult.RootCommandResult.Command.Options.FirstOrDefault(option => option is HelpOption) as HelpOption ?? new HelpOption();There was a problem hiding this comment.
I'm not sure RootCommand should be the only one with a HelpOption. Isn't it possible for a subcommand to shadow the parent's HelpOption with one that has a different syntax (e.g. supporting --help=online) or different behaviour (e.g. formatting the help from some markup language in resources, rather than from the children of the CliCommand)?
There was a problem hiding this comment.
Since ParseResult exposes RootCommandResult and RootCommand should be the only command having it...
This isn't the case. Different help options can be defined at different levels of the hierarchy.
|
I've also removed the direct usage of a new |
This fixes #2226.