-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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
util: parseArgs should support required
in options[key]
#44564
Comments
required
in options[key]required
in options[key]
Aren't required positional arguments far more common than required options? I think Node.js should follow POSIX conventions when it comes to parsing arguments, and those seem to heavily favor positional arguments for required values (see GNU core utilities, for example). |
Positional arguments are suitable for 1 or 2 arguments, but UX guides often recommend using options when there are more to make their meaning clearer. In your example with only two options, at least one of them would make sense as a positional argument and perhaps the other one could be deduced.
Normally most or all options are optional. So it isn't very likely people will have lots of required options. An earlier version of the Python library discouraged required options on principle (optParse). The current version has this to say: https://docs.python.org/3/library/argparse.html#required
|
I agree with @shadowspawn. I would say that required options are relatively uncommon. A On the contrary, usually, each option value has to be validated in some way anyway. Its existence or non-existence is usually not the only validation criterion. |
This would probably be a separate issue, but what about parseArgs({
args,
options: {
owner: {
type: 'string',
requires: ['repo'],
incompatible: ['org'],
},
org: {
type: 'string',
requires: ['repo'],
// no need to specify incompatible: ['owner']
// it should work both ways on either one
// but it can also be explicitly on both if desired
},
repo: {
type: 'string',
// details on requiresOne further down
requiresOne: ['owner', 'org'],
},
url: {
type: 'string',
incompatible: ['repo', 'org', 'owner'],
}
}
}); The above code would result in: # Allowed
foo --url=https://gh.com/user/proj
foo --owner=user --repo=proj
foo --org=nodejs --repo=node
foo
# Not allowed
foo --url=https://... --owner=user
foo --org=nodejs --url=https://...
foo --repo=proj --owner=user --url=https://...
foo --owner=user --org=nodejs --repo=proj
foo --repo=node
foo --owner=user
foo --org=nodejs
|
Nice detailed description. I suggest opening as a separate issue if you want more visibility. I think of these as beyond-basic parsing options. I don't think |
I was not aware of the original "vision" for it and its a fair point, but as a counterpoint on the other hand, in this particular case I would argue it makes sense given it only adds optional slightly more advanced (but still arguably pretty basic) configuration, so in my opinion it'd be fine to add whilst still keeping that original vision.
|
IMHO, the same can be said about default values, which are trivial to do in userland (see, for example, #44631 (comment)) but which were stilled added. My main concern here is adding complexity both to the API surface and to the implementation while still not providing a complete solution. The goal has not been to provide a full-fledged and feature-complete argument parser. In this particular case, even with the three newly proposed options ( |
Yes. Yes, indeed. Default values could have been left out! However, there were multiple people looking for defaults who still wanted it despite the relative ease of implementation or alternatives. (I speculate a partial factor may be people not familiar or comfortable with destructuring with defaults.) Checking for champion for not adding: pkgjs/parseargs#142 (comment) |
Here's how I'd write this today: let options = {
owner: {
type: 'string',
required: true,
},
repo: {
type: 'string',
required: true,
},
force: {
type: 'boolean',
},
};
let { values } = parseArgs({
args,
options,
});
for (let [name, { required }] of Object.entries(options)) {
if (required && !(name in values)) {
throw new Error(`--${name} must be provided`);
}
} This works just as well for ten required options as for two. Given how easy this is to do in userland, and that it's a relatively unusual thing to want, I don't think it belongs in the standard library. |
TypeScript will not allow this |
Seems like it does to me? Here's a playground. |
That playground isn't doing any typechecking because the |
Yes, it is doing typechecking. You just have to wait a second or two for it to load the types, after which the errors will go away. |
I've been waiting over 10 minutes and no types load and it won't typecheck, but no matter, I just looked directly at the source of |
Well, you can of course always try it locally, if the playground isn't working for you.
I wrote the types, and it's generic so that it can do precise type inference on the result. It's not something which can be "fixed" without making the experience of using the library significantly worse, as far as I'm aware. But also, TypeScript does not generally prohibit having extra properties, outside of contexts where you're passing a literal (for which it can determine that's definitely an error). So I'm not sure why you'd expect to have an error here even without generics.
There's no other built-in functions in node which are comparable to In any case, if you think the TypeScript types could be improved, best to open an issue on definitely-typed. |
Fiddled around with this a bit more and you seem to be correct, this is indeed a limitation of TypeScript currently, pretty annoying if at some point node decides to be more strict at runtime with extraneous properties for new functions, but I guess until that happens and forces TS team to do something about it this will have to do, thanks for your insights. To go back to the original topic, I'm still not a big fan of relying on something that isn't by-the-docs (Node-wise) as like I said they could decide to be stricter in the future, but until then I suppose it is a valid solution. If it was explicitly documented in the parseArgs docs that extraneous arguments for user-defined metadata was allowed, I'd be 100% for it. |
I'm +1 for this. I opened an issue that had the same goal. I think adding the |
There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment. For more information on how the project manages feature requests, please consult the feature request management document. |
There has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment. For more information on how the project manages feature requests, please consult the feature request management document. |
What is the problem this feature will solve?
I'm building a CLI that creates some instances by id and name. But I have to check if all options are filled by the user one by one.
What is the feature you are proposing to solve the problem?
Add
required
option.What alternatives have you considered?
No response
The text was updated successfully, but these errors were encountered: