dotnet / command-line-api

Command line parsing, invocation, and rendering of terminal output.
https://github.com/dotnet/command-line-api/wiki
MIT License
3.42k stars 382 forks source link

Having a sub-command with a name that matches its parent crashes the parser #2260

Open calebkiage opened 1 year ago

calebkiage commented 1 year ago
using System.CommandLine;

var rootCommand = new RootCommand();
var cmd = new Command("test");
var cmd2 = new Command("test");

cmd.AddCommand(cmd2);
rootCommand.AddCommand(cmd);

return await rootCommand.InvokeAsync(args);

When trying to build the command structure above, the parser throws the below exception:

Unhandled exception. System.ArgumentException: An item with the same key has already been added. Key: test
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at System.CommandLine.Parsing.StringExtensions.ValidTokens(Command command)
   at System.CommandLine.Parsing.StringExtensions.Tokenize(IReadOnlyList`1 args, CommandLineConfiguration configuration, Boolean inferRootCommand)
   at System.CommandLine.Parsing.Parser.Parse(IReadOnlyList`1 arguments, String rawInput)
   at System.CommandLine.CommandExtensions.GetDefaultInvocationPipeline(Command command, String[] args)
   at System.CommandLine.CommandExtensions.InvokeAsync(Command command, String[] args, IConsole console)
   at Program.<Main>$(String[] args) in ...

System.CommandLine version: 2.0.0-beta4.22272.1

calebkiage commented 1 year ago

An updated version of the app for the new structure also has that same issue:

using System.CommandLine;

var rootCommand = new CliRootCommand();
var cmd = new CliCommand("test");
var cmd2 = new CliCommand("test");

cmd.Add(cmd2);
rootCommand.Add(cmd);

return await new CliConfiguration(rootCommand).InvokeAsync(args);

System.CommandLine version: 2.0.0-beta4.23326.1