commandline icon indicating copy to clipboard operation
commandline copied to clipboard

Missing required values on immutable targets causes exception

Open altearius opened this issue 8 years ago • 0 comments

I am using CommandLineParser 2.1.1-beta.

Suppose you have two immutable options classes, one of which defines some required values:

[Verb("create", HelpText = "Create a new migration.")]
public class CreateMigrationOptions
{
	public CreateMigrationOptions(string name)
	{
		Name = name;
	}

	[Value(0, HelpText = "The optional name of the migration to create.")]
	public string Name { get; }
}

[Verb("add", HelpText = "Add a new script to a migration.")]
public class AddScriptOptions
{
	public AddScriptOptions(string migration, string script)
	{
		Migration = migration;
		Script = script;
	}

	[Value(0, Required = true, HelpText = "The name of the migration to modify.")]
	public string Migration { get; }

	[Value(1, Required = true, HelpText = "The name of the script to add.")]
	public string Script { get; }
}

When parsing command line arguments that invoke the second verb, but without the required options, a ParameterCountMismatch exception is thrown:

var parsed = Parser.Default
	.ParseArguments<
		CreateMigrationOptions,
		AddScriptOptions>(new[] { "add" });

Here is the stack trace:

System.Reflection.TargetParameterCountException: Parameter count mismatch.
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at CommandLine.Core.InstanceBuilder.<>c__DisplayClass0_2`1.<Build>b__23()
   at CommandLine.Core.InstanceBuilder.<>c__DisplayClass0_0`1.<Build>b__7()
   at CommandLine.Core.InstanceBuilder.Build[T](Maybe`1 factory, Func`3 tokenizer, IEnumerable`1 arguments, StringComparer nameComparer, Boolean ignoreValueCase, CultureInfo parsingCulture, IEnumerable`1 nonFatalErrors)
   at CommandLine.Core.InstanceChooser.MatchVerb(Func`3 tokenizer, IEnumerable`1 verbs, IEnumerable`1 arguments, StringComparer nameComparer, CultureInfo parsingCulture, IEnumerable`1 nonFatalErrors)
   at CommandLine.Core.InstanceChooser.<>c__DisplayClass0_0.<Choose>b__0()
   at CommandLine.Core.InstanceChooser.Choose(Func`3 tokenizer, IEnumerable`1 types, IEnumerable`1 arguments, StringComparer nameComparer, CultureInfo parsingCulture, IEnumerable`1 nonFatalErrors)
   at CommandLine.Parser.ParseArguments(IEnumerable`1 args, Type[] types)
   at CommandLine.ParserExtensions.ParseArguments[T1,T2,T3,T4,T5,T6,T7](Parser parser, IEnumerable`1 args)
   at Snorri.Program.ExecuteCommands(IResolutionRoot kernel, IEnumerable`1 args) in e:\Users\niels\Documents\Visual Studio 2015\Projects\Snorri\src\Snorri\Program.cs:line 78
   at Snorri.Program.<>c__DisplayClass1_0.<Main>b__0(IKernel kernel) in e:\Users\niels\Documents\Visual Studio 2015\Projects\Snorri\src\Snorri\Program.cs:line 28
   at Snorri.Program.WithDependencies(Action`1 executeCommands) in e:\Users\niels\Documents\Visual Studio 2015\Projects\Snorri\src\Snorri\Program.cs:line 127
   at Snorri.Program.Main(String[] args) in e:\Users\niels\Documents\Visual Studio 2015\Projects\Snorri\src\Snorri\Program.cs:line 28

If you change the AddScriptOptions to no longer be immutable, or if you remove the CreateMigrationOptions class from the call to ParseArguments, then there is no exception thrown, and the parsed.Errors enumerable is populated (correctly noting that a required value was missing).

Thus, throwing an exception in this case feels like it may be a bug.

altearius avatar Mar 02 '17 13:03 altearius