kimathie
kimathie

Reputation: 426

How to create a command with at least one option

I'd like to create a command that allows for the user to specify one of the available options to execute a command. For example herein is a list of services and the command is status. The user can issue the a command 'status --list scarlet garnet cardinal' for a partial set or 'status --all' for a complete set of services. I have implemented the following :

@Command(name = "status", description = "checks the status of a service")
public void status(
        @Option(names = "--all", description = "checks all services.") boolean all,
        @Option(names = "--list", arity = "0..1", description = "checks specified services.") boolean list,
        @Parameters(paramLabel = "<service>", description = "a list of service names") List<String> services) {
    if (all) {
        System.out.println("check all");
    } else if (list) {
        System.out.println("check listed");
    }
}

It works, however there's a bug, that is, if a user just supplies the command only "status" without any further arguments it is considered valid. I believe this happens because both options are boolean. How do we rectify this to have at least one of the optional options provided ?

Upvotes: 1

Views: 128

Answers (1)

Remko Popma
Remko Popma

Reputation: 36754

I think you can get the desired behaviour by changing the --list option from a boolean to an array or collection of Strings.

For example:

@Command(name = "status", description = "checks the status of a service")
public void status(
        @Option(names = "--all", description = "checks all services.") boolean all,
        @Option(names = "--list", arity = "1..*", paramLabel = "<service>",
                description = "checks specified services.") List<String> services) {
    if (all) {
        System.out.println("check all");
    } else if (services != null && !services.isEmpty()) {
        System.out.println("check listed");
    }
}

If the options are mutually exclusive, you can use an ArgGroup.

But perhaps the simplest solution for this case is to have no options, only a list of services to check. If the user does not specify a service, then the app would check all services.

In code:

@Command(name = "status",
  description = "Checks the status of all services, or only the specified services.")
public void status(
        @Parameters(paramLabel = "<service>", arity = "0..*",
                    description = "A list of service names. Omit to check all services.") 
        List<String> services) {
    if (services == null || services.isEmpty()) {
        System.out.println("check all");
    } else {
        System.out.println("check listed");
    }
}

Upvotes: 1

Related Questions