I have an .option() that is only allowed to be one of "all", "debug" or "none".
I'd like an easy way to pass an Array to an option() and have Commander automatically check that the value passed by the user is one of the permitted values.
Something like this:
.option('-t, --target <target>', 'Specifies the target.', ["all", "debug", "none"])
Also including the permitted values in the help output could be useful, provided it's not a very large Array.
I'd gladly do the PR if I can get a response from @tj or a collaborator that this is useful.
Thanks!!
I second this, Would be great to be able to do this and validate options.
1) The .option call is quite flexible already and it is not easy to add more functionality to the current signature. I am wondering about allowing building options to make it possible to add less common functionality without complicating the existing usage. See https://github.com/tj/commander.js/issues/1106#issuecomment-558379166
2) As a different approach, I have been wondering if there could be a collection of validators available from Commander to use as custom option processing functions, but my first attempts were a bit clumsy due to option name not being easily available for error messages. For an example of a simple bring-your-own validator for an array of expected values: https://github.com/tj/commander.js/issues/1130#issuecomment-569565495
(I suspect that neither of these are as "easy" as OP had in mind when said "I'd like an easy way to pass an Array to an option() and have Commander automatically check that the value passed by the user is one of the permitted values."! See next two comments for what code could look like.)
I have been wondering about the syntax and here is one approach, fluent (chaining) calls on Option object like with Command object:
program
.addOption(new Option('-t, --target <target>', 'Specifies the target (all | debug | none).')
.valueIncludedIn(["all", "debug", "none"])
)
);
This style might be used for other enhancements for options, like:
.addOption(new Option('-f, --devFeature <feature-flag>').hidden());
And another approach, convenience routines for custom option processing with existing api:
program
.option('-t, --target <target>',
'Specifies the target (all | debug | none).',
OptionValue.includedIn(["all", "debug", "none"])()
)
This style might be used for adding other custom option processing including from the examples, like:
program
.option('-t, --target <target>',
'Specifies the target(s), comma separated',
OptionValue.csv
)
Related link from https://github.com/tj/commander.js/issues/215#issuecomment-660456539
Python argparser has choices for restricting allowed values: https://docs.python.org/3/library/argparse.html#choices
Yargs has choices too.
Experimenting with Option approach in #1331:
program
.addOption(new Option('-s, --size <value>').choices(['big', 'little']));
Included in v7.0.0 pre-release #1386
I might be late to the game, but what if you could return or throw an error in the coercion function? Then you could do any validation you want. commander would automatically generate the error message. `--the-flag: ${error.message}`
Using an exception is actually the approach I took for the choice method, see commander.optionArgumentRejected at:
But I had not thought of adding the option name in the catch rather than the throw. That would be a solution to #1207
Included in Commander 7.0.0.
Nice work @shadowspawn! I'll try and make some time to give this a go.
@shadowspawn this works very well. The only feature missing right now is to make the newly created option required. I would suggest something like setRequired()
new commander.Options("-t, --test <feature>", "test the feature").choices(["feature1", "feature2"]).setRequired()
What do you think?
@fernetmatt I think that鈥檚 .makeOptionMandatory().
@lydell is correct.
Went with mandatory as the Option class already used required and optional for whether the option-value is required or optional, like '-r <value>' and '-o [value]'. (I tried some naming variations on whether the "value" was required or the "option" was required, but it was too subtle.)
Most helpful comment
Included in Commander 7.0.0.