- Notifications
You must be signed in to change notification settings - Fork 484
Verbs
Verbs help delineate and separate options and values for multiple commands within a single app.
A common usage of verbs in a sample ftp program could be to provide a specific commands: upload, download, delete, etc.
A well known example of using verbs is the git version control system with multiple verbs: add, commit, push, pull, merge, etc.
To use verb commands create an option class for each verb decorated with the [Verb] attribute:
[Verb("add",HelpText="Add file contents to the index.")]classAddOptions{//normal options here}[Verb("commit",HelpText="Record changes to the repository.")]classCommitOptions{//normal options here}[Verb("clone",HelpText="Clone a repository into a new directory.")]classCloneOptions{//normal options here}A this point you have to use a proper ParserArguments<T1, T2...> overload that accepts more than one type (without using the overload with variadic arguments, the library defines versions with up to 16 type parameters):
staticintMain(string[]args){varresult=Parser.Default.ParseArguments<AddOptions,CommitOptions,CloneOptions>(args);}In this case the T Value property of ParserResult<T> will be object but will contain the proper instance if parsing succeeds or NullInstance if fails.
The only change with normal parsing is the requirement to query the Parsed<object>.Value property and invoke the application logic written to handle a specific verb.
A helper extension method is provided to simplify this task:
staticintMain(string[]args){Parser.Default.ParseArguments<AddOptions,CommitOptions,CloneOptions>(args).WithParsed<AddOptions>(options => ...).WithParsed<CommitOptions>(options => ...).WithParsed<CloneOptions>(options => ...).WithNotParsed(errors => ...)}Coherently with ParseArguments<T1, T2, ...>() overloads used for verbs, you can take advantage also of MapResult<T1, T2, ...>(). Like in the sample with a single target instance, here we turn the parsed verb into an exit code:
staticintMain(string[]args)=>Parser.Default.ParseArguments<AddOptions,CommitOptions,CloneOptions>(args).MapResult((AddOptionsoptions)=>RunAddAndReturnExitCode(opts),(CommitOptionsoptions)=>RunCommitAndReturnExitCode(opts),(CloneOptionsoptions)=>RunCloneAndReturnExitCode(opts), errors =>1);Remark
In case of using one verb, you can use `object' as a second verb (dummy verb) as given below:
//use object as a dummy verbParser.Default.ParseArguments<Options,object>(args)At least two verbs are needed.
Using Verbs as Array of Types
You can pass array of verb types to the parser. The overload method ParseArguments has Type as an array Type[]:
publicParserResult<object>ParseArguments(IEnumerable<string>args,paramsType[]types)This overload method is valuable when implementing the verbs as a plugin. You collect the verbs using a plugin loader or Ioc container like Autofac or any DI container.
Example
staticvoidMain(string[]args){//Type[] types ={typeof(AddOptions), typeof(CommitOptions), typeof(CloneOptions) };//or collect types using reflection /plugins /Ioc containervartypes=LoadVerbs();Parser.Default.ParseArguments(args,types).WithParsed(Run).WithNotParsed(HandleErrors);}//load all types using ReflectionprivatestaticType[]LoadVerbs(){returnAssembly.GetExecutingAssembly().GetTypes().Where(t =>t.GetCustomAttribute<VerbAttribute>()!=null).ToArray();}privatestaticvoidRun(objectobj){switch(obj){caseCloneOptionsc://process CloneOptionsbreak;caseCommitOptionso://process CommitOptionsbreak;caseAddOptionsa://process AddOptionsbreak;}}Remark
The generic overload method: ParseArguments(string[] args, Type[] types) support more than 16 verbs.
The overload method ParseArguments<T1,..,T16>(string[] args) support only 16 verbs.
When verb is default, you need not to pass verb name in the command line. Instead of
#copy is verb name $ myapp copy -a xyz --verboseyou can drop the verb name copy as in non-verb option and run:
$ myapp -a xyz --verbose Default verb is configured by setting isDefault =true as:
[Verb("copy",isDefault:true,HelpText="Copy some stuff")]publicclassDefaultVerbOption{[Option('a',"alpha",Required=true)]publicstringOption{get;set;}}Or
[Verb("copy",true,HelpText="Copy some stuff")]publicclassDefaultVerbOption{[Option('a',"alpha",Required=true)]publicstringOption{get;set;}}By default, isDefault =false .
Only one verb can be default, otherwise parser fire an Error Excption.
Remark
Default verb is available in v 2.8+
Example: Display a help screen for all available verbs.
$ app --help #or $ app helpExample: Display the help screen for clone verb.
#the official syntax to call help for a verb: <VerbName> --help $ app clone --helpFor Custom help of verbs, see Custom Help for verbs
