Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide Array of permitted values for an option. #518

Closed
joshuapinter opened this issue Mar 26, 2016 · 17 comments
Closed

Provide Array of permitted values for an option. #518

joshuapinter opened this issue Mar 26, 2016 · 17 comments
Milestone

Comments

@joshuapinter
Copy link

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!!

@tmiddlet2666
Copy link

I second this, Would be great to be able to do this and validate options.

@shadowspawn
Copy link
Collaborator

shadowspawn commented Dec 30, 2019

  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 Feature Request: ability to hide options #1106 (comment)

  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: When providing custom function for options, requiredOption don't work #1130 (comment)

(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.)

@shadowspawn

This comment has been minimized.

@shadowspawn

This comment has been minimized.

@shadowspawn
Copy link
Collaborator

shadowspawn commented Jul 18, 2020

Related link from #215 (comment)

Python argparser has choices for restricting allowed values: https://docs.python.org/3/library/argparse.html#choices

Yargs has choices too.

@shadowspawn
Copy link
Collaborator

Experimenting with Option approach in #1331:

program
   .addOption(new Option('-s, --size <value>').choices(['big', 'little']));

@shadowspawn shadowspawn self-assigned this Aug 28, 2020
@shadowspawn shadowspawn added the pending release Merged into a branch for a future release, but not released yet label Sep 14, 2020
@shadowspawn shadowspawn added this to the v7.0.0 milestone Sep 14, 2020
@shadowspawn shadowspawn removed their assignment Sep 14, 2020
@shadowspawn
Copy link
Collaborator

Included in v7.0.0 pre-release #1386

@lydell
Copy link

lydell commented Nov 4, 2020

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}`

@shadowspawn
Copy link
Collaborator

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

@shadowspawn
Copy link
Collaborator

Included in Commander 7.0.0.

@shadowspawn shadowspawn removed the pending release Merged into a branch for a future release, but not released yet label Jan 15, 2021
@joshuapinter
Copy link
Author

Nice work @shadowspawn! I'll try and make some time to give this a go.

@fernetmatt
Copy link

@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?

@lydell
Copy link

lydell commented Jan 17, 2021

@fernetmatt I think that’s .makeOptionMandatory().

@shadowspawn
Copy link
Collaborator

shadowspawn commented Jan 17, 2021

@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.)

@SrBrahma
Copy link

SrBrahma commented Jul 2, 2021

Sorry for commenting here, but couldn't be there also an validator for arguments using addArgument? I also just have an array of possible values

@shadowspawn
Copy link
Collaborator

Hi @SrBrahma , .choices() for arguments is supported in a similar way to options.

From the README:

program
  .addArgument(new commander.Argument('<drink-size>', 'drink cup size').choices(['small', 'medium', 'large']))
  .addArgument(new commander.Argument('[timeout]', 'timeout in seconds').default(60, 'one minute'))

@SrBrahma
Copy link

SrBrahma commented Jul 2, 2021

Many thanks for the quick answer!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants