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);