Command-line-api: add support for global options

Created on 17 Jul 2019  路  11Comments  路  Source: dotnet/command-line-api

Hi,
I wonder if adding a global options by adding it to the RootCommand so it does not matter where in the command line i'll put them The value will be available?

enhancement

Most helpful comment

This can be done now, but it would have to be specified once for each subcommand, e.g. you would have to walk the command tree and add the option to each command. Take a look at #548 for an example.

Maybe an API something like this would simplify things when you want the option to be global?

var root = new RootCommand();
root.AddOptionToAllSubcommands(option);

All 11 comments

This can be done now, but it would have to be specified once for each subcommand, e.g. you would have to walk the command tree and add the option to each command. Take a look at #548 for an example.

Maybe an API something like this would simplify things when you want the option to be global?

var root = new RootCommand();
root.AddOptionToAllSubcommands(option);

Would be nice to have it, I also ran into the same necessity.

Doing something like AddOptionToAllSubcommands requires that the sub-commands are available before the options are added though. Wouldn't it make more sense to allow options to be inherited?

The intention could be captured at the time AddOptionToAllSubcommands is called and then applied when the CommandLineConfiguration is actually created.

Wouldn't it make more sense to allow options to be inherited?

Could you say more about this?

What I mean is that an option could have a flag (Inherited for instance), and any sub-command of a command will inherit all it's inherited options. Example (pseudo - don't have the actual APIs available atm):

var root = new RootCommand();
var repo = new Command("repo");
var updateRepo = new Command("update");

var read = new Command("read");

var source = new Option("--source") { Inherited = true };
source.Argument = new Argument<string>("URI");
repo.Add(source);

// valid: prog.exe repo --source http://test.com
// valid: prog.exe repo update --source http://test.com
// invalid: prog.exe --source http://test.com
// invalid: prog.exe read --source http://test.com

Thanks for the clarification.

If this would be interesting, I can take a shot at implementing it. I think it would be pretty straight forward.

So far, none of the properties of a Command, Option, or Argument (symbols) directly affect the behavior of the others. The relationship between these objects is determined by their hierarchy, and reuse is supported like this:

var optionX = new Option("-x");

var root = new RootCommand
{
    optionX,
    new Command("subcommand1")
    {
        optionX // optionX is valid here
    },
    new Command("subcommand2") // optionX is not valid here
}

This is why I had suggested a method, which could modify the hierarchy (or record an intention to modify it, which is acted on when the Parser instance is built), without modifying the symbols themselves.

You need to store this info somewhere though? To be order agnostic. And sure, if you want to split that up into symbol and metadata that's fine, I would argue it's less ergonomic though.

It would be good though to avoid an API that allows internal inconsistency. For example, what if I would like an option to apply to the root and to some, but not all, subcommands? The current API allows for this, while making this a property of the option itself doesn't.

Sure it does. You just do the same as you've always done. This is not a breaking change.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

anreton picture anreton  路  5Comments

jonsequitur picture jonsequitur  路  6Comments

erichiller picture erichiller  路  3Comments

jonsequitur picture jonsequitur  路  4Comments

ibigbug picture ibigbug  路  3Comments