Ability to reverse a boolean option.
dwrogers opened this issue · comments
I have a program that I have hardcoded some options into, including a couple of Boolean ones. I would like to be able to prompt the user for additional options, including the ability for them to undo options that were set by default. I had hoped to be able to just append user input to the string I hardcoded prior to calling CLIPR. To do this, I would need them to be able to specify options such as:
--whatIf false
or
--whatIf-
...in order to negate the "--whatIf" I had already included in the string. Is there a way to do this? Is this something that has come up before?
I have worked around this issue by adding a new, inverted logic option '--forReal'.
bool _whatIfMode;
[NamedArgument('w', "whatIf", Action = ParseAction.StoreTrue, Required = false,
Description = "Perform all processing except for anything which would send messages or update the system")]
public bool WhatIfMode
{
get { return _whatIfMode; }
set { _whatIfMode = value; }
}
[NamedArgument('f', "forReal", Action = ParseAction.StoreFalse, Required = false,
Description = "Resets 'whatIf' mode")]
public bool ForRealMode
{
get { return !_whatIfMode; }
set { _whatIfMode = value; }
}
So you're saying you've hardcoded a partial set of arguments (like --first value1 --whatIf true --second value2
) and want to be able to append additional arguments to cancel out the ones that are already there? So in the end it would look something like this?
--first value1 --whatIf true --second value2 --whatIf false
Where options.WhatIfMode == false
in the end?
Interesting, I haven't thought about this scenario.
Something that might work for you would be to take advantage of ParseAction.Count
which will increment an integer every time the argument is specified. You can then have a second getter ask "is the count > 1?" to know whether you specified --whatIf
twice. Or count % 2 == 0
to turn it on and off by specifying --whatIf
an even or odd number of times.
class Options
{
[NamedArgument('w', "whatIf", Action = ParseAction.Count)]
public int WhatIfCount { get; set;}
public bool WhatIfMode
{
get { return WhatIfCount > 1; }
}
}
And to use it
void Main()
{
var hardcoded = "--whatIf";
string[] args;
var addAnother = false;
if (addAnother)
{
args = (hardcoded + " " + "--whatIf").Split();
}
else
{
args = hardcoded.Split();
}
var opts = CliParser.Parse<Options>(args);
Console.WriteLine(opts.WhatIfMode);
}
Thoughts?
Another option, and this is more of a parsing quirk than an actual feature, is that the parser seems to keep the last instance of a stored value:
class Options
{
[NamedArgument('w', "whatIf", Action = ParseAction.Store)]
public bool WhatIfMode { get; set; }
}
var opts = CliParser.Parse<Options>("--mode false --mode true".Split());
Console.WriteLine(opts.WhatIfMode); // prints true
Try the same with the second as false
and it prints false. So you could hardcode the first part as --whatIf true
and append --whatIf false
as needed.
I guess it is a weird use case... I set the options up this way to allow the clients to develop a complicated form-based messaging configuration against live data without having to worry about changing any data - that's why the "whatIf" mode is turned on by default. I wanted them to have to have to do something different and obvious to be able to actually change data. But I also wanted to be able to let them fly at the right time without changing and republishing the program. (It is a ClickOnce program so they can't just change the program arguments.)
The ParseAction.Count method seems too imprecise to me - "do I have one of them or two of them?" The ParseAction.Store last-value-wins semantics does not have that problem. (I wasn't aware that clipr would figure out that it needed to convert the parameter to Boolean if the property was a Boolean!) I'll probably go that way in the future.
Thanks!
David
Glad I could help. Also, if all you want is to have whatIf
default to True (and then be able to set --whatIf false
if needed), set it to True in the constructor for your options class:
class Options
{
public Options()
{
WhatIfMode = true;
}
[NamedArgument('w', "whatIf", Action = ParseAction.Store)]
public bool WhatIfMode { get; set; }
}