110 lines
2.7 KiB
JavaScript
110 lines
2.7 KiB
JavaScript
const CmdLine = require("./CmdLine")
|
||
const CliCmdLine = require("./CliCmdLine")
|
||
const Config = require("./Config")
|
||
|
||
const gConfig = new Config();
|
||
|
||
module.exports = class CliCmdParser {
|
||
|
||
constructor(name) {
|
||
// 软件名称
|
||
this.name = name
|
||
this.cmdLines = {}
|
||
this.funcs = {}
|
||
}
|
||
|
||
/**
|
||
* 声明一条命令
|
||
* @param cmdLine 命令模板
|
||
* @param info 命令说明
|
||
* @param func 响应函数
|
||
*/
|
||
addCmdLine(cmdLine, info, func) {
|
||
let cl = CmdLine.parse(cmdLine, info);
|
||
if( this.cmdLines[ cl.cmd ] ) {
|
||
throw "重复注册的命令 " + cl.cmd
|
||
}
|
||
|
||
this.cmdLines[ cl.cmd ] = cl;
|
||
if ( func ) {
|
||
this.funcs[ cl.cmd ] = func;
|
||
}
|
||
|
||
return cl;
|
||
}
|
||
|
||
/**
|
||
* 打印命令帮助
|
||
*/
|
||
help(){
|
||
let bs = ""
|
||
if( this.name ) {
|
||
bs += this.name + gConfig.crlf
|
||
}
|
||
for ( let cmd in this.cmdLines ) {
|
||
bs = bs.concat("\t")
|
||
.concat( this.cmdLines[ cmd ].line )
|
||
.concat("\t")
|
||
.concat( this.cmdLines[ cmd ].info )
|
||
.concat( gConfig.crlf );
|
||
}
|
||
return bs;
|
||
}
|
||
|
||
canEval( cliCmdLine ){
|
||
return !! this.funcs[ cliCmdLine.cmdline.cmd ];
|
||
}
|
||
|
||
async eval( cliCmdLine ){
|
||
let func = this.funcs[ cliCmdLine.cmdline.cmd ];
|
||
if ( null == func ) {
|
||
throw "没找到命令相应函数";
|
||
}
|
||
return await func( cliCmdLine );
|
||
}
|
||
|
||
parse(argv){
|
||
if ( ! argv || argv.length < 1 ) {
|
||
return null;
|
||
}
|
||
|
||
if ( argv[0].startsWith("-") ) {
|
||
throw "入参命令格式错误 : 没有入参 cmd"
|
||
}
|
||
|
||
if ( ! this.cmdLines[ argv[0] ] ) {
|
||
return null;
|
||
}
|
||
|
||
// 标记: 去除 - 之后的值
|
||
const flags = new Set([])
|
||
|
||
// 命名参数: 去除 -- 之后的值为 key,之后值为 value
|
||
const params = {}
|
||
|
||
// 位置参数:值
|
||
const position = []
|
||
|
||
for (let i = 1; i < argv.length; i++ ) {
|
||
if ( argv[i].startsWith("--") ) {
|
||
if ( i + 1 == argv.length || argv[ i + 1 ].startsWith("-") ) {
|
||
throw "flag 格式错误" + argv[i];
|
||
}
|
||
params[ argv[i].substring(2) ] = argv[++i];
|
||
|
||
} else if ( argv[i].startsWith("-") ) {
|
||
flags.add( argv[i].substring(1) );
|
||
} else {
|
||
position.push( argv[i] );
|
||
}
|
||
}
|
||
|
||
let line = this.cmdLines[ argv[0] ];
|
||
// 整理
|
||
// line 是藐视
|
||
// flags, params, position 是值
|
||
return new CliCmdLine( this, line, flags, params, position);
|
||
|
||
}
|
||
|
||
} |