command-line-args
command-line-args copied to clipboard
double hyphen is parsed as an argument when `defaultOption` is set
The wiki discusses how to correctly handle a double hyphen / double dash (--
), but the suggested solution doesn't work when defaultOption
is set, particularly alongside multiple
:
'use strict';
const commandLineArgs = require('command-line-args')
const optionDefinitions = [
{ name: 'verbose', alias: 'v', type: Boolean },
{ name: 'src', type: String, defaultOption: true, multiple: true },
{ name: 'timeout', alias: 't', type: Number }
]
const options = commandLineArgs(optionDefinitions, { stopAtFirstUnknown: true })
console.log(options)
run with
node main.js one -t 0 -- --verbose two
produces
{ src: [ 'one', '--', 'two' ], timeout: 0, verbose: true }
That's not what --
means: the whole point is that encountering --
should mean that --verbose
is interpreted as a positional argument rather than as a flag.
On the other hand, if you have defaultOption: false
, then it will stop when it encounters the first positional argument, and the above invocation will result in
{ _unknown: [ 'one', '-t', '0', '--', '--verbose', 'two' ] }
i.e. it will fail to parse -t
.
So neither approach actually allows you to correctly handle --
.
For now, I'm working around it by manually splicing out the --
part before invoking commandLineArgs
:
'use strict';
const commandLineArgs = require('command-line-args')
const optionDefinitions = [
{ name: 'verbose', alias: 'v', type: Boolean },
{ name: 'src', type: String, defaultOption: true, multiple: true },
{ name: 'timeout', alias: 't', type: Number }
]
const { argv } = process
let notParsed = []
const dashDashIndex = argv.indexOf('--')
if (dashDashIndex !== -1) {
notParsed = argv.splice(dashDashIndex + 1)
argv.pop()
}
const options = commandLineArgs(optionDefinitions, { argv })
options.src = (options.src || []).concat(notParsed);
console.log(options)
which gives for the above invocation
{ src: [ 'one', '--verbose', 'two' ], timeout: 0 }
which is the right thing.