Command Line Parser
Motivation
Every now and then, we write a little console application to quickly get a job done. But the parsing of the arguments is always a pain. We don't invest any precious time into good exception behaviour because we just want it to do a simple job. Of course, this results in a mess after some time. Therefore, we built this little command line parser to make parsing command line arguments a simple and quick task.
Features
- fluent definition syntax using lambdas
- named, positional and switch arguments
- required and optional arguments
- value restrictions
- alias
- type conversion
- semi-automatic composition of a usage help message
Sample
Why yet another command line parser?
We needed a command line parser for Appccelerate.Version. We used the approach describe in this blog post by Daniel. And none of the existing .Net command line parser libraries met our requirements. Either the license was too restrictive, the code was of bad quality, the project was abandoned or we didn't like the API of the library. Therefore, Urs took the time to build our own little command line parser with focus on easy usage and high quality.
Conventions
The command line parser uses the following conventions:
-
is used for named and switch arguments--
is used for long alias
Argument Types
Appccelerate.CommandLineParser knows three types of arguments.
Named Arguments
A named argument is an argument identified by a name and having an associated value, like foo.exe -name value
.
A named argument is specified using WithNamed
:
You have to specify the name (without -
) and the callback that is called with the value when this argument is found.
Optionally, you can specify:
HavingLongAlias
specifies a long alias (e.g. --output).Required
specifies that the argument is required. If left out, the argument is optional.RestrictedTo
specifies allowed values - all other values result in a parsing error. If left out, all values are allowed.DescribedBy
specifies the help text by naming a place holder for the value and a description. If left out, "value" is used for the place holder and the description is empty.
Positional Arguments
A positional argument is an argument identified by its position (first positional, second positional, ...), like foo.exe first second third
.
A positional argument is specified using WithPositional
. The position is specified by the order of declaration:
You have to specify the callback that is called with the value when this argument is found.
Optionally, you can specify:
Required
specifies that the argument is required. If left out, the argument is optional.DescribedBy
specifies the help text by naming a place holder for the value and providing a description. If left out, "value" is used for the place holder and the description is empty.
Switch Arguments
A switch argument is an argument identified by its name, like foo.exe -first -second -third
.
A switch is always optional.
A switch argument is specified using WithSwitch
:
You have to specify the callback that is called when this argument is found.
Optionally, you can specify:
HavingLongAlias
specifies a long alias (e.g. --debug).DescribedBy
specifies the help text. If left out, the description is empty.
Setup Configuration
You can use the CommandLineParserConfigurator
to specify the known arguments:
The configuration can then be used to create a parser and to create the usage message.
Parse Command Line Arguments
You can create a command line parser using a command line configuration, and parse the command line arguments:
The ParseResult
that is returned contains a flag whether parsing was successful (parseResult.Succeeded
)
and in the case of an error the error reason (parseResult.Message
).
Compose Usage
You can use the UsageComposer
to create the usage help message.
The returned Usage
contains the call syntax (usage.Arguments
) and the options (usage.Options
):
Arguments sample: -required <value> [-optional <value>] [-switch] <positional>
.
[ ]
denote optional arguments< >
denote placeholders
Options sample:
The options show the name (if any), the alias (if any), the value place holder (if any), the allowed values (if specified) and the description.
You can write this information to the console:
The IndentBy
method can be used to indent lines of strings.
Type Conversion
If you have command line arguments that are basic types besides strings, you can use type conversion:
For named arguments: .WithNamed("t", (int v) => threshold = v)
.
For positional arguments: .WithPositional((bool b) => flag = b)
.
Only type conversions supported by Convert.ChangeType
are supported.
Current limitations
- only
-
/--
are supported to identify names/alias - no support for help argument, e.g.
-?
or-help
- no support for commands, e.g.
foo.exe do -name value
Road Map
- nicer usage output
- improved type conversion