You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow parseArgs options to have an optional value #53427
It's not unusual for command-line options to have optional arguments. For example, git has --color[=<when>]: If an argument is provided, it's used, but if --color is given without an argument, that argument defaults to always.
parseArgs() does not support this kind of optional argument. Either the option's type is boolean and any argument throws an error; or it's string and a missing argument throws an error.
What is the feature you are proposing to solve the problem?
Add a field to the option definition so that a string option is allowed to have no argument, and use a default value in that case. For example, the --color[=<when>] case could look like this:
Probably someone can think of a better name for this field.
What alternatives have you considered?
The alternative is to disable strict mode, and manually process the tokens array. However, this is a lot of boilerplate, and requires reimplementing the checks for which options are valid, making it error-prone.
The addition of parseArgs() was controversial, and it was eventually added to Node.js core with the understanding that it would always remain a minimal implementation for the most basic use cases. It is by no means meant to replace more feature-complete argument parsers that exist in the ecosystem.
Optional option-arguments are implemented in various ways and come with complications. My suggestion is don't include them as they complicate the parsing, despite looking attractive.
Let's start with POSIX. The standard says first, don't do it!
The Utility Syntax Guidelines in Utility Syntax Guidelines require that the option be a separate argument from its option-argument and that option-arguments not be optional, but there are some exceptions in POSIX.1-2017 to ensure continued operation of historical applications:
It says that an optional option-argument must be in the same argument as the option and not separated by a space.
The way optional option-arguments are implemented in libraries Commander, Yargs, and Python argParse is that optional option-arguments do not consume a space-separated argument that starts with a dash. This works quite nicely for interfaces which do not include positional arguments but is somewhat ambiguous for interfaces with positionals. I found this annoying enough that we eventually wrote it up for Commander to explain the problem and possible work-arounds:
With positionals, not so good for CLI user. How does user clarify that the following argument is not the option value, if they even realise the ambiguity? Requires more knowledge about conventions and support (especially -- option terminator).
Thanks folks! I was unaware that the Node implementation was supposed to be minimal, but it makes sense. Commander looks like it solves this and a few other issues I've been having, so I'll give it a try instead. 👍
I came from #54396 which was closed as duplicated.
I appreciate the information, however this issue showed some information that are missing in the documentation. Would it be possible, at least, to address that? The docs page doesn't warn about this behaviour (or doesn't show it), or it doesn't explain when to use the utility (or when not).
Activity
avivkeller commentedon Jun 12, 2024
Hey team, I'd love to work on this (adding a default / optional param)
I've self-assigned it, but if anyone disagrees, please let me know
tniessen commentedon Jun 12, 2024
The addition of
parseArgs()was controversial, and it was eventually added to Node.js core with the understanding that it would always remain a minimal implementation for the most basic use cases. It is by no means meant to replace more feature-complete argument parsers that exist in the ecosystem.shadowspawn commentedon Jun 17, 2024
Optional option-arguments are implemented in various ways and come with complications. My suggestion is don't include them as they complicate the parsing, despite looking attractive.
Let's start with POSIX. The standard says first, don't do it!
But then does say:
It says that an optional option-argument must be in the same argument as the option and not separated by a space.
With long options (from GNU) this means:
The way optional option-arguments are implemented in libraries Commander, Yargs, and Python argParse is that optional option-arguments do not consume a space-separated argument that starts with a dash. This works quite nicely for interfaces which do not include positional arguments but is somewhat ambiguous for interfaces with positionals. I found this annoying enough that we eventually wrote it up for Commander to explain the problem and possible work-arounds:
Without positionals works pretty nicely:
With positionals, not so good for CLI user. How does user clarify that the following argument is not the option value, if they even realise the ambiguity? Requires more knowledge about conventions and support (especially
--option terminator).AtkinsSJ commentedon Jun 17, 2024
Thanks folks! I was unaware that the Node implementation was supposed to be minimal, but it makes sense. Commander looks like it solves this and a few other issues I've been having, so I'll give it a try instead. 👍
ematipico commentedon Aug 17, 2024
I came from #54396 which was closed as duplicated.
I appreciate the information, however this issue showed some information that are missing in the documentation. Would it be possible, at least, to address that? The docs page doesn't warn about this behaviour (or doesn't show it), or it doesn't explain when to use the utility (or when not).
bakkot commentedon Aug 18, 2024
Sure, opened #54431.
shadowspawn commentedon Aug 18, 2024
I am not sure what is missing in particular?
(I was about to post as @bakkot addressed what I thought might be the most likely confusion.)