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