const CliParam = require("./CliParam") /** * 特色命令行交互格式 * 有且只有一个命令码 * 可以有多个参数 * 可以有多个标记,标记分无参/单参/多参 */ module.exports = class CmdLine { constructor(line, cmd, info) { // 命令 this.cmd = cmd // 说明 this.info = info // 参数 this.params = {} // 完整命令 this.line = line } addParams(name, param){ this.params[name] = param } /** * 将命令描述解释成命令格式 * @param cmdLine * @param info */ static parse(cmdLine, info) { let pp = cmdLine.trim().split(/\s+/); let cl = new CmdLine(cmdLine, pp[0], info); let canFlagOptionalMode = true; let canParamOptionalMode = true; for ( let i = 1 ;i < pp.length; i++ ) { let p = pp[i]; let isOptional = true; let isFlag = false; if ( p.startsWith("[") && p.endsWith("]")){ isOptional = true; } else if ( p.startsWith("<") && p.endsWith(">")){ isOptional = false; } else { throw "不合法的命令格式 - " + cmdLine; } // 去掉两端标记 p = p.substring( 1, p.length -1 ); if( p.startsWith("--") ) { if ( ! isOptional && ! canFlagOptionalMode ) { throw "参数解析错误 - 必选参数必须在可选参数前面 - " + cmdLine; } if ( isOptional ) { canFlagOptionalMode = false; } p = p.substring(2); isFlag = true; } else if( p.startsWith("-") ) { if ( ! isOptional && ! canFlagOptionalMode ) { throw "参数解析错误 - 必选参数必须在可选参数前面 - " + cmdLine; } if ( isOptional ) { canFlagOptionalMode = false; } // 无值 p = p.substring(1); cl.addParams( p, new CliParam( p, isOptional , true) ); continue; } else { if ( ! isOptional && ! canParamOptionalMode ) { throw "参数解析错误 - 必选参数必须在可选参数前面 - " + cmdLine; } if ( isOptional ) { canParamOptionalMode = false; } } cl.addParams( p, new CliParam( p, isOptional , isFlag, true ) ); } return cl; } }