我正在使用Java将特定标志解析到我的CLI中。该标志是“流”标志,由--stN=
表示,其中N
表示从1到10000的数字。
=
之后的参数是逗号分隔的,并且表示不同的东西 - 通常是关于如何在程序中运行某个操作的命令,用于运行N
th。
这些命令本身可以有0..N个参数。
的;
它们可以混合使用字符串,数字等。
这是我提出的解决方案:
首先,我添加了一个名为--st1=command1,arg1,arg2,command2,arg2,3,command3,command4,5
的接口来保存已解析的数据:
StreamOption
接下来,我创建了一个public interface StreamOption {
}
来处理流的一部分:
StreamOptionParser
在这个实现中,我将提交流(作为列表,用逗号分隔)。
e.g
public interface StreamOptionParser<T extends StreamOption> {
StreamReturn parse(List<String> stream, int id) throws ParameterException;
}
结果类型public class CommandOneParser implements StreamOptionParser<CommandOneOption> {
StreamReturn parse(List<String> stream, int id) throws ParameterException{
//loop through the list, if terms are found, parse to a StreamObject
//if not, pass to the return list of strings..
}
}
是一个简单的POJO,允许返回解析的StreamReturn
以及需要传递给下一个解析器的任何剩余项。我还需要返回剩余的条款,以检查所有输入是否有效,并且没有任何输入。
StreamOption
它必须持有//bit of lombok
@Getter
@Setter
@AllArgsConstructor
public class StreamReturn<T extends StreamOption> {
private List<String> remainingOptions;
private Optional<List<T>> options = Optional.empty();
}
,因为可以在同一个stream中指定多个命令.List
这是一个好方法吗?或者是否有一个更好的解决方案,更少锅炉?这有什么潜在的问题吗?我认为它可以保持可扩展性,随着程序的增长,我可以在以后轻松添加新的--stN=command1,2,3,command1,4,5,...
和Options
。
我似乎无法找到任何开箱即用的解析库/模式,有没有我可能错过的?我正在使用Parsers
作为简单的标志,但这对于jcommander来说似乎太复杂了。
先谢谢你,山姆
因此,答案是通过拆分字符串将其视为普通的CLI参数。然后我利用JCommander完成所有耗时的操作,将正确的命令推入正确的转换器。
成
command1,2,3,command2,3,string1,command3
,
command1
,
2,3
,
command2
,
3,string1
有了这个,我利用JCommander注释将正确的args传递给正确的命令。
command3
和选项:
CommandOneValues{
int myValue1;
int myValue2;
}
使用简单的转换器:
@Getter
public class CommandOneOptions {
@Parameter(names = {"command1"},
converter = CommandOneConverter.class
)
CommandOneValues values;
}
希望这有助于未来的人!
除了自定义类型转换器之外,其他工具可能具有可为替代解决方案提供想法的功能。例如,picocli有一些复杂选项的机制可能很有趣:
class CommandOneConverter implements IStringConverter<CommandOneValues>{
public CommandOneValues convert(String value){
//conversion...
}
}
引用选项
假设您按如下方式定义了该选项:
argument groups
默认情况下,picocli的@Option(names = "--st", split = ",")
List<String> parts;
函数会在引号内部忽略split
,因此您可以使用引号对参数进行分组。用户输入示例:
split
regex
Picocli会将值分成以下部分:
--st1="command1,arg1,arg2","command2,arg2,3","command3","command4,5"
以上是拆分的默认行为,不需要自定义转换器或任何其他自定义代码。
论证组
Picocli 4.0将支持重复参数组(仍处于测试阶段),这可能是建模问题的不同方式。如果应用程序的概要看起来像这样对最终用户不是很好吗?
"command1,arg1,arg2"
"command2,arg2,3"
"command3"
"command4,5"
也就是说,myapp (--cmd=<commandName> [<commandArg>...])...
选项与零个或多个位置参数一起成为参数组,并且可以指定该参数组一次或多次。最终用户可以输入如下值:
--cmd
完成此任务的代码可能如下所示:
myapp --cmd=command1 arg1 arg2 --cmd=command2 arg2 3 --cmd=command3 --cmd=command4 5