kit.program/argv/parser.js
2024-09-02 17:36:34 +08:00

110 lines
2.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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