Skip to content

Latest commit

 

History

History
177 lines (118 loc) · 6.51 KB

index.md

File metadata and controls

177 lines (118 loc) · 6.51 KB

General {#mainpage}

[TOC]

🌊🦈 CShargs argument parser

(Hopefully) easy to use declarative argument parser for C#.

We strive to create an argument parser with an easy set up. We want for definition of parser to take only a page of code and be close to just defining a class. We also want to avoid having a secondary API for retrieval of parsed data. To achieve this we needed to connect the definitions of options with with their retrieval and usage. We decided to let the user define how they will be fetching and using the parsed data by creating their own parser class with class fields representing data. So to use the parsed data user just needs to access a certain field in their parser class.

To connect parser with option definitions and parser configuration, annotations with Attributes are used. Our library processes the annotations on initialization, then creates an inner data structure to represent the user defined parser. During argument parsing it uses this data structure to interpret incoming tokens as user defined options. Results of parsing are then saved into the fields of the parser class where user can access them.


Getting started

To use automatic argument parsing, define a class representing the parsed arguments. 🌊🦈 will populate this object with data from the command line.

  • Create a class that represents arguments of your command (must be child of CShargs.Parser class)
  • Properties or methods in the class correspond to command options. Annotate them with attributes to specify kinds of options.
  • Parameters of an option are specified in attribute constructor.
  • To parse arguments, create an instance of this object and call the CShargs.Parser.Parse() function, passing command line arguments to it.
class MyCommandArguments : CShargs.Parser {
    // ... options go here
}

static void Main(string[] argv) {
    var arguments = new MyCommandArguments();
    arguments.Parse(argv);
}
  • Parsed options and their parameters will be filled in the fields of the class instance.
  • Plain arguments can be found in PlainArgs property as a list of strings.

Error handling

When parsing fails, appropriate CShargs.ParsingException is thrown. It contains autogenerated error message. See \ref ParsingExceptions for details. If you implement custom option/type, you can throw FormatException or OverflowException to signal to the parser that the parsing has failed. Similarly, you can call standard parsing methods, ie int.Parse, Convert.To..., because they throw these exceptions on parsing failure.

If your parser configuration contains a conflict, CShargs.ConfigurationException is thrown at parser initialisation time.

Features

See lists of:

  • \ref OptionAttributes "all option types"
  • \ref ParsingExceptions "all exceptions thrown during parsing"

Flag option ( --flag / -f )

See CShargs.FlagOptionAttribute

Flag option attribute is used for options without parameters. The type of the property must be bool.

\dontinclude TimeExample.cs \skip "verbose" \until }

For full example see \ref TimeExample.cs

Value option ( --key=Value / -k Value / -kValue )

See CShargs.ValueOptionAttribute

Value option attribute is used for options with parameters. Type of the option property must be either:

  • one of the C# primitives (int, string, bool, short, long, etc.)
  • an enum. Entries are case sensitive, if LongCaseInsensitive setting is not set.
  • any user defined type T, which provides static method T Parse(string str);

\dontinclude TimeExample.cs \skipline format \skipline *

\skip "format" \until }

Verb option ( git push )

See CShargs.VerbOptionAttribute

Verb option attribute is used for subcommands. In this case, type of the option property must be a child of the CShargs.Parser class.

\dontinclude GitExample.cs \skip "push" \until }

Custom option

See CShargs.CustomOptionAttribute

If you need an option that needs some context during its own parsing, or you need to interpret the raw arguments in slightly different way, you can use the CustomOption attribute on a method. The signature of the method should be void MyMethod(string value).

If the custom parameter has a value attached to it (like this: --param=value), it is given via the string value parameter of the method. Otherwise the parameter is null.

\dontinclude CustomExample.cs \skip // \until } \until }

Settings

See CShargs.ParserConfigAttribute

You can change the default parser configuration by annotating your parser class with parser config attribute.

In default configuration parsing is case sensitive and all syntax variants for writing options are allowed.

  • aggregating short options ie. -abc / -a -b -c
  • syntax of option parameters ie. -c 123 / -c123 / -c=123

Use CShargs.OptionFlags to forbid unwanted syntax variants.

Alias options

Each option allows you to define one mandatory name and one optional short alias.

In addition to that you can set more aliases using CShargs.AliasOptionAttribute, like this:

[AliasOption("R", nameof(Recursive))]
[AliasOption("a", nameof(Recursive), nameof(Force))]
class MyArguments : Parser {
    [FlagOption("recursive", shortName: 'r')]
    bool Recursive { get; set; }

    [FlagOption("force", shortName: 'f')]
    bool Force { get; set; }

    // option -a is now equivalent to -rf and -Rf
}

You have to use property names of the aliased options. If you wont use them, you will get an exception on parser initialization. Keep in mind, that the parser class can be annotated with multiple CShargs.AliasOptionAttribute attributes. Also, you can create one alias for multiple flag options.

Option groups

See CShargs.OptionGroupAttribute

If you want to force the user to select one of a list of options, use the group option attribute. Again, use property names to reference other options. The group must not contain any required options or any option dependencies, otherwise CShargs.ConfigurationException is thrown on initialization.

\dontinclude GroupExample.cs \skip OptionGroup \until // \until }

Option dependencies

You can specify that some options are available only when other options are present. Use the useWith argument in your option attribute which takes the option property name.

class MyArguments : Parser {

    [FlagOption("print", shortName: 'p', help: "Print out progress")]
    bool Print { get; set; }

    [FlagOption("verbose", shortName: 'v', help: "Print more details", useWith: nameof(Print))]
    bool Verbose { get; set; }

    // if -v is used without -p parameter, an exception is thrown
}