-
Notifications
You must be signed in to change notification settings - Fork 10
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
make it possible to require long options with values use =
#52
Comments
There is information available to the author in the setup of the parsing configuration, in addition to the Possible approach, with bonus support for const allArgs = process.argv;
const withValue = ['foo'];
const dashdash = allArgs.indexOf('--');
const possibleOptions = (dashdash >= 0) ? allArgs.slice(0, dashdash) : allArgs;
withValue.forEach((option) => {
if (possibleOptions.includes(`--${option}`)) {
console.error(`--${option} must have a value specified using "=", like "--${option}=value"`);
process.exit(2);
}
})
parseArgs(allArgs, { withValue }); |
imo I think that having to look at Perhaps there's metadata that could be provided that could give me enough info to directly do the validation? |
I have some empathy with your reaction. But there are only going to be nice answers to some custom changes and additions to the I think the "Intended Audience" from the previous proposal was quite realistic in this regard. #45 (comment) There are other parsing decisions which are not represented in the results, and an author can not always change the rules by looking at the results. For example, an author wanting to make it an error if an option is specified more than once. A different case that came up recently in context of |
Another possible approach, const myStringOptions = ['foo'];
const myBooleanOptions = ['flag'];
// Do not declare any withValue since do not want to allow "--foo value"
const { options, values } = parseArgs({ strict: false });
// Bring your own validation.
// (Assuming boolean option stores true, which has not landed yet)
Object.keys(options).forEach((option) => {
if (myBooleanOptions.includes(option)) {
if (typeof values[option] !== 'boolean') {
console.error(`Unexpected value for option: ${option}`);
}
}
else if (myStringOptions.includes(option)) {
if (typeof values[option] === 'string') {
console.error(`Missing value for option: ${option}`);
}
} else {
console.error(`Unknown option: ${option}`);
}
}); [Edit: some refactoring for newer terminology and conventions.] |
As with #45, I'm a bit worried about feature creep ...
I agree that if we could come up with a reasonable hook for "bringing your own validation", perhaps we could both keep the API surface really small, while supporting various preferences. |
To throw out an option I've used before in other parsing libraries: if the parsed object surfaces (or can be made to surface) location information, that makes it easy for a consumer to do this sort of check. For example, imagine that there's a const { flags, values, positionals, indexes } = parseArgs(argv, { withValue, ... });
for (let option of withValue) {
for (let index of indexes[option] ?? []) {
if (!argv[index].includes('=')) {
console.error(`--${option} must have a value specified using "=", like "--${option}=value"`);
process.exit(2);
}
}
} It also makes it possible to build many other sorts of validation, like "was this flag duplicated" (check to see if It's almost universal for parsers to expose location information (even regexes do, these days!), so there's good precedent for this kind of thing. (It might be better for |
Interesting idea. I like your examples of situations that this can detect: duplicate options, ordered options. What parsing libraries offer this, or is this something you added yourself? However, I'm only exploring. I don't think exposing more information is important at this time! |
No JS-based CLI argument parser I'm aware of does this, to be clear, but parsers in general almost always do. See pretty much every parser on astexplorer.net, for some examples. |
I like @bakkot's suggestion a lot. Another advantage of this design, is that errors can point to the exact token in process.argv that broke the parse, if we do opt for strict by default. There's a standard parse format I've used before, uinst, https://www.npmjs.com/package/unist-util-visit. Which has the benefit of tooling behind it. I agree with @shadowspawn, perhaps this is a post MVP addition, but can be a plan for how we expose highly customizable validation. |
For interest and can safely be ignored, I came across a mode in Minimist that could have led to confusion about long options and values. Minimist lets you switch zero-config from var argv = require('minimist')(process.argv.slice(2));
console.log(argv);
var argv = require('minimist')(process.argv.slice(2), { boolean: true });
console.log(argv);
|
Per discussion around #25 (comment), I want to use this API, but enforce that options with values use an
=
sign.It's fine if the validation code is in userland (ie, my code) on top of parseArgs.
How can I do that?
The text was updated successfully, but these errors were encountered: