You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Required ArgGroup combined with DefaultValueProvider issue #1848
This usually works as expected, with picocli requiring at least the --url option and the other options being optional, with a synopsis like the following: (--url=<url> [--proxy-host=<proxyHost>] [--proxy-port=<proxyPort>] [--proxy-user=<proxyUser>] [--proxy-password]... [-k])
However, if we configure a global default value provider (in our case retrieving default values from environment variables), the synopsis changes to the following, indicating that --url is now optional: ([--url=<url>] [--proxy-host=<proxyHost>] [--proxy-port=<proxyPort>] [--proxy-user=<proxyUser>] [--proxy-password]... [-k])
Due to multiplicitly = "1" on the ArgGroup, picocli still requires at least one of the options in the ArgGroup to be specified on the command line, even though the required --url option is already being satisfied through the default value provider.
privatebooleancontainsRequiredOptions(ArgGroupSpecargGroupSpec) {
for ( OptionSpecoption : argGroupSpec.options() ) {
if ( option.required() ) { returntrue; }
}
returnfalse;
}
Call this new method in the GroupMatchContainer::validate method:
if (missing.validate() && missing.multiplicity().min > 0 && containsRequiredOptions(missing) ) {
I'm not sure though whether there's any valid use case for having multiplicity = "1" on an ArgGroup that has only optional options. If that's the case, maybe we should add a new attribute to the ArgSpec annotation to indicate that it's not required if it contains only non-required options. Any suggestions for the name for this attribute, if necessary?
@remkop Any comments on this? Because of this issue, our project still needs to use a patched version of the CommandLine class; preferably we would like to start using an official picocli release in the near future.
Hey @remkop. Sorry for the delay here, but I'll be submitting a PR soon with the fix from @rsenden and the associated unit test.
I have three questions for you though:
For the unit test, I've put it in DefaultProviderTest.java. I have doubts that this is the best location to put the unit test in, so if you want the unit test placed in some other location, please let me know.
I've noticed that for command options which are a part of an ArgGroup, they are unable to receive a default value via DefaultValueProvider. Is this expected behavior? I tried looking through the tests in both DefaultProviderTest.java and ArgGroupTest.java that test for ArgGroup options receiving a default value via DefaultValueProvider, but I didn't see any. If feel this is unexpected behavior, then I'll create a new issue. Or if you suspect that I might be doing something wrong, then I welcome any guidance you can provide.
I've noticed that for a required option which could possibly have a default value supplied via DefaultValueProvider, the help/synopsis usage information could change for that one specific option, from being required to optional. Using the example that @rsenden used earlier:
If the default value provider class returns null for a required option, then the help/usage output will look like the following: (--url=<url> ...)
But if a non-null value is returned for that required option then the help/usage output will look like: ([--url=<url>] ...)
Maybe this last thing (my 3rd question) is a non-issue. But I figured that maybe options explicitly set to required = true should always be shown as a required option in the help/usage output, regardless if DefaultValueProvider is able to provide a value or not. What do you think?
Hello @remkop and @rsenden .
I think that the initially proposed fix needs to be updated slightly as I noticed that it was causing the unit test testIssue1027RepeatingPositionalParamsWithMinMultiplicity to fail as the fix doesn't check for positional parameters. PR #2030 has been raised with the updated fix and unit test. Please let me know if you see any issues.
Hello @remkop. Apologies, but on further testing, we're finding out that the PR we submitted (#2030) for this issue doesn't cover all scenarios. I'd like to request for this issue to be reopened. We've created a new fix for which we'll be submitting a new PR for. I'm just evaluating the existing unit test to see if it's sufficient before raising the next PR.
Hi @wtfacoconut and @rsenden, it looks like #2030 has caused a regression:
when an arg-group has multiplicity=1, then picocli should require that at least one of the options in the group is specified.
See #2059: the test case in #947 now no longer works... (I should have added that test to the ArgGroupTest class, apologies.)
This conflicts with your expectations in the description for this ticket.
One idea is to revert the changes made in #2030, and satisfy your requirements by changing your application: change the UrlConfigOptions group to have multiplicity = "0..1" (and if necessary validate that the url option has a default).
Hey @remkop, @rsenden. I am currently handling some family related matters. I noticed this issue as well but won't be able to update untill the day after tomorrow.
Essentially what needs to happen is that our check needs to be updated to handle required parameters.
Essentially what needs to happen is that our check needs to be updated to handle required parameters.
I am not sure that the problem is really related to required options/parameters:
note that the test case in #947 has two non-required options, and we still want picocli to show a "missing option" error when none of these options are specified because the group's multiplicity is 1. The idea is that the user must specify one or both of these options, but omitting all options should trigger an error.
I am not sure how that squares with the description of this ticket (#1848), where you don't want that error (because the required option has a default value). To be honest I am not sure yet what the solution is. One idea is to model the multiplicity of the UrlConfigOptions group in your application as "0..1". There may be other ideas.
But it does appear that #2030 introduced a regression, and some change is needed to make the test in #947 pass again.
Hello @remkop, I'm fully back on line now. I used the unit test that you provided in #947 to reproduce the issue that you mentioned.
Are you saying that you're "not sure yet what the solution is" because there are some potentially deeper issues/implications, or something?
Also, in the cotext of the unit test that you wrote for #947, would it be a reasonable expectation to have ArgGroups with a multiplicity of 1, recognize default values for options (provided by either an annotation or default value provider class), so that it doesn't cause an error about a missing option/value?
First (and this is an aside), looking at a question in an earlier comment:
I've noticed that for command options which are a part of an ArgGroup, they are unable to receive a default value via DefaultValueProvider. Is this expected behavior? I tried looking through the tests in both DefaultProviderTest.java and ArgGroupTest.java that test for ArgGroup options receiving a default value via DefaultValueProvider, but I didn't see any. If feel this is unexpected behavior, then I'll create a new issue. Or if you suspect that I might be doing something wrong, then I welcome any guidance you can provide.
This is not expected behaviour. I don't see why options/positional params in a group should not be able to get default values via DefaultValueProvider... If this is still the case please raise a separate ticket.
Back to the main topic:
I just pushed a change to improve the solution introduced in [4b41a21] by adding support that allows detecting whether an ArgSpec's value came from a default value or from the command line.
Can you review?
Activity
rsenden commentedon Oct 17, 2022
The following changes fix this issue in our application:
Add method
GroupMatchContainer::containsRequiredOptions:Call this new method in the
GroupMatchContainer::validatemethod:I'm not sure though whether there's any valid use case for having
multiplicity = "1"on anArgGroupthat has only optional options. If that's the case, maybe we should add a new attribute to theArgSpecannotation to indicate that it's not required if it contains only non-required options. Any suggestions for the name for this attribute, if necessary?rsenden commentedon Oct 17, 2022
Actually, the above didn't work well for a nested tree of
ArgGroups, where some of theArgGroupshaveexclusive = true.The following updates to
GroupMatchContainerseem to work much better:The
containsRequiredSubgroupsmethod could be improved, but first want to get your opinion on this approach.rsenden commentedon Nov 23, 2022
@remkop Any comments on this? Because of this issue, our project still needs to use a patched version of the
CommandLineclass; preferably we would like to start using an official picocli release in the near future.remkop commentedon Nov 23, 2022
The last attempt that handles both options and subgroups looks good. Can you provide a PR with tests?
MikeTheSnowman commentedon May 23, 2023
Hey @remkop. Sorry for the delay here, but I'll be submitting a PR soon with the fix from @rsenden and the associated unit test.
I have three questions for you though:
For the unit test, I've put it in
DefaultProviderTest.java. I have doubts that this is the best location to put the unit test in, so if you want the unit test placed in some other location, please let me know.I've noticed that for command options which are a part of an ArgGroup, they are unable to receive a default value via
DefaultValueProvider. Is this expected behavior? I tried looking through the tests in bothDefaultProviderTest.javaandArgGroupTest.javathat test for ArgGroup options receiving a default value viaDefaultValueProvider, but I didn't see any. If feel this is unexpected behavior, then I'll create a new issue. Or if you suspect that I might be doing something wrong, then I welcome any guidance you can provide.I've noticed that for a required option which could possibly have a default value supplied via DefaultValueProvider, the help/synopsis usage information could change for that one specific option, from being required to optional. Using the example that @rsenden used earlier:
(--url=<url> ...)([--url=<url>] ...)Maybe this last thing (my 3rd question) is a non-issue. But I figured that maybe options explicitly set to
required = trueshould always be shown as a required option in the help/usage output, regardless if DefaultValueProvider is able to provide a value or not. What do you think?MikeTheSnowman commentedon May 25, 2023
Hello @remkop and @rsenden .
I think that the initially proposed fix needs to be updated slightly as I noticed that it was causing the unit test
testIssue1027RepeatingPositionalParamsWithMinMultiplicityto fail as the fix doesn't check for positional parameters. PR #2030 has been raised with the updated fix and unit test. Please let me know if you see any issues.remkop commentedon May 25, 2023
@wtfacoconut @rsenden I will try to get to this soon.
MikeTheSnowman commentedon May 25, 2023
Roger that, take your time. 🙂
[#2026][#2027][#2029][#2034][#2035][#2036][#1848][#2030] update RELEA…
[#1848][#2030] replace Java 6 API with Java 5 API
MikeTheSnowman commentedon Jul 6, 2023
Hello @remkop. Apologies, but on further testing, we're finding out that the PR we submitted (#2030) for this issue doesn't cover all scenarios. I'd like to request for this issue to be reopened. We've created a new fix for which we'll be submitting a new PR for. I'm just evaluating the existing unit test to see if it's sufficient before raising the next PR.
remkop commentedon Jul 6, 2023
Absolutely, no worries.
Just reference the issue and previous PR in the new PR.
Just a heads-up that I'll be traveling from Saturday for 2 weeks and I won't be taking my pc, so please be patient. 😅
MikeTheSnowman commentedon Jul 7, 2023
No worries! Enjoy your trip and bring me back a t-shirt. 😉
remkop commentedon Aug 5, 2023
Hi @wtfacoconut and @rsenden, it looks like #2030 has caused a regression:
when an arg-group has multiplicity=1, then picocli should require that at least one of the options in the group is specified.
See #2059: the test case in #947 now no longer works... (I should have added that test to the
ArgGroupTestclass, apologies.)This conflicts with your expectations in the description for this ticket.
One idea is to revert the changes made in #2030, and satisfy your requirements by changing your application: change the
UrlConfigOptionsgroup to havemultiplicity = "0..1"(and if necessary validate that theurloption has a default).Thoughts?
MikeTheSnowman commentedon Aug 5, 2023
Hey @remkop, @rsenden. I am currently handling some family related matters. I noticed this issue as well but won't be able to update untill the day after tomorrow.
Essentially what needs to happen is that our check needs to be updated to handle required parameters.
remkop commentedon Aug 5, 2023
Hi @wtfacoconut, thanks for the quick reply.
I am not sure that the problem is really related to required options/parameters:
note that the test case in #947 has two non-required options, and we still want picocli to show a "missing option" error when none of these options are specified because the group's multiplicity is 1. The idea is that the user must specify one or both of these options, but omitting all options should trigger an error.
I am not sure how that squares with the description of this ticket (#1848), where you don't want that error (because the required option has a default value). To be honest I am not sure yet what the solution is. One idea is to model the multiplicity of the
UrlConfigOptionsgroup in your application as "0..1". There may be other ideas.But it does appear that #2030 introduced a regression, and some change is needed to make the test in #947 pass again.
MikeTheSnowman commentedon Aug 24, 2023
Hello @remkop, I'm fully back on line now. I used the unit test that you provided in #947 to reproduce the issue that you mentioned.
Are you saying that you're "not sure yet what the solution is" because there are some potentially deeper issues/implications, or something?
Also, in the cotext of the unit test that you wrote for #947, would it be a reasonable expectation to have ArgGroups with a multiplicity of 1, recognize default values for options (provided by either an annotation or default value provider class), so that it doesn't cause an error about a missing option/value?
[#2059] ArgGroup fix regression and refine solution introduced in [#1848
[#2059] ArgGroup fix regression and refine solution introduced in [#1848
remkop commentedon Aug 26, 2023
Sorry for the late response.
First (and this is an aside), looking at a question in an earlier comment:
This is not expected behaviour. I don't see why options/positional params in a group should not be able to get default values via
DefaultValueProvider... If this is still the case please raise a separate ticket.Back to the main topic:
I just pushed a change to improve the solution introduced in [4b41a21] by adding support that allows detecting whether an
ArgSpec's value came from a default value or from the command line.Can you review?