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

Allow parseArgs options to have an optional value #53427

Closed
AtkinsSJ opened this issue Jun 12, 2024 · 4 comments · May be fixed by #53434
Closed

Allow parseArgs options to have an optional value #53427

AtkinsSJ opened this issue Jun 12, 2024 · 4 comments · May be fixed by #53434
Assignees
Labels
feature request Issues that request new features to be added to Node.js. util Issues and PRs related to the built-in util module.

Comments

@AtkinsSJ
Copy link

What is the problem this feature will solve?

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:

{
	color: {
		type: 'string',
		valueIfNoArgument: 'always',
	}
}

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.

@AtkinsSJ AtkinsSJ added the feature request Issues that request new features to be added to Node.js. label Jun 12, 2024
@RedYetiDev RedYetiDev self-assigned this Jun 12, 2024
@RedYetiDev
Copy link
Member

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

@RedYetiDev RedYetiDev added the util Issues and PRs related to the built-in util module. label Jun 12, 2024
@tniessen
Copy link
Member

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
Copy link
Member

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

Guideline 7:
Option-arguments should not be optional.

But then does say:

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.

utility_name -oVALUE
utility_name -o POSITIONAL_ARGUMENT_NOT_OPTION_VALUE

With long options (from GNU) this means:

utility_name --optional=VALUE
utility_name --optional POSITIONAL_ARGUMENT_NOT_OPTION_VALUE

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:

utility_name -o
utility_name -oVALUE
utility_name -o VALUE
utility_name -o -s SSS

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

utility_name -o WHAT_AM_I

@AtkinsSJ
Copy link
Author

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. 👍

@AtkinsSJ AtkinsSJ closed this as not planned Won't fix, can't repro, duplicate, stale Jun 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issues that request new features to be added to Node.js. util Issues and PRs related to the built-in util module.
Projects
Status: Pending Triage
Development

Successfully merging a pull request may close this issue.

4 participants