Search code examples
javacommand-line-interfacepicocli

picocli: show help if no parameter given


I would like to show the help automatically when I run my CLI app without parameters. I have seen that this question appears multiply times on StackOverflow. I spent significant time figuring this out, I have read the official document, checked articles, but still not clear how to achieve this.

This is what I have:

Main class

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

The class that handles the show-user function:

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

The class to handle the create-user command:

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

Case 1: when I call this app with -h then the help is displayed properly:

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

Case 2: showing help for the 1st function, calling show-user -h:

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

Case 3: chowing help for the 1st function, calling create-user -h:

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

Case 4: calling my app without param shows this:

wanna show the help here

My question is simple:

How to show the help when I run my CLI tool without params (Case 4)?

I guess that I need to add custom code into the HelloCli.call() method with a loop that collects the help texts from the two classes that implement the functions. But not sure how. I have not found any sample code for this popular use case.

My additional question is similar to the first one: Can I show somehow the full help that is shown together everything from Case 2 and Case 3?


Solution

  • This is documented in the section on subcommands, Making Subcommands Required.

    Essentially, do not implement Callable or Runnable in the top-level command. This makes it mandatory for end users to specify a subcommand. The manual has an example.

    About your second question, how to customize the usage help message, please take a look at the picocli-examples module of the picocli GitHub project. A lot of the examples are about custom help. For example, this one shows the full hierarchy of subcommands (and sub-subcommands) in the usage help of the top-level command.