Please help me get node's commander
module to parse arguments the way I want.
I'm looking to upload a list of files to a named database. There is a default database name, so the user shouldn't need to include a database parameter.
I'd like this command to work as following:
>>> ./upload.js --db ReallyCoolDB /files/uploadMe1.txt /files/uploadMe2.txt
(uploads "uploadMe1.txt" and "uploadMe2.txt" to database "ReallyCoolDB")
>>> ./upload.js /files/uploadMe1.txt /files/uploadMe2.txt
(uploads "uploadMe1.txt" and "uploadMe2.txt" to the default database)
>>> ./upload.js --db ReallyCoolDB
(returns an error; no files provided)
How can I implement this with commander
? I've tried a number of things already, currently I'm stuck with this code which doesn't work:
// upload.js:
#!/usr/bin/env node
var program = require('commander');
program
.version('0.1.0')
.description('Upload files to a database')
.command('<path1> [morePaths...]')
.option('-d, --db [dbName]', 'Optional name of db', null)
.action(function(path1, morePaths) {
// At this point I simply want:
// 1) a String "dbName" var
// 2) an Array "paths" containing all the paths the user provided
var dbName = program.db || getDefaultDBName();
var paths = [ path1 ].concat(morePaths || []);
console.log(dbName, paths);
// ... do the upload ...
})
.parse(process.argv);
When I try to run ./upload.js
, I get no output!
How can I use commander to accept a single optional parameter, and a non-empty list of strings??
EDIT: Thanks to Rob Raisch's answer I've solved my problem! The solution is to use usage
instead of action
, do all work after the program
commands (instead of within an action
function), work with program.db
and program.args
, and manually ensure that program.args
is non-empty:
var program = require('commander');
program
.version('0.1.0')
.description('Upload files to a database')
.usage('[options] <path1> [morePaths ...]') // This improves "--help" output
.option('-d, --db [dbName]', 'Optional name of db', null)
.parse(process.argv);
var dbName = program.db || getDefaultDBName();
var paths = program.args;
if (!paths.length) {
console.log('Need to provide at least one path.');
process.exit(1);
}
// Do the upload!
The README.md file for the commander
command line processing module answers your use case in its second paragraph:
"Options with commander are defined with the .option() method, also serving as documentation for the options. The example below parses args and options from process.argv, leaving remaining args as the program.args array which were not consumed by options."
// .command('sub-command-name <path1> [morePaths...]')
.arguments('<path1> [morePaths...]')
.arguments('<paths...>')
or use the new syntax for an argument at a time (so more like adding subcommands and options):
.argument('<paths...>', 'description')
It looks like the --db
option should have an option-argument if it is used, so I suggest <dbName>
rather than [dnName]
.
You could specify the default db with the option so it can be seen in the help too.
Putting it all together:
#!/usr/bin/env node
var program = require('commander');
program
.version('0.1.0')
.description('Upload files to a database')
.argument('<paths...>', 'one or more files to upload')
.option('-d, --db <dbName>', 'name of db', getDefaultDBName())
.action(function(paths, options) {
// At this point I simply want:
// 1) a String "dbName" var
// 2) an Array "paths" containing all the paths the user provided
console.log(options.db, paths);
// ... do the upload ...
})
.parse(process.argv);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With