dotnet / dotnet/command-line-api
Tokenizing of the Options adds other options as arguments
- Dominant language
- C#
- Stars
- 3.7k
- Forks
- 428
- PR merge metrics
- No merged PRs in 30d
Description
Seems that if you miss the Argument for an Option, then command-line-api with parse the next Option as the Argument. This doesn't seem to me like expected behaviour. If this is expected behaviour, is there a way to alter the parser, or plugin parser behaviour?
I have the following code:
```
static async Task Main(string[] args)
{
var fileOption = new Option("--file", "file to load") {Arity = new ArgumentArity(1, 1)};
var sourceUrlOption = new Option("--source", "source url") { Arity = new ArgumentArity(1, 1) };
var load = new Command("load") { fileOption, sourceUrlOption };
load.Handler = CommandHandler.Create(DoSomethingAsync);
var rootCommand = new RootCommand {load};
await rootCommand.InvokeAsync(args);
}
static async Task DoSomethingAsync(string file, string source)
{
Console.WriteLine($"{file} {source}");
await Task.Delay(100);
}
```
When called using the following:
```
$ dotnet my-commandline load --file --source
```
I would expect the following error output from command-line-api:
```
Required argument missing for option: '--file'.
Required argument missing for option: '--source'.
...
```
However, the application runs and Invokes the DoSomething Async method with the file variable being set to the string '--source'. Outputing:
```
--source
```
It seems that the issue is in [StringExtensions.cs](https://github.com/dotnet/command-line-api/blob/main/src/System.CommandLine/Parsing/StringExtensions.cs) in the Tokenize method at line 131. It adds the next Option as an Argument to the previous Option. I would have thought that the expected behavour would be to add an Option. Which would then result in both the Options being added to the tokenList object.
Contributor guide
Assessment
This issue has not been assessed yet.