I have defined options as follows:
public class ArgumentsHeader
{
[VerbOption("configure", HelpText = "Sets configuration on server.")]
public ServerConfigurationArguments ServerConfigurationArguments { get; set; }
[HelpVerbOption]
public string GetUsage(string s)
{
return HelpText.AutoBuild(this, s);//always just 'help' or null showing up here.
}
}
public class ServerConfigurationArguments : ArgumentsBase
{
[Option('f', "filename", HelpText = "Path to JSON configuration file", DefaultValue = "config.json", Required = true)]
public string PathToConfig { get; set; }
}
Then parsing them like this:
string invokedVerb = null;
object invokedVerbInstance = null;
var parser = new Parser(x =>
{
x.MutuallyExclusive = true;
});
var options = new ArgumentsHeader();
if (!parser.ParseArguments(args, options,
(verb, subOptions) =>
{
// if parsing succeeds the verb name and correct instance
// will be passed to onVerbCommand delegate (string,object)
invokedVerb = verb;
invokedVerbInstance = subOptions;
}))
{
Exit(ExitStatus.InvalidArguments);
}
But if I try to run my exe with 'help configure' it will just print out entire help, AND in GetUsage(string) method there is only 'help' command showing up in debugger.
Is it a bug or what?
It IS a bug.
I checked with a program similar to yours and had the same (mis)behavior, then switched to the Command Line project itself, had the same but I think I found the problem.
If you are using the "source" version of Command Line Parser embedded in your project, you may fix it as follows (the code below is from class commandLine.Parser):
private bool TryParseHelpVerb(string[] args, object options, Pair<MethodInfo, HelpVerbOptionAttribute> helpInfo, OptionMap optionMap)
{
var helpWriter = _settings.HelpWriter;
if (helpInfo != null && helpWriter != null)
{
if (string.Compare(args[0], helpInfo.Right.LongName, GetStringComparison(_settings)) == 0)
{
// User explicitly requested help
// +++ FIX
// var verb = args.FirstOrDefault(); // This looks wrong as the first element is always the help command itself
var verb = args.Length == 1 ? null : args[1]; // Skip the help command and use next argument as verb
// --- FIX
if (verb != null)
{
var verbOption = optionMap[verb];
if (verbOption != null)
{
if (verbOption.GetValue(options) == null)
{
// We need to create an instance also to render help
verbOption.CreateInstance(options);
}
}
}
DisplayHelpVerbText(options, helpInfo, verb);
return true;
}
}
return false;
}
Unfortunately, if you link directly to the Command Line Parser DLL I don't think there is any workaround for it. In this case only the author can fix it...
If you are using the NuGet package, here is a quick work around. Store the args with the options so you can forward the actual verb to HelpText.AutoBuild. Also you will need to have an instance of your Verb Option for the HelpText.AutoBuild to inspect.
public class ArgumentsHeader
{
public string[] args { get; set; } = new string[0];
[VerbOption("configure", HelpText = "Sets configuration on server.")]
public ServerConfigurationArguments ServerConfigurationArguments { get; set; } = new ServerConfigurationArguments();
[HelpVerbOption]
public string GetUsage(string verb)
{
if (verb?.ToLower() == "help" && args.Length > 1)
{
verb = args[1];
}
return HelpText.AutoBuild(this, verb);
}
}
Then just create the options with the args.
var options = new ArgumentsHeader { args = args };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With