JC.CommandLine
3.0.0
dotnet add package JC.CommandLine --version 3.0.0
NuGet\Install-Package JC.CommandLine -Version 3.0.0
<PackageReference Include="JC.CommandLine" Version="3.0.0" />
<PackageVersion Include="JC.CommandLine" Version="3.0.0" />
<PackageReference Include="JC.CommandLine" />
paket add JC.CommandLine --version 3.0.0
#r "nuget: JC.CommandLine, 3.0.0"
#:package JC.CommandLine@3.0.0
#addin nuget:?package=JC.CommandLine&version=3.0.0
#tool nuget:?package=JC.CommandLine&version=3.0.0
John Cronan's Command Line Parser
This project is a flexible, feature-rich, well-tested command line parser implemented in 100% managed C#.
Philosophy
The parser is not attribute-based. Instead, command-line arguments and switches are defined and parsing options set via a builder (CommandLineParserBuilder), which is oriented toward simple, judicious use of method-chaining. Fully "fluent" syntax is specifically avoided.
Over-validation is specifically avoided. Consumers, it is assumed, will necessarily perform validation of their own anyway, so it doesn't make sense to write a lot of code to implement validation features that are very easy to do in consuming code.
Parsing and validation errors result in exceptions. It is the consumer's responsibility to handle them appropriately, e.g. displaying command usage text and potentially exiting prematurely. Parse warnings are exposed through the result returned by the Parse method, or by object binding (see below).
Usage
The package can be consumed one of three ways: By calling properties and methods of the ICommandLineParseResults instance returned from ICommandLineParser's Parse method; by property binding; or by constructor binding. Although property binding, being the expected most-common usage, is the default object binding, constructor binding is actually the recommended usage, as a command line is naturally immutable anyway.
Usage is simple: Create an instance of CommandLineParserBuilder, call its methods to set parse options and define arguments and switches, invoke the CreateParser method and, in turn, invoke Parse. Parse returns and instance of ICommandLineParseResults, which can then be used to Bind parse results to a newly-created object.
The object binders can bind (case insensitively) to arguments and properrties of most commonly used value types. Command line arguments with multiple values can be bound to a wide variety of collection types, including array, IEnumerable<T>, List<T>, IList<T>, ImmutableArray<T>, as well as their corresponding non-generic types.
Unnamed values are bound to arguments with the names "unnamedValues", "leadingUnnamedValues", and "trailingUnnamedValues". Parse warning are bound to a property named "parseWarnings".
The following command line:
Program.exe Import /Files authors.csv titles.csv publishers.csv /Batch-Size 1000 /S (local) /D Books /Verbose
May be defined and parsed by the following code:
var args =
new CommandLineParserBuilder()
.UseConstructorBinding()
.AddArgument("Files", ArgumentMultiplicity.OneOrMore, true)
.AddArgument("Batch-Size", ArgumentMultiplicity.One, false)
.AddArgument("Server", ArgumentMultiplicity.One, false)
.AddArgument("Database", ArgumentMultiplicity.One, true)
.AddSwitch("Verbose")
.CreateParser()
.Parse()
.Bind<CommandLine>();
And bound to a class with the following constructor:
internal class CommandLine
{
public CommandLine(ImmutableArray<string> leadingUnnamedValues,
ImmutableArray<string> files, int? batchSize, string server,
string database, bool verbose)
{
}
}
Or, if using property binding (with the UsePropertyBinding method):
internal class CommandLine
{
public ImmutableArray<string> LeadingUnnamedValues { get; set; }
public ImmutableArray<string> Files { get; set; }
public int? BatchSize { get; set; }
public string Server { get; set; }
public string Database { get; set; }
public bool Verbose { get; set; }
}
See the integration tests in the test folder at https://github.com/john-cronan/main for additional examples of usage.
Future Directions
Testing. The project could use more organized, thorough testing.
Binding errors and warnings. Currently, exceptions occurring during object binding are not handled ideally, especially type conversion errors. Revisions to allow the binders to contribute errors and warnings to the parsing/binding process would be beneficial.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- System.Collections.Immutable (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
3.0.0 - Improved support for complex command lines, where a single utility handles multiple
commands (a la the dotnet and azure CLIs), including a CommandDispatcher.
2.0.0 - Addition of "help switches". The presence of a defined help switch on a command line
weakens ordinary validation (parse errors surface as warnings instead), so that a command
line that doesn't really need to be valid anyway (help is being requested) can be parsed.