commandline
commandline copied to clipboard
Missing required values on immutable targets causes exception
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.