-
Notifications
You must be signed in to change notification settings - Fork 418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Need documentation for how to handle custom parameter validation #1147
Comments
Hi @LorenKeagle glad to hear you like picocli! To answer your questions:
Picocli currently does not have this feature. Applications will need to do custom validation in the business logic (see below).
There are two ways to do this: throw a @Command(name = "myapp", mixinStandardHelpOptions = true, version = "myapp 0.1")
class MyApp implements Runnable {
@Option(name="--xml") List<File> xmlFiles;
@Option(name="--log") List<File> logFiles;
@Option(name="--report-name") List<String> reportNames;
@Option(name="--report-id") List<int> reportIDs;
@Spec private CommandSpec spec; // injected by picocli
public static void main(String... args) {
System.exit(new CommandLine(new MyApp()).execute(args));
}
public void run() {
validate();
// business logic here
}
private void validate() {
if (missing(xmlFiles) && missing(logFiles) && missing(reportNames) && missing(reportIDs)) {
throw new ParameterException(spec.commandLine(),
"Missing option: at least one of the '--xml', '--log', '--report-name', or '--report-id' options must be specified.");
}
}
private void missing(List<?> list) {
return list == null || list.isEmpty();
}
} Throwing a
Picocli cannot do this automatically, so the question is how to do this manually. This is an interesting problem.
... but I am not sure this expresses your intention very well.
That is correct.
Yes, that is a different way to design things, with different trade-offs. |
Thank you for the response. The example of how to use the combination of the ParameterException and CommandSpec is exactly what I was looking for. As for the ArgGroup discussion, I believe the design is good from the perspective of exclusive and dependent option groups. My concern was more regarding the organization of options in the usage text, as opposed to the validation functionality. While I may want to be able to express the relationships between options in terms of mutual exclusivity and dependency, I may also want to organize options in the help text according to their related functionality. I suppose in many cases, subcommands could be a natural mechanism to isolate things, but that doesn't fit my use case. In the meantime, I have different option sets for different vendor interoperability that I want to have grouped in the help text, but some of those options need to have their own mutual dependencies with other global options. I'll work my way up to learning how to organize subcommands eventually, but it would take some thinking to redesign the tool entirely around that concept. I'm just getting started on this port from Commons CLI. |
I see what you mean now, thanks for the clarification! It is possible to customize the options list programmatically using the Help API, see this example and this example but this is quite a bit more complicated than the annotations-based approach with Argument Groups. If my understanding is correct your question has been answered, so if it is okay with you I will close this ticket. |
Reopening: let's take this opportunity to add a section about Validation to the user manual. |
I added a section on on Validation to the user manual. |
Picocli 4.5.1 has been released, with the updated user manual. Don't forget to star ⭐ picocli on GitHub if you like the project! 😉 |
First of all, thanks for this tool. It is a huge improvement over Commons CLI!
However, I was expecting some of the custom option validation that I had written for CLI to be supported using PicoCLI.
I have an application that accepts several different types of input, i.e. XML files, log files, report names, report ids. These are each implemented as Options, so they can individually be collected in lists:
@option(name="--xml") List xmlFiles;
@option(name="--log") List logFiles;
@option(name="--report-name") List reportNames;
@option(name="--report-id") List reportIDs;
These are neither mutually exclusive, nor dependent. I just need to validate that at least one input is provided to the app, and print the usage/help output otherwise. I can't find a way to do this, and there are no examples on how to add this validation into my business logic.
So my questions are:
A second, related issue is that each of the options in the example above are already part of their own ArgGroups (with validate=false), so that I can keep them organized with other related flags in the help usage. I do not believe that I can include an option in multiple ArgGroups (please correct me if I am wrong!). Wouldn't it be better to be able to provide a groupName="foo" parameter in the Options attribute to collect items together, so that Options validation can be separated from the organization in the help usage?
The text was updated successfully, but these errors were encountered: