Как создать команду хотя бы с одним параметром

Я хотел бы создать команду, которая позволяет пользователю указать одну из доступных опций для выполнения команды. Например, здесь приведен список услуг, а команда — это статус. Пользователь может ввести команду 'status --list scarlet garnet cardinal' для частичного набора или 'status --all' для полного набора услуг. Я реализовал следующее:

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

Это работает, однако есть ошибка, то есть, если пользователь просто указывает команду только status без каких-либо дополнительных аргументов, она считается действительной. Я считаю, что это происходит потому, что оба параметра являются логическими. Как мы можем исправить это, чтобы иметь хотя бы одну из дополнительных опций?


person kimathie    schedule 11.02.2021    source источник
comment
используйте некоторые проверки if, если нет других, выдайте исключение   -  person Stultuske    schedule 11.02.2021
comment
Ну, это был мой последний шанс, однако я надеялся на решение, которое будет использовать функции пикокли.   -  person kimathie    schedule 11.02.2021


Ответы (1)


Я думаю, вы можете получить желаемое поведение, изменив параметр --list с логического на массив или набор строк.

Например:

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

Если параметры являются взаимоисключающими, вы можете использовать ArgGroup.

Но, пожалуй, самое простое решение для этого случая — не иметь никаких опций, а только список сервисов для проверки. Если пользователь не укажет службу, приложение проверит все службы.

В коде:

@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");
    }
}
person Remko Popma    schedule 12.02.2021
comment
Большое спасибо, это действительно полезно. Мне очень нравится простое решение, как я до такого не додумался!! - person kimathie; 12.02.2021
comment
Привет, Ремко, я забыл упомянуть, что в вашем простом решении, когда List‹String› Services не имеет значений, он завершается как нуль, и поэтому .isEmpty генерирует исключение NullPointerException. - person kimathie; 12.04.2021
comment
@kimatie Спасибо, что указали на это! Я обновил свой ответ. - person Remko Popma; 12.04.2021