picocli:如果没有给出参数则显示帮助

问题描述 投票:0回答:3

我想在不带参数运行 CLI 应用程序时自动显示帮助。 我发现这个问题在 StackOverflow 上出现了多次。我花了很多时间来解决这个问题,我已经阅读了官方文档,检查了文章,但仍然不清楚如何实现这一点。

这就是我所拥有的:

主课

@Command(
        subcommands = {C1.class, C2.class}
)
public class HelloCli implements Callable<Integer>  {

    @Option(names = {"?", "-h", "--help"},
            usageHelp = true,
            description = "display this help message")
    boolean usageHelpRequested;

    @Override
    public Integer call() throws Exception {
        System.out.println("wanna show the help here");
        return 1;
    }

    public static void main(String... args) {
        int exitCode = new CommandLine(new HelloCli()).execute(args);
        System.exit(exitCode);
    }
}

处理show-user函数的类:

@CommandLine.Command(name = "show-user",
                     aliases = "-show-user")
public class C1 implements Callable<Integer> {

    @CommandLine.Option(names = {"?", "-h", "--help"},
                        usageHelp = true,
                        description = "display this help message")
    boolean usageHelpRequested;

    @CommandLine.Option(names = {"-p1"},
                        description = "show-user: param 1")
    String  p1;

    @Override
    public Integer call() throws Exception {
        System.out.println("executing the 'show-user' business logic...");
        System.out.println("param 1: " + p1);
        return 4;
    }
}

处理 create-user 命令的类:

@CommandLine.Command(name = "create-user",
                     aliases = "-create-user")
public class C2  implements Callable<Integer> {

    @CommandLine.Option(names = {"?", "-h", "--help"},
                        usageHelp = true,
                        description = "display this help message")
    boolean usageHelpRequested;

    @CommandLine.Option(names = {"-p1"},
                        description = "create-user: another param 1")
    String  p1;

    @Override
    public Integer call() throws Exception {
        System.out.println("executing the 'create-user' business logic...");
        System.out.println("param 1: " + p1);
        return 5;
    }
}

案例1:当我用

-h
调用这个应用程序时,帮助会正确显示:

Usage: <main class> [?] [COMMAND]
      ?, -h, --help   display this help message
Commands:
  show-user, -show-user
  create-user, -create-user

案例 2:显示第一个函数的帮助,调用

show-user -h
:

Usage: <main class> show-user [?] [-p1=<p1>]
      ?, -h, --help   display this help message
      -p1=<p1>        show-user: param 1

案例 3:查询第一个函数的帮助,调用

create-user -h
:

Usage: <main class> create-user [?] [-p1=<p1>]
      ?, -h, --help   display this help message
      -p1=<p1>        create-user: another param 1

案例 4:在没有参数的情况下调用我的应用程序会显示以下内容:

wanna show the help here

我的问题很简单:

在没有参数的情况下运行 CLI 工具时如何显示帮助 (

Case 4
)?

我想我需要将自定义代码添加到

HelloCli.call()
方法中,并使用一个循环从实现这些功能的两个类中收集帮助文本。但不确定如何。我还没有找到这个流行用例的任何示例代码。

我的附加问题与第一个问题类似: 我可以以某种方式显示来自

Case 2
Case 3
的所有内容一起显示的完整帮助吗?

java command-line-interface picocli
3个回答
1
投票

这记录在有关子命令的部分中,使子命令成为必需

本质上,不要在顶级命令中实现 Callable 或 Runnable。这使得最终用户必须指定子命令。手册有一个例子。

关于你的第二个问题,如何自定义使用帮助信息,请查看 picocli GitHub 项目的 picocli-examples 模块。很多示例都是关于自定义帮助的。 例如,这个在顶级命令的使用帮助中显示了子命令(和子子命令)的完整层次结构。


1
投票

您也可以使用

CommandSpec
执行此操作,如 picocli-examples 存储库中的 Git 示例所示。只需将
spec.commandLine().usage(System.err)
添加到顶级命令的
call()
/
run()
方法即可。

@Command(name = "cli", subcommands = {ShowUserCommand.class})
public class CLI implements Runnable {

    @Option(names = {"-h", "--help"}, usageHelp = true, description = "Display this usage menu")
    private boolean help;

    @Spec
    CommandSpec spec;

    @Override
    public void run() {
        // print the help menu if no subcommand is passed
        spec.commandLine().usage(System.err);
    }

    public static void main(String[] args) {
        final int exitCode = new CommandLine(new CLI()).execute(args);
        System.exit(exitCode);
    }
}

@Command(name = "show-user", description = "Show the current user")
public class ShowUserCommand implements Runnable {
    
    @Option(names = {"-h", "--help"}, usageHelp = true, description = "Display this usage menu")
    private boolean help;
    
    @Option(names = {"-u", "--uppercase"}, description = "Print the username as uppercase")
    private boolean uppercase;

    @Spec
    CommandSpec spec;
    
    @Override
    public void run() {
        String username = System.getProperty("user.name");
        System.out.println("User: " + (uppercase ? username.toUpperCase() : username));
    }
}

执行不带任何参数的命令将打印帮助菜单:

关于您的后续问题,似乎没有办法打印完整的帮助消息(包括子命令的选项),需要使用

-h
传递子命令才能查看该特定子命令的帮助。


0
投票

如果您发现了这个并且使用子命令,答案非常简单:

  1. Do使用Callable或Runnable
  2. Do使用CommandLine的execute方法而不是parseArgs
© www.soinside.com 2019 - 2024. All rights reserved.