引子
本文使用Nodejs主要實現(xiàn)了如下形式的命令行程序
node index -A 100 //主命令
node index cmd1 -C 100 -D 200 //使用option的子命令
node index cmd2 param1 param2 param3 //使用argments的子命令
node index cmd3 -E 100 -F 200 param1 param2 //同時使用argments和option的子命令
文中option的取值通過options.option名
的方式取得讥邻,option名
在option定義時,通過--option名
定義
導(dǎo)入第三方package
var co = require('co');
var program = require('commander');
var colors = require('colors');
書寫流程控制函數(shù)
對于每一個命令,雖然執(zhí)行內(nèi)容不同瞳购,但執(zhí)行流程如下所示大致相同
- 使用co調(diào)用該命令的處理函數(shù)
- 執(zhí)行成功后輸出
success
信息垢揩,退出程序 - 執(zhí)行失敗后輸出
error
信息玖绿,退出程序
var execute = function(target, args) {
co(function*() {
yield target.apply(this, args);
}).then(function() {
console.log(colors.green('[end]') + ' success');
process.exit();
}, function(error) {
console.log(error);
process.exit();
});
};
書寫各命令的處理函數(shù)
- 主命令處理函數(shù)
接受program作為入?yún)ⅲ瑥闹锌色@取指定的option的值叁巨。
var doMain = function*(program) {
console.log(colors.green('[start]') + ' doMain1...');
// do something
console.log(program.aa);
console.log(colors.green('[end ]') + ' doMain1');
};
- 子命令1的處理函數(shù)
使用options作為入?yún)叻耍瑥闹锌色@取指定的option的值。
var doCmd1 = function*(options) {
console.log(colors.green('[start]') + ' doCmd1...');
// do something
console.log(options.cc + ',' + options.dd);
console.log(colors.green('[end ]') + ' doCmd1');
};
- 子命令2的處理函數(shù)
使用命令行參數(shù)作為入?yún)?/li>
var doCmd2 = function*(arg1, arg2, arg3) {
console.log(colors.green('[start]') + ' doCmd2...');
// do something
console.log(arg1 + ',' + arg2 + ',' + arg3);
console.log(colors.green('[end ]') + ' doCmd2');
};
- 子命令3的處理函數(shù)
使用命令行參數(shù)和options作為入?yún)⒎嫔祝琽ptions中可獲取指定的option的值蚀瘸。
var doCmd3 = function*(arg1, arg2, arg3, options) {
console.log(colors.green('[start]') + ' doCmd3...');
// do something
console.log(arg1 + ',' + arg2 + ',' + arg3 + ',' + options.ee + ',' +
options.ff);
console.log(colors.green('[end ]') + ' doCmd3');
};
定義命令行參數(shù),Option以及Action
- 主命令定義
定義程序的版本庶橱,option信息和幫助信息贮勃。
program
.version('0.0.1');
program
.description('使用node書寫命令行程序的簡單框架')
.option('-A, --aa <optionA>', 'XXXX數(shù).')
.option('-B, --bb <optionB>', 'XXXX數(shù).');
program.on('--help', function() {
console.log(' Examples:');
console.log('');
console.log(' node index cmd1 -C 100 -D 200');
console.log(' node index cmd2 param1 param2 param3');
console.log(' node index cmd3 -E 100 -F 200 param1 param2');
console.log('');
});
- 子命令定義
定義各命令的option和處理action,以及描述信息和幫助信息
program
.command('cmd1')
.description('只包含Option的子命令')
.option('-C, --cc <optionC>', 'XXXX數(shù).')
.option('-D, --dd <optionD>', 'XXXX數(shù).')
.action(function() {
execute(doCmd1, arguments);
});
program
.command('cmd2 <arg1> <arg2> [arg3]')
.description('只包含命令行參數(shù)的子命令')
.action(function() {
execute(doCmd2, arguments);
}).on('--help', function() {
console.log(' arg1:');
console.log('');
console.log(' arg1的含義說明');
console.log('');
});
program
.command('cmd3 <arg1> <arg2> [arg3]')
.option('-E, --ee <optionE>', 'XXXX數(shù).')
.option('-F, --ff <optionF>', 'XXXX數(shù).')
.description('同時包含命令行參數(shù)和Option的子命令')
.action(function() {
execute(doCmd3, arguments);
}).on('--help', function() {
console.log(' arg1:');
console.log('');
console.log(' arg1的含義說明');
console.log('');
});
命令行解析和執(zhí)行
program.parse(process.argv);
主程序流程控制
- 設(shè)置主程序運行flag
var mainFlg = true;
- 運行程序時悬包,如果未指定任何子命令或option信息衙猪,輸出幫助信息,不執(zhí)行主命令
if (!process.argv.slice(2).length) {
program.outputHelp(make_red);
mainFlg = false;
}
function make_red(txt) {
return colors.red(txt); //display the help text in red on the console
}
- 運行程序時布近,如果指定了子命令垫释,執(zhí)行子命令,不執(zhí)行主命令
var cmds = [];
program.commands.map(function(cmd) {
cmds.push(cmd._name);
});
for (var arg of process.argv.slice(2)) {
if (cmds.indexOf(arg) >= 0) {
mainFlg = false;
}
}
if (mainFlg) {
execute(doMain, [program]);
}
完整的程序文件
'use strict';
var co = require('co');
var program = require('commander');
var colors = require('colors');
var execute = function(target, args) {
co(function*() {
yield target.apply(this, args);
}).then(function() {
console.log(colors.green('[end ]') + ' success');
process.exit();
}, function(error) {
console.log(error);
process.exit();
});
};
var doMain = function*(program) {
console.log(colors.green('[start]') + ' doMain1...');
// do something
console.log(program.aa);
console.log(colors.green('[end ]') + ' doMain1');
};
var doCmd1 = function*(options) {
console.log(colors.green('[start]') + ' doCmd1...');
// do something
console.log(options.cc + ',' + options.dd);
console.log(colors.green('[end ]') + ' doCmd1');
};
var doCmd2 = function*(arg1, arg2, arg3) {
console.log(colors.green('[start]') + ' doCmd2...');
// do something
console.log(arg1 + ',' + arg2 + ',' + arg3);
console.log(colors.green('[end ]') + ' doCmd2');
};
var doCmd3 = function*(arg1, arg2, arg3, options) {
console.log(colors.green('[start]') + ' doCmd3...');
// do something
console.log(arg1 + ',' + arg2 + ',' + arg3 + ',' + options.ee + ',' +
options.ff);
console.log(colors.green('[end ]') + ' doCmd3');
};
program
.version('0.0.1');
program
.description('使用node書寫命令行程序的簡單框架')
.option('-A, --aa <optionA>', 'XXXX數(shù).')
.option('-B, --bb <optionB>', 'XXXX數(shù).');
program.on('--help', function() {
console.log(' Examples:');
console.log('');
console.log(' node index cmd1 -C 100 -D 200');
console.log(' node index cmd2 param1 param2 param3');
console.log(' node index cmd3 -E 100 -F 200 param1 param2');
console.log('');
});
program
.command('cmd1')
.description('只包含Option的子命令')
.option('-C, --cc <optionC>', 'XXXX數(shù).')
.option('-D, --dd <optionD>', 'XXXX數(shù).')
.action(function() {
execute(doCmd1, arguments);
});
program
.command('cmd2 <arg1> <arg2> [arg3]')
.description('只包含命令行參數(shù)的子命令')
.action(function() {
execute(doCmd2, arguments);
}).on('--help', function() {
console.log(' arg1:');
console.log('');
console.log(' arg1的含義說明');
console.log('');
});
program
.command('cmd3 <arg1> <arg2> [arg3]')
.option('-E, --ee <optionE>', 'XXXX數(shù).')
.option('-F, --ff <optionF>', 'XXXX數(shù).')
.description('同時包含命令行參數(shù)和Option的子命令')
.action(function() {
execute(doCmd3, arguments);
}).on('--help', function() {
console.log(' arg1:');
console.log('');
console.log(' arg1的含義說明');
console.log('');
});
program.parse(process.argv);
var mainFlg = true;
if (!process.argv.slice(2).length) {
program.outputHelp(make_red);
mainFlg = false;
}
function make_red(txt) {
return colors.red(txt); //display the help text in red on the console
}
var cmds = [];
program.commands.map(function(cmd) {
cmds.push(cmd._name);
});
for (var arg of process.argv.slice(2)) {
if (cmds.indexOf(arg) >= 0) {
mainFlg = false;
}
}
if (mainFlg) {
execute(doMain, [program]);
}