natemcmaster / CommandLineUtils

Command line parsing and utilities for .NET

Home Page:https://natemcmaster.github.io/CommandLineUtils/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Exception when defining a property as Argument in a command and also in one of its sub commands

ernstc opened this issue · comments

Describe the bug
Defining a property as Argument in a command and also in one of its sub commands, it generates an exception.

System.Reflection.TargetException : Object does not match target type.

  Stack Trace: 
RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
MethodBase.Invoke(Object obj, Object[] parameters)
<>c__DisplayClass2_0.<GetPropertyGetter>b__0(Object obj)
<>c__DisplayClass1_0.<AddArgument>b__1(ParseResult r)
CommandLineApplication.HandleParseResult(ParseResult parseResult)
CommandLineApplication.HandleParseResult(ParseResult parseResult)
CommandLineApplication.Parse(String[] args)
CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
CommandLineApplication.ExecuteAsync[TApp](CommandLineContext context, CancellationToken cancellationToken)
CommandLineApplication.Execute[TApp](CommandLineContext context)
CommandLineApplication.Execute[TApp](IConsole console, String[] args)
CommandLineApplication.Execute[TApp](String[] args)

To Reproduce
Steps to reproduce the behavior:

  1. Using the version '4.0.1' of the library
  2. Sample code
using McMaster.Extensions.CommandLineUtils;

[Command("console-app")]
[Subcommand(typeof(ConfigureCommand))]
public class Program
{
    static void Main(string[] args) => CommandLineApplication.Execute<Program>(args);
    public int OnExecute() => 1;
}

[Command]
[Subcommand(typeof(ListCommand))]
public class ConfigureCommand
{
    [Argument(0)]
    public string? ArgumentProperty { get; set; }
    public int OnExecute() { Console.WriteLine($"configure: {ArgumentProperty}"); return 0; }
}

[Command]
public class ListCommand
{
    [Argument(0)]
    public string? ArgumentProperty { get; set; }
    public int OnExecute() { Console.WriteLine($"list: {ArgumentProperty}"); return 0; }
}
  1. Run the console application with the arguments configure list any-value

Additional context
There is a work around for this bug, but only if it's possible to define a base class that contains the argument property for both commands: configure and list.

public class CommandWithArgument
{
    [Argument(0)]
    public string? ArgumentProperty { get; set; }
}

[Command]
[Subcommand(typeof(ListCommand))]
public class ConfigureCommand : CommandWithArgument
{
    public int OnExecute() { Console.WriteLine($"configure: {ArgumentProperty}"); return 0; }
}

[Command]
public class ListCommand : CommandWithArgument
{
    public int OnExecute() { Console.WriteLine($"list: {ArgumentProperty}"); return 0; }
}