5

I'm butting my head against a wall trying to 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!
4

1 回答 1

0

命令行处理模块的README.md文件commander在其第二段中回答了您的用例:

“带有指挥官的选项是使用 .option() 方法定义的,也用作选项的文档。下面的示例从 process.argv 解析 args 和选项,将剩余的 args 作为选项不使用的 program.args 数组。 "

于 2017-10-30T19:50:38.710 回答