Buy Me a Coffee

Buy Me a Coffee!

Sunday, January 29, 2017

Using command Line Verbs with the Beta version of the Command Line Parsing Library

A very nice feature of the Command Line Parser Library is the verb option.  It keeps you from having to throw in a bunch of Boolean flags and code flow control.  Verbs allow you (really, force you) to keep your arguments for each action in a separate Options object.  To get to use verbs, you will need to install the beta version from NuGet (or pull the source if you are really adventurous):
Command Line Parser Library Beta NuGet package
Once you do, a whole new world opens up for you.  You can now create verb option objects that isolate specific arguments to those actions.  To create a verb option object, you simply decorate a class with the Verb attribute, passing in the command line keyword and the HelpText.  It really is as simple as that.  Never one to leave well enough alone, I also played around with using a GlobalOptions object that each of the specific verb objects inherits from.  That works as expected, and allows you to consolidate common arguments in a single location.

Without further adieu, here are my three test options objects:


    class GlobalOptions
    {
        [Option('v', "verbose", Default = false,
          HelpText = "Prints all messages to standard output.")]
        public bool Verbose { get; set; }
    }


    [Verb("add", HelpText = "Add files to the site.")]
    class AddOptions : GlobalOptions
    {
        [Option('s', "source", Default = ".",
          HelpText = "The source directory for the files to process.")]
        public string Source { get; set; }
    }


    [Verb("show", HelpText = "Display the contents of a file.")]
    class ShowOptions : GlobalOptions
    {
        [Option('f', "file", Default = ".",
          HelpText = "The file to show.")]
        public string File { get; set; }
    }

And here is the main program:


        static int Main(string[] args)
        {
            return Parser.Default.ParseArguments<AddOptions, ShowOptions>(args)
              .MapResult(
                (AddOptions opts) => RunAddAndReturnExitCode(opts),
                (ShowOptions opts) => RunShowAndReturnExitCode(opts),
                errs => 1);
        }
 
        private static int RunShowAndReturnExitCode(ShowOptions options)
        {
            if (options.Verbose && !string.IsNullOrEmpty(options.File))
            {
                Console.WriteLine("Source File: {0}", options.File);
            }
            Console.WriteLine("displaying file");
            return 0;
        }
 
        private static int RunAddAndReturnExitCode(AddOptions options)
        {
            if (options.Verbose && !string.IsNullOrEmpty(options.Source))
            {
                Console.WriteLine("Source of Files: {0}", options.Source);
            }
            Console.WriteLine("adding files");
            return 0;
        }

And finally, here is the sample output:
C:\blog2>BlogPost.exe
BlogPost 1.0.0.0
Copyright c Microsoft 2017

ERROR(S):
  No verb selected.

  add        Add files to the site.

  show       Display the contents of a file.

  help       Display more information on a specific command.

  version    Display version information.


C:\blog2>BlogPost.exe help add
BlogPost 1.0.0.0
Copyright c Microsoft 2017

  -s, --source     (Default: .) The source directory for the files to process.

  -v, --verbose    (Default: false) Prints all messages to standard output.

  --help           Display this help screen.

  --version        Display version information.


C:\blog2>BlogPost.exe add
adding files

C:\blog2>BlogPost.exe add -v
Source of Files: .
adding files

A truly valuable addition to an already great library.  Next, I will get back to the PnP.Core provisioning series.  See you tomorrow!  Don't forget to unit test!