command-line-api: Can't combine arguments with array option
Consider the following code:
var rootCommand = new RootCommand
{
new Option<string[]?>("--config")
{
IsRequired = false,
},
new Argument<string>("source"),
new Argument<string>("dest"),
};
rootCommand.Handler = CommandHandler.Create<string, string, string[]?>((source, dest, config) =>
{
Console.WriteLine($"The value for 'source' is: {source}");
Console.WriteLine($"The value for 'dest' is: {dest}");
Console.WriteLine($"The number of config params is: {config?.Length ?? 0}");
});
rootCommand.Invoke(new[] { "--config", "abc", "--config", "def", "/src", "/dest" });
Running this code gives you:
Required argument missing for command: CommandLineReproducer
Required argument missing for command: CommandLineReproducer
Usage:
CommandLineReproducer [options] <source> <dest>
Arguments:
<source>
<dest>
Options:
--config <config>
--version Show version information
-?, -h, --help Show help and usage information
In my opinion, this should work.
What will work is if the --config options are put to the end, like so:
rootCommand.Invoke(new[] { "/src", "/dest", "--config", "abc", "--config", "def" });
However, I think, both calls should behave identical (especially since the error message in the first call - “Required argument missing for command: CommandLineReproducer” - is totally confusing).
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 1
- Comments: 15 (7 by maintainers)
This is configurable using
Option.AllowMultipleArgumentsPerToken. (The property name here could probably be made clearer. Suggestions welcome.)The default for this setting is to allow
--config abc defto parse as an array for option--config. Seeing this example makes me think we should swap the default for this property. The behavior does exist in some command line apps, and the configurability is intended to allow System.CommandLine to handle idiosyncratic legacy syntaxes. In this way it’s not strictly POSIX but more of a superset intended to accommodate both POSIX and Windows-style syntax.There’s a related issue that needs to be addressed to bring the single-arity behavior into line with POSIX expectations: #1083.
Also related: #669.
I disagree. It may be that you are technically correct but for an end user of the CLI the current behavior is totally confusing.
If you look at existing CLIs it’s customary to specify options before arguments:
I’m not that deep in how the
System.CommandLineparser works but if you’re right and--config abc --config defis the same as--config abc defthan this would always prevent array options before arguments - which is an issue/problem in my opinion.Maybe this behavior could be made configurable?
And are there examples for CLIs that use the
--config abc defform? If not, this form could be dropped entirely.