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