Skip to content
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

1409 documentation tests #1463

Merged
merged 8 commits into from
Nov 16, 2021
54 changes: 54 additions & 0 deletions docs/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3138,6 +3138,60 @@ usage help shows the wrong default value
----
====

==== Default Values in Unreferenced Argument Groups
MadFoal marked this conversation as resolved.
Show resolved Hide resolved
When an argument group is defined with default values in the annotated fields, but during usage does not reference any of the arguments within the group, picocli will instantiate those objects to their declared values. However, picocli will instantiate the other objects to their default annotated values if a single argument within the argument group is defined.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is tricky to give a short and clear description of the problem we are trying to solve here... How about something like this?

If none of the options in an argument group is specified on the command line, picocli will not instantiate the user object for that group. So how does the application access default values for the group options? Essentially, the application needs to do some extra work for groups, that is not necessary for options outside of argument groups.

Then maybe follow this by a recommended usage (see also below).


.Java
[source,java,role="primary"]
----
@Command(name = "test", description = "demonstrates Default Value declaration")
class MyApp {
@ArgGroup Outer outer;

class Outer {
MadFoal marked this conversation as resolved.
Show resolved Hide resolved
@Options(names = "-x", defaultValue = "XX") String x;
@ArgGroup(exclusive = "true") Inner inner;
}

class Inner {
MadFoal marked this conversation as resolved.
Show resolved Hide resolved
@Options(names = "-a", defaultValue = "AA") String a = "AA";
@Options(names = "-b", defaultValue = "BB") String b = "BB";
}

public void run() {
if (outer == null) { // no options specified on command line; apply default values
outer = new Outer;
}
if (outer.inner == null) { // handle nested sub-groups; apply default for inner group
outer.inner = new Inner;
}
remkop marked this conversation as resolved.
Show resolved Hide resolved

// remaining business logic...
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
@Command(name = "test", description =["demonstrates Default Value declaration"])
class MyApp {
@ArgGroup lateinit var outer: Outer

class Outer {
@Options(names = "-x", defaultValue = "XX") lateinit var x: String()
@ArgGroup lateinit var inner: Inner
}

class Inner {
@Options(names = "-a", defaultValue = "AA") var a = "AA"
@Options(names = "-b", defaultValue = "BB") var b = "BB"
}

remkop marked this conversation as resolved.
Show resolved Hide resolved
}
----
In this example above, there are two cases why we need to write our class with both annotated and declared values. The first reason is that if we do not supply any arguments, the annotated "defaultValues" field will provide the instantiated value. The second reason is if we provide an "x" value but no "a" or "b" value, the variables use their declared value instead of the annotated value. Thus, in our example, by setting the annotated "defaultValue" and the declared value to the same default value, we ensure that we always have the correct default value for different combinations of arguments.
Copy link
Owner

@remkop remkop Nov 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be an idea to phrase this as a recommendation?
And maybe put it in before the example code, what do you think?

The recommended way to work with default values for options in groups is as follows:

  • ...
  • ...

Putting it all together, see the example below.



=== Positional Parameters

When a `@Parameters` positional parameter is part of a group, its `index` is the index _within the group_, not within the command.
Expand Down