commandline icon indicating copy to clipboard operation
commandline copied to clipboard

How do I print the help screen?

Open ptr727 opened this issue 8 years ago • 6 comments

How do I print the help output I've evaluated the logical options and something is wrong?

            // Parse the commandline arguments
            // https://github.com/gsscoder/commandline
            Parser parser = new Parser(with =>
            {
                with.CaseSensitive = false;
                with.HelpWriter = Console.Error;
            });
            ParserResult<Options> result = parser.ParseArguments<Options>(args);
            if (result.Tag == ParserResultType.NotParsed)
            {
                return -1;
            }
            Options options = ((Parsed<Options>)result).Value;

            // Process or monitor must be specified
            if (options.ProcessFolders == false && options.MonitorFolders == false)
            {
                // TODO : Call help output directly
                return -1;
            }

ptr727 avatar May 23 '17 17:05 ptr727

Are you looking for HelpText.AutoBuild(args)?

NVanderEnde avatar May 24 '17 15:05 NVanderEnde

How do I use it?

ptr727 avatar May 26 '17 16:05 ptr727

Like so:

  private static string HelpOutput(Parameters args)
    {
        var result = new StringBuilder();

        result.AppendLine("Hello, and welcome to the  console application.");
        result.AppendLine("This application takes in a data file and attempts to import that data into our systems.");
        result.AppendLine("Valid options are:");
        result.AppendLine(HelpText.AutoBuild(args));
        result.AppendLine("Press any key to exit");

        return result.ToString();
    }

where Parameters is some class that's been annotated with the Option attributes, etc.

NVanderEnde avatar May 26 '17 16:05 NVanderEnde

I get a runtime exception:

            // Parse the commandline arguments
            // https://github.com/gsscoder/commandline
            Parser parser = new Parser(with =>
            {
                with.CaseSensitive = false;
                with.HelpWriter = Console.Error;
            });
            ParserResult<Options> result = parser.ParseArguments<Options>(args);
            if (result.Tag == ParserResultType.NotParsed)
            {
                Tools.WriteLineError("Failed to parse commandline.");
                return -1;
            }
            Options options = (((Parsed<Options>)result).Value);

            // Process or monitor must be specified
            if (options.ProcessFolders == false && options.MonitorFolders == false)
            {
                Tools.WriteLineError(CommandLine.Text.HelpText.AutoBuild(result));
                Tools.WriteLineError("Failed to parse commandline, missing action.");

                return -1;
            }

Fails at runtime.

System.ArgumentException occurred
  HResult=0x80070057
  Message=Excepting NotParsed<T> type.
  Source=CommandLine
  StackTrace:
   at CommandLine.Text.HelpText.AutoBuild[T](ParserResult`1 parserResult, Int32 maxDisplayWidth)
   at Plex.Program.Main(String[] args) in C:\Users\piete\OneDrive\Projects\Plex\Plex\Program.cs:line 44

ptr727 avatar May 26 '17 20:05 ptr727

I also get the same error at runtime using my own sample project. Probably a different topic... but it is unclear what the best practices are to get the helptext to be output when the args follow the "help verb" or "help" construct using the v2.x codebase - documentation is dated and so is the sample.


static int Main(string[] args)
{
	var results = Parser.Default.ParseArguments<SetupDirectionCommandOptions>(args);
	var exitCode = 0;
	if (args[0].Equals("help", StringComparison.InvariantCultureIgnoreCase))
	{
		var text = HelpText.AutoBuild(results);
		Console.WriteLine(text.ToString());
		return 0;
	}
	else
	{
		exitCode = results.MapResult(
		(SetupDirectionCommandOptions opts) => RunSetupDirection(opts),
		errs => (int)1);
	}
			

	return exitCode;
}

this is what my verb looks like...


[Verb(Verbs.SetupDirectionKey, HelpText = "Setup a direction command")]
public class SetupDirectionCommandOptions : SubOptionsBase
{
	[Option('r', "rotation-type", Default = PivotRotation.None, HelpText = "Set the pivot direction")]
	public PivotRotation Direction { get; set; }

	[Option('v', "velocitymode-type", Default = VelocityMode.AutoVri, HelpText = "Set the velocity mode")]
	public VelocityMode VelocityModeType { get; set; }

	[Option("percent", Default = 100, HelpText = "Set the speed percentage")]
	public int Percent { get; set; }

	[Option('f', "flowrate", Default = 6, HelpText = "Set the flow rate")]
	public float FlowRate { get; set; }

	[Option("ispumpon", Default = true, HelpText = "Set the is pump on flag")]
	public bool IsPumpOn { get; set; }
}

cbertolasio avatar Jun 14 '17 18:06 cbertolasio

I believe that this is definitely a bug in the code. If you use the overload of AutoBuild(...) that takes onError and onExample functions then it will write successfully.

It actually has an explicit block in the code which checks whether or not the ParserResult<T> being passed in is a NotParsed result in which case it gracefully attempts to write the error output.

if (onError != null && parserResult.Tag == ParserResultType.NotParsed)
{
    errors = ((NotParsed<T>)parserResult).Errors;

    if (errors.OnlyMeaningfulOnes().Any())
        auto = onError(auto);
}

So, as a workaround in the meantime you can just use

Console.WriteLine(HelpText.AutoBuild(result, null, null));

veleek avatar Jul 25 '17 23:07 veleek