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