JLine中的Picocli命令层次结构

时间:2019-06-06 16:39:10

标签: shell command-line-interface interactive picocli jline3

我正在使用Pico CLI v4.0.0-alpha-3和jline v3。我有以下课程(使用注释)。当我运行主类时,似乎无法运行命令并调用可调用对象。如果我简单地传入参数,就可以调用可调用对象。

@CommandLine.Command(name = "Test CLI",
        description = "CLI tool",
        header = "%n@|green test cli |@",
        footer = {"",
                "@|cyan Press Ctrl-D to exit the CLI.|@",
                        ""},
        version = "1.0.0",
        showDefaultValues = true,
        optionListHeading = "@|bold %nOptions|@:%n",
        subcommands = {
                Sync.class,
                Status.class
    })
public class Tester implements Callable<Integer> {

    private static final String PROMPT = "Test CLI> ";

    private LineReaderImpl lineReader;
    private PrintWriter out;


    @Option(names = {"-u", "--username"}, required = true, description = "user name")
    private String userName;

    @Option(names = {"-p", "--password"}, required = true, description = "password")
    private String password;



   final Tester tester = new Tester();
    final CommandLine cmd = prepareCommand(tester);
    final int exitCode = cmd.execute(args);

当我运行Java应用程序并运行带有参数的命令时,可调用对象不会被调用。当我简单地传递参数时,可调用对象就会被调用。关于如何解决此问题的任何想法,以便CLI用户必须在命令后输入参数。

2 个答案:

答案 0 :(得分:1)

打开CLI终端后,我再也无法使用命令名称。我可以只使用没有命令名称的参数。

我最终将逻辑移至子命令,然后可以调用该子命令。但是,现在CLI将建议的命令显示为“父命令+子命令”,我发现这很混乱(并且使用该选项不会产生期望的结果)。我最终从父命令中删除了该描述,以解决它。

答案 1 :(得分:1)

命令行实用工具

我认为打包Java应用程序的方式是造成混乱的原因。 如果您的应用程序是单个可执行文件,例如myapp.exe,那么您将在命令行上调用该应用程序,如下所示:

myapp -u xxx

如果您的应用程序是Java类,则需要这样调用它:

java -cp mylib.jar com.myorg.MyApp -u xxx

因此,顶级命令是com.myorg.MyApp类本身,在命令行上无需指定myapp作为com.myorg.MyApp类的参数< / em>。

现在假设您的myapp应用程序具有一个名为sub的子命令。同样,如果您的应用程序是单个可执行文件,则可以在命令行上调用子命令,如下所示:

myapp sub --subcommand-options

作为Java类,您需要像下面这样调用它。请注意,在这里,您要做,需要为<{1}}类指定子命令名称作为命令行参数

com.myorg.MyApp
  

旁注:人们经常做的是为Windows和Unix创建启动脚本,该脚本允许您以java -cp mylib.jar com.myorg.MyApp sub --subcommand-options 而非myapp的身份执行应用程序。人们对GraalVM充满热情的原因之一是GraalVM本机映像解决了该打包问题,并允许Java开发人员将其应用程序作为单个可执行文件分发。

Picocli的主要用例是方便使用Java创建命令行实用程序。因此,使用以下代码很容易完成上述操作:

java -cp mylib.jar com.myorg.MyApp

交互式命令行应用程序

使用JLine创建交互式CLI Shell应用程序时,需要记住,在命令行上未指定顶级命令。

因此,您希望用户能够在外壳中键入的所有命令都应该是子命令,就像您在答案中所描述的那样。

顶层命令仍然可以为用户提供帮助。一种想法是在用户输入无效命令(或仅按回车不带参数)时打印一条友好的帮助消息,然后打印顶层命令的使用帮助。