-
Notifications
You must be signed in to change notification settings - Fork 105
Ambiguity with multiples
Ambiguity issues can arise where two or more multiple
options are defined where one is the defaultOption
. Imagine we built a tool with the following option definitions.
const commandLineArgs = require('command-line-args')
const optionDefinitions = [
{ name: 'files', multiple: true, defaultOption: true },
{ name: 'actions', multiple: true }
]
const options = commandLineArgs(optionDefinitions)
The tool (named example
in this case) might typically be used like this...
$ example one.js two.js
...resulting in these options
.
{ files: [ 'one.js', 'two.js' ] }
So far, everything is great. In this next command, the user wishes to perform the print
and archive
actions on each file.
$ example --actions print archive one.js two.js
The parser now has an ambiguity issue - it's not clear which of the four values supplied should be passed to --actions
and which to --files
(the defaultOption
). As it stands, the parsed options
will look like this.
{ actions: [ 'print', 'archive', 'one.js', 'two.js' ] }
The two actions (print
and archive
) have been parsed as actions, which is correct. However, the two file names have been parsed as actions too, which is incorrect. There are several ways to avoid ambiguity arising.
-
Supply the args in a different order. The following example works correctly, removing the ambiguity but introduces an unwelcome "order sensitivity" to the command.
$ example one.js two.js --actions print archive
-
Be specific where the
--files
list begins.$ example --actions print archive --files one.js two.js
-
Disable greedy parsing on one of the options, using
lazyMultiple
instead.const optionDefinitions = [ { name: 'files', multiple: true, defaultOption: true }, { name: 'actions', lazyMultiple: true } ]
Now, our user will need to specific the
--actions
option for each value added to the list, for example:$ example --actions print --actions archive one.js two.js
Now our parsed
options
look correct.{ actions: [ 'print', 'archive' ], files: [ 'one.js', 'two.js' ] } }