Seems pretty obvious to me that is perfectly possible ( and even reasonable) to be able to send a unkown length list of values for an option, and agree that being that the scenario, it could only be applied to last option ( or, optionally, until we find some kind of "terminate" char combo ( "--" would be great, but probably mess with some command shells)
it's doable?
https://github.com/tj/commander.js?#variadic-arguments
:)
It specifies exactly "The last argument of a command can be variadic"
And If there isn't a command ?
I was asking for something like
myapp --list-of-files-to-use file1 file2 file3
Could you use the args value?
myapp --option value file1 file2 file3 --optionb value file4
# //=> command.parse().args === ['file1', 'file2', 'file3', 'file4']
If you needed to, you could add a --use-a-list-of-files toggle, if it's set, you treat args as a list of files.
That's what I'm using right now. but it would be nice to be able to specify
var cmdr= require('commander')
cmdr.version('1.0.0')
.usage('something')
.option('-m, --mods <mod> [otherMods...]', 'some description', [ ])
and after parsing ,commander returns something like:
var modlist = cmdr.mods; // modlist contains ['item1','item2', 'item3']
This is not and "urgent" request . it's just a "nice addition if posible"
I'm seeing the need for this as well.
I was asking for something like
myapp --list-of-files-to-use file1 file2 file3
Another option is to use Coercion (as noted in examples):
program.
.option('-f, --files <file>', 'A path for file.', function(file, files) {
files.push(file);
return files;
}, [])
When called with:
myapp --files file1 -f file2 --files file3`
Will give you an array of files:
console.log(program.files);
// ['file1', 'file2', 'file3']
I think support for variadic args on options should be added.
Any plans on adding this feature ?
There might be a way to add it but I bet it breaks far more than you'd want.
And realistically it's not normal to want a variable list of values going into an option... nix getopt specs i doubt would have any specs for that... because it makes it hard to determine where to assign values.
I've gotten around this by taking in a comma separated list for an option. I take the option value and split the list to get my variadic arguments. I kind of disagree that it's not normal to want variadic values. I have a very legitimate need for them and I'm sure there are many more use cases.
A command separated list is a fine solution for your problem.
The real issue is when you have a variadic option, and no options between that variadic option and other arguments, they bleed into the variadic. Using a comma separated list helps define for the parser that these arbitiary characters showing up are still part of my --mods option, and not input file arguments (for example)
Are there some well known commands with variadic option support? I can't think of one. (I am not suggesting it isn't potentially useful, but am interested in prior art.)
As mentioned in the previous comments, two conventional ways of doing multiple values for an option (and covered in Open Group Utility Conventions) are:
example -f alpha -f beta -f gamma
example -f alpha,beta,gamma
This is a pretty necessary feature, you can see multiple alternatives to commander implementing it. If I make anything for a pipeline, I'm going to want to be able to pass a variadic amount of files or whatever to it. The comma and multi-flag work arounds are janky.
I see Yargs has https://yargs.js.org/docs/#api-arraykey and uses the -- terminator suggested by the original poster.
Update: this comment says does Yargs not use -- as array terminator anymore: https://github.com/yargs/yargs/issues/1527#issuecomment-577120619
I have been thinking about how this might be implemented and be as consistent as possible with existing processing. Proposal:
1) Syntax:
program
.option('-m, --mods <mod...>'),
.option('-o, --optional [opts...]')
2) If a value or values are specified then the option value is an array.
3) The first option argument is parsed in the same way as if the ... was not specified.
4) Subsequent option arguments are processed as for optional options ([value]), so a leading - or -- indicates an option and not a further argument. A lone -- stops the option processing as normal.
Example:
$ transpile --include *.js --exclude *.test.js -- thisIsAnOperandNotAnOptionValue
need any help?
Since you ask, I have some questions about your previous comment @trisimix , thanks!
you can see multiple alternatives to commander implementing it
What alternatives? (other than yargs which I found)
Adding variadic option values adds some ambiguities into the parsing. I am interested in seeing the syntax and trade-offs other alternatives have taken.
Variadic option values are not covered by the Open Group Utility Conventions and I am also interested if there is a common approach for terminating the option values from other implementations, or explicit coverage in other standards.
If I make anything for a pipeline, I'm going to want to be able to pass a variadic amount of files or whatever to it.
What is an example call to your command going to look like?
(I wasn't sure what you meant by a pipeline and how you want to call your command, which required variadic options and not just variadic arguments.)
I'm seeing the need for this too.
I'm developing an Express CLI helper which creates controller and routers and models as well.
For example the command for creating a new model is:
shirdal make:model <model-name> --attributes title:string,body:text
I guess every one prefer a command like this:
shirdal make:model <model-name> --attributes title:string body:text
I can't use variadic arguments in command because i may need to add more options like associations.
The problem got more complicated in creating router files.
The command is something like this which is not nice at all:
shirdal make:router<router-name> --routes post:/,get:/,delete:/:id
Sorry for delay, I actually don't even remember posting this, I just got the notification in email. I was neck deep in some typescript jenkins pipeline stuff for a company I don't currently work for when I wrote my original comment, and to be honest I don't even remember what work-around we used haha. Sorry to be of no help for your background research. Still willing to help if I can.
What is an example call to your command going to look like?
For us we were creating pipeline tools to do some wacky things like black box testing of language models, and creating of confusion matrices.
So a loose example without exactly remembering what I did...
We might want to break up our black box tests an be able to:
blackbox --tests test_file_for_english.json test_file_for_spanish.json
In our jenkins pipeline this might get called automatically when someone tries to push a change to our english and spanish language models, then either pass or blow-up and return a confusion matrix.
Sorry if I totally missed the scope of info you are looking for :P
For comparison, python argparse uses nargs to specify number of expected values, including + and *:
I have opened a PR with a work in progress: #1250
Fairly happy with how it has worked out so far.
Released with Commander v6.0.0 : https://github.com/tj/commander.js/releases/tag/v6.0.0
Most helpful comment
That's what I'm using right now. but it would be nice to be able to specify
and after parsing ,commander returns something like:
var modlist = cmdr.mods; // modlist contains ['item1','item2', 'item3']This is not and "urgent" request . it's just a "nice addition if posible"