change arity of parameters based on options ?

6 views
Skip to first unread message

mand...@redhat.com

unread,
Feb 6, 2022, 7:04:44 PM2/6/22
to picocli
Hey,

Trying to figure out how best to do the following in jbang:

Normally jbang has a parameter:

@CommandLine.Parameters(index = "0", arity = "1", description = "A file with java code or if named .jsh will be run with jshell")
String scriptOrFile;
 

meaning for all cases a file is required.

Now, I would like to add an option `-i` which says - no need to have a file and enter interactive mode.

How would you go about adding such option that mades the arity 0 for "scriptOrFile" but otherwise should be arity 1 ?


Remko Popma

unread,
Feb 6, 2022, 8:13:07 PM2/6/22
to picocli
The simplest thing to do is to change the arity of the positional parameter from 1 to "0..1" and do the validation in the logic of the command.

The implementation of this validation could look like this:

```java 
@Spec CommandSpec spec;

public void run() { // or call 
  if (!interactive && scriptOrFile == null) {
    throw new ParameterException(spec.commandLine(),
        "Missing required file with Java code.");
  }
```

I would also change the description of the positional parameter  to add a sentence like "Ignored when --interactive is specified."


--
You received this message because you are subscribed to the Google Groups "picocli" group.
To unsubscribe from this group and stop receiving emails from it, send an email to picocli+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/picocli/a69e05f6-2140-4709-847a-55a160d6994en%40googlegroups.com.

Max Rydahl Andersen

unread,
Feb 7, 2022, 3:52:00 AM2/7/22
to Remko Popma, picocli

Hi Remko,

The issue is that the help now makes it show as not required when it really is for 99% of cases....but I guess I can't have it all :)

/max

Andres Almiray

unread,
Feb 7, 2022, 4:24:01 AM2/7/22
to Max Rydahl Andersen, Remko Popma, picocli
Hi Max,

I use composite with include and exclude sections. JReleaser release command shows how it can be done. —auto-config and all other options related to it are exclusive from the “main” use case. No custom validation logic was needed in this way. 

Remko Popma

unread,
Feb 7, 2022, 5:42:08 PM2/7/22
to Andres Almiray, Max Rydahl Andersen, picocli
Max,

Other than Andres' solution, if the issue is that the synopsis now shows `command -xyz [<scriptOrFile>]`, 
where you want to show `command -xyz <scriptOrFile>`, there are several solutions.

The simplest solution is to use a custom synopsis (https://picocli.info/#_custom_synopsis).
This has the drawback that any subsequent changes require you to also update the custom synopsis, which is fragile.

A less simple solution is to parse in two phases, similar to what is documented here: https://picocli.info/#_controlling_the_locale
The idea is that you use the first phase to determine whether the --interactive flag was set, and depending on that
you would create a different model (e.g. add the `scriptOrFile` positional parameter or leave it out, or something like that.)
This is quite a bit of work though...

Another option is to just live with the truth. :-)
If the `scriptOrFile` positional parameter is not mandatory in 1% of the cases, it is not always mandatory.
And the description of the `scriptOrFile` positional parameter and the --interactive option could clarify when the positional parameter becomes mandatory.

Hope this helps,
:-)
Remko

Reply all
Reply to author
Forward
0 new messages