Search code examples
command-line-argumentspicocli

Customized help display in PicoCli?


I have a use case where I need to post the entire help for a CLI in a specified format. I have found a way to do that using the following:


@CommandLine.Command(name="myAp",
        synopsisSubcommandLabel = "", usageHelpWidth = 120,
        commandListHeading = "",
        customSynopsis =  "\n\nArguments for MyApp operation.\n"
                + "\n"
                + "Operations:\n"
                + "    create                 Create the stuff\n"
                + "    list                   List the stuff\n"
                + "    add                    Add things\n"
                + "        -r --type                  One or both of [Type1, Typ2]\n"
                + "        -a --annualCost            AnnualCost\n"
                + "        -n --number                Number of each type thing\n"
                + "    subtract               Subtract things\n"
                + "        -r --reasons               Combination of\n"
                + "                                        fiscal (fiscal reason)\n"
                + "                                        operational (operational reason\n"
                + "                                        other (other reason)\n"
                + "    -h      Display this help message and exit\n"
)
class PicoCliParser {
    // All of my other Parameters and options here

    @Option(names = { "-h", "--help" }, usageHelp = true, hidden = true)
    boolean helpRequested = false;

    public static void main(String[] args) throws Exception {
        PicoCliParser parser = new PicoCliParser();
        CommandLine cmd = new CommandLine(parser);
        try {
            CommandLine.ParseResult parseResult = cmd.parseArgs(args);
            System.err.println("parseResults: " + parseResult.matchedArgs().toString());
            if (cmd.isUsageHelpRequested()) {
                cmd.usage(System.out);
            }
        } catch (CommandLine.ParameterException e) {

        }

    }
}

If the user enters -h or --help, the help prints out in the format that I want, If they do not enter -h or -H it doesn't.

Is there a better way to do this?

If we add additional commands in the future, then whoever adds them has to remember to update the help string.


Solution

  • Your solution works, but has the drawback (like you mentioned) that the usage help message is static and won't reflect future updates like new subcommands or options being added.

    Picocli does provide a way to customize the usage help message dynamically via its Help API. This allows you to reorder or replace sections in the usage help message. I believe the section you want to replace is the command list section.

    This will require a bit of a deep dive into the picocli usage help model. To help you get started, the picocli-examples module has some custom help examples. This example shows how to modify the usage help message to show the full command hierarchy (without options though), which is fairly close to what you want to do. You could take it as a starting point. If you have more questions feel free to raise tickets on the picocli github issue tracker (or here).