-
Notifications
You must be signed in to change notification settings - Fork 996
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
Disallow multiple arguments (array) for individual key #1318
Comments
Within "yargs-parser" you can define |
'use strict';
var parse = require('yargs-parser');
var args = parse(
['--timeout', '2s', '--timeout', '1s', '--timeout', '800', '--file', '2', '--file', '6'], {
array: [{key: 'file', number: true}],
string: ['timeout'],
configuration: {
'duplicate-arguments-array': false,
'camel-case-expansion': false
}
});
console.log(args); // { _: [], timeout: '800', file: [ 2, 6 ] }
// with "array: [{key: 'file', string: true}]," the output is:
// { _: [], timeout: '800', file: [ '6' ] } |
I found this quite confusing as well. I'm seeing that by default, if I specify a type like I would have expected any option key that specifies a Due to compatibility, maybe it would be more feasible to only enable this behavior in strict parsing mode, or perhaps also require setting In the meantime people need to be aware of this gotcha, or arguments will not have their expected types under all circumstances, even in strict mode. Depending on what the program does with the argument, this could be pretty bad. Here's what I am currently doing for additional validation: const program = require( 'yargs' )
.usage( ... )
.option( 'string-arg1', { type: 'string' } )
...
.strict();
const argv = program.argv;
function usageAndExit( errorMessage ) {
if ( errorMessage ) {
console.error( 'Error: %s', errorMessage );
console.error();
}
program.showHelp();
process.exit( 1 );
}
[ 'stringArg1', 'stringArg2', 'numberArg', 'choiceArg' ].forEach( arg => {
if ( argv[ arg ] && Array.isArray( argv[ arg ] ) ) {
usageAndExit( util.format(
'Invalid value for --%s: %o',
arg,
argv[ arg ]
) );
}
} ); |
You can use
But yeah, an option that should be included in arguments only once is such a trivial case, it makes no sense at all that there's no simple way to specify it. Especially considering that you set the type of option as a simple value (number/string) and then you get it as an array, forcing you to perform unnecessary checks. |
Too check all, I resorted to .check((args) => {
const arrayArgs = Object.entries(args)
.filter(([k, v]) => typeof k === 'string' && /[A-Z]+/i.test(k) && Array.isArray(v))
.map(([k, _]) => k)
return arrayArgs.length > 0
? `Too many arguments: ${arrayArgs.join(', ')}`
: true
}) |
Some tests with the the current master branch of yargs. With the default configuration: const yargs = require('yargs')
console.log(
yargs
.option("collection", { array: true })
.parse()
) $ node index.js --collection 1 --collection 2 3 --scalar 5 --scalar 6 7
{ _: [ 7 ],
collection: [ 1, 2, 3 ],
scalar: [ 5, 6 ],
'$0': 'index.js' } If disabling .parserConfiguration({
"duplicate-arguments-array": false
}) $ node index.js --collection 1 --collection 2 3 --scalar 5 --scalar 6 7
{ _: [ 7 ], collection: [ 2, 3 ], scalar: 6, '$0': 'index.js' } And even if specifying .option("collection", { array: true, string: true }) $ node index.js --collection 1 --collection 2 3 --scalar 5 --scalar 6 7
{ _: [ 7 ],
collection: [ '2', '3' ],
scalar: 6,
'$0': 'index.js' } To summarize:
So:
IMHO:
|
This seems to also affect variadic positional arguments: var yargs = require("yargs")
yargs
.parserConfiguration({
"duplicate-arguments-array": false,
})
.command(
"test <name> <key> <value> [extras...]",
"Test positional arguments",
function (yargs) {},
function (argv) {
console.log(argv.name, argv.key, argv.value, argv.extras)
}
)
.parse()
Removing $ node index.js test name key1 value1 key2 value2
name key1 value1 [ 'key2', 'value2' ] Explicitly specifying the type of the variadic argument as |
Yargs .parserConfiguration({
"duplicate-arguments-array": false,
})
.option(`s`, {
alias: `source`,
default: undefined,
nargs: 1,
requiresArg: true,
string: true,
array: false,
}) and calling {
"_": [],
"s": "qwe",
"source": [
"asd",
"qwe"
],
"$0": "mycommand"
} Notice that |
Description
"duplicate-arguments-array"
exists as a "yargs-parser" option to set this globally.But I don't see how to leave it enabled globally and disable it on key-by-key basis (or vice versa).
Need both behaviors.
Desired Outcome
Example has two arguments:
collection
: Value is an array of all provided valuesscalar
: Value should be last givenRelated
#229 (Disallow multiple arguments (array) for a key) [original issue]
#530 (Disable "duplicates" behaviour)
#586 (Add coerce API)
The text was updated successfully, but these errors were encountered: