Commander.js中文文档

本文翻译自https://github.com/tj/commander.js

 

Commander

  node.js命令行界面的完整解决方案,受Ruby Commander启发。

 

安装

$ npm install commander --save

 

Options 解析

  使用.option()方法定义commander的选项options,也可以作为选项的文档。 下面的示例将解析来自process.argv的args和options,然后将剩下的参数(未定义的参数)赋值给commander对象的args属性(program.args),program.args是一个数组。

 

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var program = require('commander');

program
  .version('0.1.0')
  .option('-p, --peppers', 'Add peppers')
  .option('-P, --pineapple', 'Add pineapple')
  .option('-b, --bbq-sauce', 'Add bbq sauce')
  .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
  .parse(process.argv);

console.log('you ordered a pizza with:');
if (program.peppers) console.log('  - peppers');
if (program.pineapple) console.log('  - pineapple');
if (program.bbqSauce) console.log('  - bbq');
console.log('  - %s cheese', program.cheese);

 

执行

node index.js -pPbc hahah
you ordered a pizza with: - peppers - pineapple - bbq - hahah cheese

短标志可以作为单个arg传递,例如-abc相当于-a -b -c。 比如“ --template-engine”之类的多词组成的选项会变成骆驼式的program.templateEngine。

请注意,以--no前缀开头的多词选项是其后选项的布尔值的反。 例如,--no-sauce将program.sauce的值设置为false。

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var program = require('commander');

program
  .option('--no-sauce', 'Remove sauce')
  .parse(process.argv);

console.log('you ordered a pizza');
if (program.sauce) console.log('  with sauce');
else console.log(' without sauce');

 执行结果

node index.js --no-sauce
you ordered a pizza without sauce

 

 版本选项

调用版本会默认将-V和--version选项添加到命令中。 当存在这些选项中的任何一个时,该命令将打印版本号并退出。

#!/usr/bin/env node

var program = require('commander');

program
    .version('0.0.1')
    .parse(process.argv);

执行结果:

node index.js -V

0.0.1

如果希望程序响应-v选项而不是-V选项,只需使用与option方法相同的语法将自定义标志传递给version方法

program
  .version('0.0.1', '-v, --version')

版本标志可以被命名为任何值,但是长选项是必需的。

 

Command-specific options

你可以在命令上绑定选项

#!/usr/bin/env node

var program = require('commander');

program
  .command('rm <dir>')
  .option('-r, --recursive', 'Remove recursively')
  .action(function (dir, cmd) {
    console.log('remove ' + dir + (cmd.recursive ? ' recursively' : ''))
  })

program.parse(process.argv)

  

node index.js rm /hahah -r

remove /hahah recursively

使执行命令时,将验证该命令的options,任何未知的option都将报错。 但是,如果基于action的命令如果没有定义action,则不验证options。

 

Coercion

function range(val) {
  return val.split('..').map(Number);
}

function list(val) {
  return val.split(',');
}

function collect(val, memo) {
  memo.push(val);
  return memo;
}

function increaseVerbosity(v, total) {
  return total + 1;
}

program
  .version('0.1.0')
  .usage('[options] <file ...>')
  .option('-i, --integer <n>', 'An integer argument', parseInt)
  .option('-f, --float <n>', 'A float argument', parseFloat)
  .option('-r, --range <a>..<b>', 'A range', range)
  .option('-l, --list <items>', 'A list', list)
  .option('-o, --optional [value]', 'An optional value')
  .option('-c, --collect [value]', 'A repeatable value', collect, [])
  .option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0)
  .parse(process.argv);

console.log(' int: %j', program.integer);
console.log(' float: %j', program.float);
console.log(' optional: %j', program.optional);
program.range = program.range || [];
console.log(' range: %j..%j', program.range[0], program.range[1]);
console.log(' list: %j', program.list);
console.log(' collect: %j', program.collect);
console.log(' verbosity: %j', program.verbose);
console.log(' args: %j', program.args);

  执行结果

node index.js -i 1.2 -f 1.2 -r 1..2 -l a,b -o hehe -c heihei -v zeze

 int: 1
 float: 1.2
 optional: "hehe"
 range: 1..2
 list: ["a","b"]
 collect: ["heihei"]
 verbosity: 1
 args: ["zeze"]

  正则表达式

program
  .version('0.1.0')
  .option('-s --size <size>', 'Pizza size', /^(large|medium|small)$/i, 'medium')
  .option('-d --drink [drink]', 'Drink', /^(coke|pepsi|izze)$/i)
  .parse(process.argv);

console.log(' size: %j', program.size);
console.log(' drink: %j', program.drink);

  执行结果

node index.js -s hahah -d hehe

 size: "medium"
 drink: true

  size 没有输入值则报错,不符合正则则为默认值,符合正则则为size

  drink 没有输入则报undefined,不符合正则则为true,符合正则则为drink

 

Variadic arguments可变参数

命令command有且只有最后一个参数可变不固定的。 要使参数变量可变,必须将...附加到参数名称。 这是一个例子:

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var program = require('commander');

program
  .version('0.1.0')
  .command('rmdir <dir> [otherDirs...]')
  .action(function (dir, otherDirs) {
    console.log('rmdir %s', dir);
    if (otherDirs) {
      otherDirs.forEach(function (oDir) {
        console.log('rmdir %s', oDir);
      });
    }
  });

program.parse(process.argv);

  执行结果

node index.js rmdir ./hahah aaa bbb ccc

rmdir ./hahah
rmdir aaa
rmdir bbb
rmdir ccc

  可变参数的值保存在数组中, 通过program.args以及传递action的参数获取。

 

指定参数语法 Specify the argument syntax

#!/usr/bin/env node

var program = require('commander');

program
  .version('0.1.0')
  .arguments('<cmd> [env]')
  .action(function (cmd, env) {
     cmdValue = cmd;
     envValue = env;
  });

program.parse(process.argv);

if (typeof cmdValue === 'undefined') {
   console.error('no command given!');
   process.exit(1);
}
console.log('command:', cmdValue);
console.log('environment:', envValue || "no environment given");

  执行结果

node index.js cmd env

command: cmd
environment: env

  尖角括号<>(例如<cmd>)表示必需的输入。 方括号(例如[env])表示可选输入。

  

Git风格的子命令

当.command()用description参数时,不应调用.action(回调)来处理子命令,否则会出错。 这是告诉commander你要为子命令使用单独的可执行文件,就像git(1)和其他流行的工具一样。
这时commander将尝试使用名称program-command搜索条目脚本目录中的可执行文件(如./examples/index),如index-install,index-search。

可以通过调用.command()传递options。 将opts.noHelp指定true将从生成的帮助输出中删除子命令。 如果未指定其他子命令,则为opts.isDefault指定true将运行子命令。

如果程序设计为全局安装,请确保可执行文件具有正确的模式,如755。

 

--harmony

您可以通过两种方式启用--harmony选项:

子命令脚本使用 #! /usr/bin/env node --harmony, 注意某些操作系统版本不支持此模式。
调用命令时使用--harmony选项,如node --harmony examples/index publish。 产生子命令进程时将保留--harmony选项。

 

默认help Automated --help

帮助信息是根据commander已知的信息自动生成的:

$ ./examples/pizza --help
Usage: pizza [options]

An application for pizzas ordering

Options:
  -h, --help           output usage information
  -V, --version        output the version number
  -p, --peppers        Add peppers
  -P, --pineapple      Add pineapple
  -b, --bbq            Add bbq sauce
  -c, --cheese <type>  Add the specified type of cheese [marble]
  -C, --no-cheese      You do not want any cheese

  

自定义help Custom help

您可以通过侦听“--help”来显示任意-h, - help信息。 一旦完成,Commander将自动退出,所以程序的其余部分将不会执行,例如,在使用--help时,以下可执行文件“stuff”将不会输出。

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var program = require('commander');

program
  .version('0.1.0')
  .option('-f, --foo', 'enable some foo')
  .option('-b, --bar', 'enable some bar')
  .option('-B, --baz', 'enable some baz');

// must be before .parse() since
// node's emit() is immediate

program.on('--help', function(){
  console.log('')
  console.log('Examples:');
  console.log('  $ custom-help --help');
  console.log('  $ custom-help -h');
});

program.parse(process.argv);

console.log('stuff');

  执行结果

node index.js -h

Usage: index [options]

Options:
  -V, --version  output the version number
  -f, --foo      enable some foo
  -b, --bar      enable some bar
  -B, --baz      enable some baz
  -h, --help     output usage information

Examples:
  $ custom-help --help
  $ custom-help -h

  

.outputHelp(cb)

输出帮助信息而不退出。 回调cb允许在显示帮助文本之前对其进行后处理。如果要在默认情况下显示帮助(例如,如果未提供command),则可以使用以下内容:

var program = require('commander');
var colors = require('colors');

program
  .version('0.1.0')
  .command('getstream [url]', 'get stream URL')
  .parse(process.argv);

if (!process.argv.slice(2).length) {
  program.outputHelp(make_red);
}

function make_red(txt) {
  return colors.red(txt); //display the help text in red on the console
}

.help(cb)

输出帮助信息并立即退出。 回调cb允许在显示帮助文本之前对其进行后处理。

自定义事件监听 Custom event listeners

可以通过监听command和option事件来执行自定义操作。

program.on('option:verbose', function () {
  process.env.VERBOSE = this.verbose;
});

// error on unknown commands
program.on('command:*', function () {
  console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' '));
  process.exit(1);
});

 示例

var program = require('commander');

program
  .version('0.1.0')
  .option('-C, --chdir <path>', 'change the working directory')
  .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
  .option('-T, --no-tests', 'ignore test hook');

program
  .command('setup [env]')
  .description('run setup commands for all envs')
  .option("-s, --setup_mode [mode]", "Which setup mode to use")
  .action(function(env, options){
    var mode = options.setup_mode || "normal";
    env = env || 'all';
    console.log('setup for %s env(s) with %s mode', env, mode);
  });

program
  .command('exec <cmd>')
  .alias('ex')
  .description('execute the given remote cmd')
  .option("-e, --exec_mode <mode>", "Which exec mode to use")
  .action(function(cmd, options){
    console.log('exec "%s" using %s mode', cmd, options.exec_mode);
  }).on('--help', function() {
    console.log('');
    console.log('Examples:');
    console.log('');
    console.log('  $ deploy exec sequential');
    console.log('  $ deploy exec async');
  });

program
  .command('*')
  .action(function(env){
    console.log('deploying "%s"', env);
  });

program.parse(process.argv);

  

 

  

 

posted @ 2018-10-21 21:09  mirandachen  阅读(18147)  评论(1编辑  收藏