Reputation: 210
I'm using commander.js to parse the command line args and I'm trying to collect an optional param that can appear multiple times and it always returns the options I set plus the default one.
function collect (val, memo) {
memo.push(val);
return memo;
}
program
.command('run <param>')
.action(function run(param, options) {
console.log(param);
console.log(options.parent.config);
});
program
.option('-c, --config <path>', 'Config', collect, ["/path/to/default"])
.parse(process.argv);
When I call the script like this:
index.js run some -c "/some/path" -c "/other/path"
It prints:
[ '/path/to/default', '/some/path', '/other/path' ]
But it should only print:
['/some/path', '/other/path' ]`
When I call it without the -c
param it works correctly, printing the array with the default value. How can I fix this?
Upvotes: 6
Views: 8698
Reputation: 1801
You could mark the array you pass as default option, then when collecting look for it.
function collectRepeatable(value, previous) {
if (previous._isDefault) {
return [value];
}
previous.push(value);
return previous;
}
function defaultRepeatable(array) {
array._isDefault = true;
return array;
}
//...
program
//...
.option('--exclude <file>', 'excludes files in input directory by file or pattern',
collectRepeatable, defaultRepeatable(['.gitignore', 'codeswing.json']))
//...
I created Replit space that includes full example: https://replit.com/@AgainPsychoX/testing-commander-repeatable-options
Upvotes: 1
Reputation: 7862
The commander
"Repeatable value" option doesn't support a default value, at least in a way that prevents you from having to write your own logic to handle the scenario where the user pass one or more values.
The way you wrote your code, you're gonna have to check the size of the program.config
attribute:
-c
option value, the size is > 1
;=== 1
.IMO, this scenario calls for the "A list" option, which supports the default value, and saves you some extra work. Like:
program
.option('-l, --list <items>', 'A list', list, [ "/path/to/default" ])
.parse(process.argv);
To have access to the values passed, just call program.list
, and in the command line, call it with values:
$ index.js run some -l "/some/path","/other/path"
// where console.log(program.list) prints [ "/some/path", "/other/path" ]
Or, without values:
$ index.js run some
// where console.log(program.list) prints [ "/path/to/default" ]
Upvotes: 6