commandline icon indicating copy to clipboard operation
commandline copied to clipboard

Invalid verbs do not cause errors if a default verb is set

Open JimSuplizio opened this issue 3 years ago • 1 comments

Below is a very simplified C# console application I called DefaultVerb. Running the application with start or finish works as expected, outputting Start or Finish correctly, but if I run the application with DefaultVerb.exe foo, it outputs Start. If I set isDefault to false, and run DefaultVerb.exe foo I receive the following expected error: ERROR(S): Verb 'foo' is not recognized. --help Display this help screen. --version Display version information. When I have isDefault: true on my verb, what should be the behavior if I pass in an invalid verb? I'm not expecting a bad verb to run my default verb.

` using CommandLine; using System;

internal class Program { [Verb("start", isDefault: true, HelpText = "start help")] class StartOptions { }

[Verb("finish", HelpText = "finish help")]
class FinishOptions
{
}

static void Main(string[] args)
{
    var parser = new Parser(settings =>
    {
        settings.AutoVersion = false;
        settings.CaseSensitive = false;
        settings.HelpWriter = Console.Out;
    });

    parser.ParseArguments<StartOptions, FinishOptions>(args)
        .WithNotParsed(ExitWithError)
        .WithParsed(DoSomething);
}

static void DoSomething(object commandObj)
{
    switch (commandObj)
    {
        case StartOptions:
            Console.WriteLine("Start");
            break;
        case FinishOptions:
            Console.WriteLine("Finish");
            break;
    }
}
static void ExitWithError(IEnumerable<Error> errors)
{
    Environment.Exit(1);
}

} `

JimSuplizio avatar Sep 23 '22 21:09 JimSuplizio

This looks like it's related to #847 "unused positional argument / value".

An unmapped positional argument with value foo is being passed to the default verb start, even though start doesn't define any positional arguments.

If you add a positional argument to StartOptions you'll see the value foo being passed:

[Verb("start", isDefault: true, HelpText = "start help")]
class StartOptions
{
	[Value(0)]
	public string Positional { get; set; }
}

...

static void DoSomething(object commandObj)
{
    switch (commandObj)
    {
        case StartOptions startOptions:
            Console.WriteLine($"Start: {startOptions.Positional}");
            break;
        case FinishOptions:
            Console.WriteLine("Finish");
            break;
    }
}

DefaultVerb.exe foo --> Start: foo

hallipr avatar Feb 23 '23 21:02 hallipr