前言
应公司要求准备弄一个cli,那就暂定为win-cli吧~
然而发现有很多不了解的东西,学习的东西也挺多的,那就慢慢啃吧(慢慢吭是不阔能的...)~哈哈
首先就是commander了。
什么是commander
关于github上的介绍,这是一个node命令行接口的解决方案,那肯定是和node相关的东东啦。
我们就按照github上的英文文档来吧!!(英文菜鸡一个...然后发现有中文的README,哈哈),还是手敲一遍加强记忆吧。
安装
npm install commander
声明program变量
Commander为了方便快捷编程导出一个全局对象。
const program = require('commander')
program.version('0.0.1')
对于可能以多种方式使用commander的大型程序,包括单元测试,最好创建一个本地commander对象来使用。
const commander = require('commander')
const program = new commander.Command()
program.version('0.0.1')
选项
.option()方法用来定义带有选项的commander,同时也用于这些选项的文档。每个选项可以有一个短标识(单个字符)和一个长名字,它们之间用逗号或者空格分开。
选项(第二个参数)会被放到commander对象的属性上,多词选项如“--template-engine”会被转为驼峰法"program.templateEngine"。多个短标识可以组合为一个参数,如“-a -b -c”等价于“-abc”。
program.option('选项命令','描述', '选项处理函数', '默认值')
常用选项类型,boolean和值
最常用的两个选项类型是boolean(选项后面不跟值)和选项跟一个值(用尖括号声明)。除非在命令行中指定,否者两者都是undefined。
const program = require('commander')
program
.option('-d, --debug', 'output extra debugging')
.option('-s --small', 'small pizza size')
.option('-p, --pizza-type <type>', 'flavour of pizza')
program.parse(process.argv)
if(program.debug) console.log(program.opts())
console.log('pizza details:');
if (program.small) console.log('- small pizza size');
if (program.pizzaType) console.log(`- ${program.pizzaType}`);
默认选项值
可以为选项设置一个默认值。
const program = require('commander')
program
.option('-c, --cheese<type>', 'add the specified type of cheese', 'blue')
program.parse(process.argv)
console.log(`cheese:${program.cheese}`)
program.parse(arguments)会处理参数,没有被使用的选项会被存放在program.args数组中。
$ pizza-options
cheese: blue
$ pizza-options --cheese stilton
cheese: stilton
其他选项类型,可忽略的布尔值和标志值
选项的值伟boolean类型时,可以在其加长名字前加no-规定这个选项值伟false。单独定义同样使选项默认为真。
如果你先定义了--foo,再加上--no--foo并不会改变它本来的默认值。你可以为Boolean类型的标识指定一个默认的布尔值,从命令行里可以重写它的值。
const program = require('commander');
program
.option('--no-sauce', 'Remove sauce')
.option('--cheese <flavour>', 'cheese flavour', 'mozzarella')
.option('--no-cheese', 'plain with no cheese')
.parse(process.argv);
const sauceStr = program.sauce ? 'sauce' : 'no sauce';
const cheeseStr = (program.cheese === false) ? 'no cheese' : `${program.cheese} cheese`;
console.log(`You ordered a pizza with ${sauceStr} and ${cheeseStr}`);
你可以指定一个用作标志的选项,它可以接受值(使用方括号声明,即传值不是必须的)
const program = require('commander')
program
.option('-c, --cheese [type]', 'ADD CHEESE WITH OPTIONAL TYPE')
program.parse(process.argv)
if(program.cheese === undefined) console.log('NO CHEESE');
else if(program.cheese === true) conosle.log('ADD CHEESE');
else console.log(`ADD CHEESE TYPE ${program.cheese}`)
自定义选项处理
你可以指定一个函数来处理选项的值,接受两个参数:用户传的值,上一个值(previous value),它会返回新的选项值。
版本选项
version方法会处理现实版本命令,默认选项标识为-V和--version,当存在时会打印版本号并退出。
program.version('0.0.1')
你可以自定义标识,通过给version方法再传递一个参数,语法与option方法一致。版本标识名字可以是任意的,但是必须要有长名字。
program.version('0.0.1', '-v, --version', 'output the current version')
Commands
你可以使用.command为你的最高层命令指定子命令。这里我们有两种方法可以实现:
- 为命令绑定一个操作处理程序(action handler)
- 将命令单独写成一个可执行文件。
在.command的第一个参数你可以指定命令的名字以任何参数。参数可以是<required>必须或者[optional]可选,并且最后一个参数也可以是variadic...可变。
//通过绑定操作处理程序实现,这里description的定义和.command是分开的
//返回新生成的命令,即该子命令,以供继续配置
program
.command('clone <source> [destination]')
.description('clone a repository into a newly created directory')
.action((source, detination) => {
console.log('cloen command called')
})
//通过单独分离的可执行文件实现命令(注意这里description是作为.command的第二个参数)
//返回最顶层的命令以供继续添加子命令
program
.command('start <service>', 'start named service')
.command('stop [service]', 'stop named service, or all if no name supplied')
指定参数语法
你可以通过.arguments来为最顶级命令指定参数,对于子命令来说参数都包括在.command调用之中的。尖括号(e.g.<required>)意味着必须的输入,而方括号(e.g.[optional])则代表了可选的输入。
var program = require('command')
program
.version('0.0.1')
.arguments('<cmd> [env]')
.action(fucntion(cmd, env) {
cmdValue = cmd
envValue = env
})
program.parse(process.argv)
//使用
win 'cmd' 'env'
一个命令有且仅有最后一个参数是可变的,你需要在参数名后加上...来使他可变,例如:
var program = require('commander')
program
.version('0.1.0')
.command('rmdir <dir> [otherDirs...]')
.action(function(dirm otherDirs){
if(otherDirs) {
otherDirs.forEach(function(oDir){
console.log('rmdir %s', oDir)
})
}
})
program.parse(process.argv)
操作处理程序(Action handler)(子)命令
你可以使用操作处理程序为一个命令增加选项options。操作处理程序会接收每一个你声明的参数的变量,和一个额外的参数--这个命令对象自己。这个命令的参数包括添加的命令特定选项的值。
var program = require('commander')
program
.command('rm <dir>')
.option('-r, --recursive', 'REMOVE RECURSIVELY')
.action(function(dir, cmdObj) {
console.log('remove ' + dir + (cmdObj.recursive ? ' recursively' : ''))
})
program.parse(process.argv)
当一个命令在命令行上被使用时,它的选项必须是合法的。使用任何未知的选项会报错。然而如果一个基于操作的命令没有定义任何操作,那么这些选项是不合法的。
定义配置选项可以随着调用 .command() 传递。 为 opts.noHelp 指定 true 则该命令不会出现生成的帮助输出里。
Git风格的子命令
当.command()带有描述参数时,不能采用.action(callback)来处理子命令,否则会出错。这告诉commander,你将采用单独的可执行文件作为子命令,就像git(1)和其他流行的工具一样。Commander将会尝试在入口脚本(例如:./examples/pm)的目录搜索program-command形式的可执行文件,例如pm-install, pm-search。你可以是用配置选项executableFile来指定一个自定义的名字。
你可以在可执行文件里处理可执行子命令的选项,而不必在顶层声明他们
// file: ./examples/pm
var program = require('commander');
program
.version('0.1.0')
.command('install [name]', 'install one or more packages')
.command('search [query]', 'search with optional query')
.command('update', 'update installed packages', {executableFile: 'myUpdateSubCommand'})
.command('list', 'list packages installed', {isDefault: true})
.parse(process.argv)
自动化帮助信息 --help
帮助信息是 commander 基于你的程序自动生成的,下面是 --help 生成的帮助信息:
Options:
-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 (default: "marble")
-C, --no-cheese You do not want any cheese
-h, --help output usage information
自定义帮助
你可以通过监听 --help来控制-h, --help显示任何信息。一旦调用完成,Commander将自动退出,你的程序的其余部分不会展示。
例如在下面的 “stuff” 将不会在执行 --help 时输出。
var program = require('commander');
program
.version('0.0.1')
.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');
.outputHelp(cb)
输出帮助信息的同时不退出。可选的回调可在显示帮助文本后处理。如果你想显示默认的帮助。你可以使用类似的东西。
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
}
.helpOption(flag, description)
重写覆盖默认的帮助标识和描述
program
.helpOption('-e, --HELP', 'read more information');
.help(cb)
输出帮助信息并立即退出。 可选的回调可在显示帮助文本后处理。
自定义事件监听
你可以通过监听命令和选项来执行自定义函数。
// 当有选项verbose时会执行函数
program.on('option:verbose', function () {
process.env.VERBOSE = this.verbose;
});
// 未知命令会报错
program.on('command:*', function () {
console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' '));
process.exit(1);
});
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。