javascriptnode.jsnode-commander

Commander.js collect multiple options always include default


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?


Solution

  • 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:

    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" ]