Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NDesk.Options: how to register required parameters correctly? [duplicate]

Tags:

I am trying to utilize the OptionSet class in the following way:

  string resultsFileName = null;   bool isHelp = false;    var p = new OptionSet() {     { "r=|resultsFile=",  "The file with the results", v => { resultsFileName = v; } }     { "h|help", "Show this help", v => { isHelp = (v != null); } },   };    try   {     p.Parse(args);   }   catch (OptionException e)   {     Console.WriteLine("Invalid arguments: " + e.Message);     ShowHelp(p);     return;   } 

Thus, resultsFile option is expected to be required (according to documentation: http://www.ndesk.org/doc/ndesk-options/NDesk.Options/OptionValueType.html). However, when I run the program as is (i.e. with no command line arguments) the exception is not thrown. Please assist.

Update: It looks in debugger like when no command line options are provided, the private void AssertValid (int index) method will be never reached to throw new OptionException.

like image 790
BreakPhreak Avatar asked Oct 28 '10 09:10

BreakPhreak


1 Answers

This is a duplicate of How to enforce required command-line options with NDesk.Options?, and the answer is the same: NDesk.Options doesn't support that.

Quoting myself:

As per the OptionValueType.Required docs, the = within an option specification doesn't apply to the OptionSet as a whole, but just to the value for that specific option.

The importance of this is really only relevant in two scenarios, so first let's consider the OptionSet parser:

string a = null; string b = null; var options = new OptionSet {     { "a=", v => a = v },     { "b=", v => b = v }, }; 

Scenario 1 where it's important is that OptionSet.Parse() works in a single-pass, forward-only manner, and does not look at option values to determine if they "should be" values. Thus, consider:

options.Parse(new[]{"-a", "-b"}); 

The result of this will be that a has the value "-b", and b is null. Since the handler for -a requires a value, it always gets the following value (unless the value is "encoded" into the original option, e.g. -a=value).

The second place where this is important is when a value-requiring option is the last option, and there isn't a value present for it:

options.Parse(new[]{"-a"}); 

This will throw an OptionException, as the handler for -a requires a value, and no value is present.

Consequently, if you have an option that itself is required (as opposed to an option that requires a value), you need to manually check for this:

string dir = null; new OptionSet {     { "o=", v => dir = v }, }.Parse (args);  if (dir == null)     throw new InvalidOperationException ("Missing required option -o=DIR"); 
like image 105
jonp Avatar answered Oct 12 '22 15:10

jonp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!