Introduction

This library allows to easily analyze a command line with a syntax similar to getopt. Unlike most other .NET alternatives, like Plossum.CommandLine, gsscoder’s or Ooki.CommandLine, Icm.CommandLine doesn’t use attributes but a fluent interface. This makes it easier (or even possible) to implement localization or plugin schemas in which a 3rd party could add new options to your command line.

Alternatives

There are many attribute-based .NET command line parsers, like Plossum.CommandLine, gsscoder’s, Ooki.CommandLine.

As far as I know, there is only other .NET project that uses a fluent interface, Fluent Command Line Parser. The approach is slightly different: it simplifies the syntax by allowing at most one subargument per parameter. This enables the parser to type the values (since there is only one), and to map them to a class.

Command line syntax

It assumes the following general syntax:

program -namedparam1 subarg1a subarg1b -namedparam2 subarg2a subarg2b [--] unnamedparam1 unnamedparam2

To use it, you must create an instance of CommandLine and follow the next steps:

  • Configure named and unnamed parameters
  • Process a command line with ProcessArguments
  • Check for errors and act accordingly
  • Get obtained values and use them in your app

The following sections analyze those steps.

This is a typical example you can use to get an idea of how can you use the library:

CommandLine cmdline = new CommandLine();

cmdline
    .Required("b", "base", "Base of the logarithm", SubArgument.Required("base"))
    .Optional("e", "exponent", "Exponent of the logarithm", SubArgument.Required("exponent"))
    .Optional("x", "extensions", "Extensions", SubArgument.List("extensions"))
    .MainParametersExactly({ new UnnamedParameter("number", "Number which logarithm is extracted") });

if (cmdline.HasErrors()) {
    ColorConsole.Instructions(cmdline);
    return;
}

int exponent = 0;
int @base = int.Parse(cmdline.GetValue("base"));
if (cmdline.IsPresent("exponent")) {
    exponent = int.Parse(cmdline.GetValue("exponent"));
} else {
    exponent = 1;
}

ICollection<string> extensions = null;
if (cmdline.IsPresent("extensions")) {
    extensions = cmdline.GetValues("extensions");
} else {
    extensions = new List<string>();
}

string operand = cmdline.MainValue;

Configuration

Using fluent syntax you can configure the named parameters and the unnamed parameters.

Named parameters

Each named parameter can be optional or required. For more complex relationships about conditionally required parameters, the developer must do their own work.

To create an optional parameter use Optional and to create a required one use Required.

You must pass the short and long names, a description and the subarguments.

Unnamed (main) parameters

Since the main parameters are not identified by a name, you can only specify lower and upper bounds on the quantity of them. However, to provide a meaningful help text, you must give names and descriptions for the bounded ones (those up to the upper bound if it exists, or the lower in other case) and also, if there is no upper bound, a generic name for the unbounded ones.

The fluid syntax allows you to choose between all possible options, let’s see them in detail:

  • MainParametersOptional [0, +Inf): You must provide a name for argrest.
  • MainParametersBetween [x, y]: You must provide names por arg1, arg2, … argx, …, argy.
  • MainParametersAtLeast [x, +Inf): You must provide names por arg1, arg2, … argx, and argrest.
  • MainParametersAtMost [0, x]: You must provide names por arg1, arg2, … argx.
  • MainParametersRequired [1, +Inf): You must provide names for arg1 and argrest.
  • MainParametersNone [0, 0]: You must not provide names.

NOTE: By default, a CommandLine will feature a --help/-h. There is also a extension method (ColorConsole.Instructions) that prints an autogenerated help text, based on the descriptions used to configure parameters.

Processing

You process the command line with ProcessArguments, which must be passed a String array like the one provided by Environment.GetCommandLineArgs. In fact, calling CommandLine.ProcessArguments without arguments will process the result of Environment.GetCommandLineArgs.

Check errors

CommandLine.ProcessArguments NEVER fails. Instead, it produces a list of errors found.

The property CommandLine.ErrorList will provide that. Usually you will show the errors and stop the application. You can also use the extension method ColorConsole.Instructions to print instructions before exit.

CommandLine only includes validation of:

  • Required named parameters
  • Required subarguments
  • Required main (unnamed) parameters
  • Existence of parameters
  • Proper syntax, including:
    • Double hyphen for long parameter name
    • Single hyphen for short parameter name
    • Optional single hyphen alone for separating the named parameter part from the unnamed arguments.

For any more advanced or specific validations, the client will have to do it herself.

Get values

If no error is found, CommandLine.IsPresent will say if a named parameter is present, CommandLine.GetValue and CommandLine.GetValues will return subarguments of some named parameter, and CommandLine.MainValue and CommandLine.MainValues will return the unnamed parameters.

For a complete example, see Icm.CommandLine.Sample package.