Skip to content
vdasusPublic

About

Getopt::Long-style command-line option parser for .NET. Maintained fork of Mono.Options / NDesk.Options.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Optionus

A small, dependency-free command-line option parser for .NET, in the style of Perl's Getopt::Long.

Optionus is a maintained fork of Mono.Options, which itself grew out of NDesk.Options. Both upstream projects are no longer actively maintained. Optionus keeps the API and behaviour, targets current .NET, and fixes a few long-standing issues.

Authors and credits

Optionus is based on the work of the original authors:

  • Jonathan Pryor: original author of NDesk.Options and Mono.Options
  • Federico Di Gregorio: contributor
  • Rolf Bjarne Kvinge: contributor (Xamarin)
  • Novell, Xamarin Inc and Microsoft Corporation: copyright holders of the upstream code

Fork maintained by vdasus.

Features

  • Single source file, no dependencies
  • Option prototypes: "v|verbose", "n|name=" (required value), "l|level:" (optional value)
  • Short, long and Windows-style prefixes: -v, --verbose, /verbose
  • Values as -n=foo, -n:foo, -n foo
  • Bundling: -abc is the same as -a -b -c; -Dname=value
  • Boolean switches: -x+ / -x-
  • Typed values through TypeConverter: int, enum, Nullable<T>, custom types
  • Key/value options: -Dkey=value
  • -- stops option processing
  • Response files: @args.txt
  • Generated help text: WriteOptionDescriptions
  • Git-style sub-commands with CommandSet and Command

Target frameworks

  • netstandard2.0 (.NET Framework 4.6.1+, .NET Core 2.0+, Mono)
  • net10.0

Installation

dotnet add package Optionus

Quick start

using Optionus;

bool showHelp = false;
int verbosity = 0;
string? output = null;
var names = new List<string>();

var options = new OptionSet {
    "Usage: greet [OPTIONS]+ NAME...",
    "",
    "Options:",
    { "n|name=", "the {NAME} to greet", v => names.Add(v) },
    { "o|output=", "write to {FILE}", v => output = v },
    { "v", "increase verbosity", v => { if (v != null) ++verbosity; } },
    { "h|help", "show this message and exit", v => showHelp = v != null },
};

List<string> extra;
try {
    extra = options.Parse(args);
}
catch (OptionException e) {
    Console.Error.WriteLine($"greet: {e.Message}");
    Console.Error.WriteLine("Try `greet --help' for more information.");
    return 1;
}

if (showHelp) {
    options.WriteOptionDescriptions(Console.Out);
    return 0;
}

Parse returns the arguments it did not consume.

Sub-commands

var suite = new CommandSet("tool") {
    "usage: tool COMMAND [OPTIONS]+",
    new Command("build", "Build the project") {
        Options = new OptionSet { { "c|configuration=", v => configuration = v } },
        Run = args => Build(args),
    },
};
return suite.Run(args);

tool help and tool help build are provided automatically.

Migrating from NDesk.Options or Mono.Options

Replace the package reference and the namespace:

- using NDesk.Options;
- using Mono.Options;
+ using Optionus;

The public API is otherwise unchanged.

Changes compared to Mono.Options

  • Namespace Optionus; SDK-style project for netstandard2.0 and net10.0
  • Breaking: typed values (int, double, DateTime, …) are converted with the invariant culture, so -r=1.5 means 1.5 on every machine. Mono.Options used the current culture, where 1.5 fails on a machine with a decimal comma (lt-LT, de-DE, …)
  • Response files are closed when parsing fails part-way; previously the file handle stayed open until garbage collection
  • ArgumentSource.GetArgumentsFromFile opens the file on first enumeration, so an enumerable that is never enumerated does not leak a handle
  • A response file that includes itself, directly or indirectly, raises OptionException instead of recursing until resources run out (nesting limit: 64)
  • CommandSet.GetCompletions handles a prefix with leading whitespace correctly
  • The "Found {0} option values" error message is now passed to the message localizer before formatting, consistent with the other messages
  • Binary serialization members of OptionException are only compiled for netstandard2.0 (formatter-based serialization is obsolete on .NET 8+)
  • Tests ported from NUnit to xUnit v3

Building and testing

dotnet build
dotnet test

Requires the .NET 10 SDK.

License

MIT. See LICENSE. The original copyright notices are kept in the source file and in the license.

About

Getopt::Long-style command-line option parser for .NET. Maintained fork of Mono.Options / NDesk.Options.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages