-
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
Mixing multiplicity or required + non-required options in an exclusive ArgGroup gives unexpected results #871
Comments
Thanks again for raising this. I will need some time for this. |
No problem at all, please take your time! Again I really appreciate your work here :) |
I would really like to see that or, even more restrictive, (optionally) specify a single argument that starts a new group (all other args would be pushed into the previous group). An example use-case is our connectomics visualization and proof-reading tool Paintera. N5 datasets can be added through the picocli CLI by specifying a container and one ore more datasets inside that container:
It would make sense here to start a new group only with the
In practice, this will not happen (a lot) because users will probably intuitively specify the container first, but I think it may be confusing if they accidentally do so. |
@hanslovsky I suspect that Paintera is a good use case for repeating subcommands. #454 is on the todo list for picocli 4.2. @wjohnson5 sorry for my late reply, I had other commitments that took my time. In the context of mutually dependent groups (where all options must co-occur), the notion of optional and required options makes sense. It is useful to be able to define a group as However, what does it mean if an option is not required in an exclusive group? Using the corresponding example: I think the simplest thing to do, both from an implementation/maintenance perspective, but also from a usability perspective, is to make all options required in exclusive groups. To ease migration, we can silently make the default to be The example you mention in example 4 looks like a bug. If the max multiplicity is greater than 1, a new group should be created for each option in the exclusive group. |
That makes sense to me. |
…ered `required`, to prevent unexpected results when mixing required and non-required options in exclusive ArgGroups.
Fixed and included in the 4.1.2 release. After enforcing all options to be Please verify when you get a chance. I also updated the documentation for exclusive and non-exclusive groups to note the use of required options. Feedback welcome! |
Related to #870
Tested with latest master. Using multiplicity="0..*" and
exclusive = true
with an ArgGroup, orexclusive = true
with an ArgGroup that has both optional and required parameters gives unexpected results.cli --opt=1
results in one group:{name=null, opt=1}
. Even though no required options are provided, validation passes.cli --name=foo --opt=1
givesError: --name=<name>, --opt=<opt> are mutually exclusive (specify only one)
. Even though --opt is optional, it's still exclusive with --name.cli --opt=1 --name=foo
works and results in[{name=null, opt=1},{name=foo, opt=null}]
. Whoa, switching the arg order makes it work? It still seems to be exclusive, but for some reason now it knows to create a second group.cli --name=foo --id=bar
givesError: --name=<name>, --id=<id> are mutually exclusive (specify only one)
. This seems like a bug. Those should be two valid groups, right?{name=foo, id=null}
and{name=null, id=bar}
? Why doesn't it create a second group now?I'd think, either (1) only the required arguments are exclusive, and it's still an error to specify an ArgGroup option without exactly one of the required args, as in #870, or maybe (2) picocli should just immediately error out if using non-required options w/ exclusive = True. I'm leaning heavily toward (1).
In general, I think the logic should be:
(1) Attempt to fit an arg into the previous group, unless it makes the group invalid. *
(2) If a new arg cannot be fit into the previous group, start a new group with it, and validate the (now completed) previous group.
(3) Now that a new group is started, check if the new number of groups > max multiplicity.
(4)
exclusive
simply changes the validation of required options in a group.exclusive=true
means exactly 1 of the required options per group, andexclusive=false
means all of the required options per group. Not specifying any required options should always be invalid.Max multiplicity=1 can be a special case, where we know not to start a new group so the error message is clearer: "--foo, --bar are mutually exclusive"
* Consider making it so that only required args can start a new group. Optional args would always be pushed into the previous group, triggering a validation error if, for example, providing too many of that optional arg, and it would be illegal to start with an optional arg. This makes it always obvious which group an optional arg belongs to:
cli --req --opt --opt --req --req --opt --req
-> always{req, opt, opt}, {req}, {req, opt}, {req}
. Currently, it's{req, opt}, {opt, req}, {req, opt}, {req}
if opt is singular, but{req, opt, opt}, {req}, {req, opt}, {req}
if opt is repeatable.The text was updated successfully, but these errors were encountered: