Skip to content

ArgumentResult.OnlyTake(0) doesn't work with a scalar argument followed by an enumerable argument #1759

Closed
@baronfel

Description

@baronfel

If you've got two arguments, one of arity ZeroOrOne and the second of arity ZeroOrMore, the token passed to the first argument isn't returned to the pool (and therefore passed to the second argument) when OnlyTake(0) is used to reject the token passed to the scalar argument.

Sample C# code
using System.CommandLine;
using System.CommandLine.Parsing;

class TestCommand : Command
{
    private static ParseArgument<string> Nope =
            (ctx) =>
            {
                ctx.OnlyTake(0);
                return null;
            };
    public static readonly Argument<string> Scalar = new Argument<string>( parse: Nope);
    public static readonly Argument<string[]> Multiple = new();

    public TestCommand() : base("test", "do the testy") {
        this.Add(Scalar);
        this.Add(Multiple);

        this.SetHandler(ctx => {
            var parseResult = ctx.ParseResult;
            var forward = parseResult.GetValueForArgument(Multiple);
            Console.WriteLine("Forwarded:");
            foreach (var arg in forward ?? Array.Empty<string>()) {
                Console.WriteLine($"\t{arg}");
            }
        });
    }
}

public static partial class Program {
    public static int Main(string[] argv) {
        return new TestCommand().Invoke(argv);
    }
}

If you dotnet run [parse] a b c this code, you get the output [ test [ string <> ] [ string[] <b> <c> ] ]. Note that the a token is lost.
I would expect a b c to be the tokens that the second argument collects.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions