Display A Help Screen

Mapping a method with HelpOptionAttribute will allow the parser to display a help screen when parsing rule are violated.

class Options
{
  [Option("p", "person-to-greet", Required=true, HelpText="The person to greet.")]
  public string PersonToGreet { get; set; }
  [HelpOption]
  public string GetUsage()
  {
    return "Please read user manual!" + Environment.NewLine;
  }
}

In this sample the -p|--person-to-great option is mandatory. Omitting it will cause the parser to display the string returned byOptions::GetUsage().

When mapping a method with HelpOption the are only few constraint to respect. The method must be an instance method, it have to return a string and accept no parameters. The name can be the one that you prefer.

Using Help Text Class

The CommandLine.Text namespace contains helper types to make easy the render of the help screen.

class Options
{
  [Option("p", "person-to-greet", Required=true, HelpText="The person to greet.")]
  public string PersonToGreet { get; set; }
  [HelpOption]
  public string GetUsage()
  {
    var help = new HelpText {
      Heading = new HeadingInfo("<>", "<>"),
        Copyright = new CopyrightInfo("<>", 2012),
        AdditionalNewLineAfterOption = true,
        AddDashesToOption = true };
    help.AddPreOptionsLine("<>");
    help.AddPreOptionsLine("Usage: app -pSomeone");
    help.AddOptions(this);
    return help;
  }
}

In this example the method creates an HelpText instance, it uses secondary helper types to specify heading and copyright informations and sets some preferences.

Then it simply add text as a StringBuilder and with a single call (AddOptions) renders the options block. Every option attribute (exceptValueList) inherits from BaseOptionAttribute and this type has a property named HelpText. And precisely the value of this property is used byAddOptions method.

Handling Parsing Errors

Parsing errors like badly formatted values or missing required options can be captured as generic list of ParsingError type. Access this data requires that your target class inherits from the abstract CommandLineOptionsBase.

class Options : CommandLineOptionsBase
{
}

This will let you access the protected member LastPostParsingState defined as PostParsingState. It follows complete object model.

public sealed class PostParsingState
{
  public List Errors { get; }
}

public class ParsingError
{
  public BadOptionInfo BadOption { get; }
  public bool ViolatesRequired { get; }
  public bool ViolatesFormat { get; }
  public bool ViolatesMutualExclusiveness { get; }
}

public sealed class BadOptionInfo
{
  public string ShortName { get; }
  public string LongName { get; }
}

The following snippet of code demonstrates how to report errors using HelpText::RenderParsingErrorsText for render the text block automatically:

class Options : CommandLineOptionsBase
{
  [HelpOption]
  public string GetUsage()
  {
    var help = new HelpText();
    // ...
    if (this.LastPostParsingState.Errors.Count > 0)
    {
      var errors = help.RenderParsingErrorsText(this, 2); // indent with two spaces
      if (!string.IsNullOrEmpty(errors))
      {
        help.AddPreOptionsLine(string.Concat(Environment.NewLine, "ERROR(S):"));
        help.AddPreOptionsLine(errors);
      }
    }
    // ...
    return help;
  }
}

Automatic Building

Taking advantage of assembly attributes and recently added helpers you can build HelpText instance with one line of code.

As first thing define attributes (usually in Properties/AssemblyInfo.cs):

// from .NET class library
[assembly: AssemblyTitle("yourapp")]
[assembly: AssemblyCopyright("Copyright (C) 2012 Your Name")
[assembly: AssemblyInformationalVersionAttribute("1.0")]

// from CommandLineParser.Text
[assembly: AssemblyLicense(
  "This is free software. You may redistribute copies of it under the terms of",
  "the MIT License <http://www.opensource.org/licenses/mit-license.php>.")]
[assembly: AssemblyUsage(
  "Usage: YourApp -rMyData.in -wMyData.out --calculate",
  "           YourApp -rMyData.in -i -j9.7 file0.def file1.def")]

Now inside Options::GetUsage method just make this call:

return HelpText.AutoBuild(this, (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current));

As previously stated the parser knows when to call GetUsage and AutoBuild knows how to format the help screen for you.

Last edited Jun 2, 2012 at 7:28 AM by gsscoder, version 7

Comments

kirkbroadhurst Jan 16, 2014 at 3:43 PM 
It is out of date - 18 months as of now - but rather than nitpick rusty documentation it's easy enough to identify how to implement the same functionality. Just add

[ParserState]
public IParserState LastParserState { get; set; }

to your 'Options' class and the Parser will both place the parse errors there, and read those errors when running AutoBuild.

ericpopivker Jun 26, 2013 at 2:11 PM 
This is out of date. Class CommandLineOptionsBase does not exist any longer.