1. 程式人生 > >Commander.js中文文件

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