3

I have a command with subcommands. In my application I want it mandatory for the user to specify a subcommand. How should I do this?

(See also https://github.com/remkop/picocli/issues/529)

Remko Popma
  • 35,130
  • 11
  • 92
  • 114

1 Answers1

6

Update: this is now documented in the picocli manual: https://picocli.info/#_required_subcommands


Prior to picocli 4.3, the way to achieve this would be to show an error or throw a ParameterException if the top-level command is invoked without subcommand.

For example:

    @Command(name = "top", subcommands = {Sub1.class, Sub2.class},
             synopsisSubcommandLabel = "COMMAND")
    class TopCommand implements Runnable {

        @Spec CommandSpec spec;

        public void run() {
            throw new ParameterException(spec.commandLine(), "Missing required subcommand");
        }

        public static void main(String[] args) {
            CommandLine.run(new TopCommand(), args);
        }
    }

    @Command(name = "sub1)
    class Sub1 implements Runnable {
        public void run() {
            System.out.println("All good, executing Sub1");
        }
    }

    @Command(name = "sub2)
    class Sub2 implements Runnable {
        public void run() {
            System.out.println("All good, executing Sub2");
        }
    }

From picocli 4.3, this can be accomplished more easily by making the top-level command not implement Runnable or Callable.

If the command has subcommands but does not implement Runnable or Callable, picocli will make subcommands mandatory.

For example:

@Command(name = "top", subcommands = {Sub1.class, Sub2.class},
         synopsisSubcommandLabel = "COMMAND")
class TopCommand {
    public static void main(String[] args) {
        CommandLine.run(new TopCommand(), args);
    }
}
Remko Popma
  • 35,130
  • 11
  • 92
  • 114
  • As @david-wikler correctly noted, the auto-generated synopsis in the usage help message would still show the command as optional within `[` and `]` brackets, so this is not a perfect solution. A workaround for this is to provide a custom synopsis, see https://picocli.info/#_custom_synopsis for details. – Remko Popma Dec 08 '18 at 22:13
  • How does this solution help if you actually want your TopCommand to run? For example, to receive command options that are applicable to all subcommands? This solution seemingly bypasses the main commands to receive options? – taftster Feb 28 '19 at 08:48
  • To let your subcommands access options from the top-level command, you don't actually need to `run` your top-level command. Instead, you probably want to use the `@ParentCommand` annotation. See the user manual for an example: https://picocli.info/#__code_parentcommand_code_annotation – Remko Popma Feb 28 '19 at 09:49