Skip to content

Commit

Permalink
[#1815] DOC: Improve user manual section for non-validating ArgGroups
Browse files Browse the repository at this point in the history
Closes #1815
  • Loading branch information
remkop committed Dec 24, 2022
1 parent 612e301 commit d70cc29
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 3 deletions.
3 changes: 2 additions & 1 deletion RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ Artifacts in this release are signed by Remko Popma (6601 E5C0 8DCC BB96).
* [#1881] DOC: Many documentation improvements. Thanks to [Andreas Deininger](https://github.com/deining) for the pull request.
* [#1855][#1857] DOC: Add new user manual section called [Rare Use Cases](https://picocli.info/#_rare_use_cases) detailing `System.exit` usage. Thanks to [Tadaya Tsuyukubo](https://github.com/ttddyy) for the pull request.
* [#1880] DOC: Improve documentation for negatable options that are true by default. Thanks to [Sebastian Hoß](https://github.com/sebhoss) for raising this.

* [#1815] DOC: Improve user manual section for non-validating ArgGroups. Thanks for [Paul Harris](https://github.com/rolfyone) for raising this.
*


## <a name="4.7.1-deprecated"></a> Deprecations
Expand Down
26 changes: 26 additions & 0 deletions docs/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3082,6 +3082,32 @@ The ordering of group option sections can be controlled with the `order` attribu
@ArgGroup(heading = "Last%n", order = 3) lateinit var section3: Section3
----

==== Validation Trade-offs
Note that setting `validate = false` means that picocli won't validate user input for the group.
For example, even for groups with `multiplicity = 1`, when the end user specifies the group multiple times, no error is shown.
If the group is a single-value field, only the last occurrence is stored and previous occurrences are silently dropped.

If validation is needed, the recommendation is to make the field holding the group a collection, and doing <<Custom Validation>>. For example to ensure that this collection holds only a single element:


.Java
[source, java,role="primary"]
----
@ArgGroup(validate = false, heading = "This is the first section%n", multiplicity = "0..1")
private List<Section1> section1List = new ArrayList<>();
@Spec CommandSpec spec;
// validate in the business logic
public void run() {
if (section1List.size() > 1) {
throw new ParameterException(spec.commandLine(),
"Group [-a=<a>] [-b=<b>] [-c=<c>] can be specified at most once.");
}
// remaining business logic...
}
----

=== Repeating Composite Argument Groups

The below example shows how groups can be composed of other groups, and how arrays and collections can be used to capture repeating groups (with a `multiplicity` greater than one):
Expand Down
33 changes: 31 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2529,9 +2529,9 @@ <h3 id="_annotation_processor"><a class="anchor" href="#_annotation_processor"><
<p><strong>Compile time error checking</strong>. The annotation processor shows errors for invalid annotations and attributes immediately when you compile, instead of during testing at runtime, resulting in shorter feedback cycles.</p>
</li>
<li>
<p><strong><a href="#_graalvm_native_image">GraalVM native images</a></strong>. The annotation processor generates and updates <a href="https://www.graalvm.org/22.2/reference-manual/native-image/overview/BuildConfiguration/">GraalVM configuration</a> files under
<p><strong><a href="#_graalvm_native_image">GraalVM native images</a></strong>. The annotation processor generates and updates <a href="https://www.graalvm.org/latest/reference-manual/native-image/overview/BuildConfiguration/">GraalVM configuration</a> files under
<code>META-INF/native-image/picocli-generated/$project</code> during compilation, to be included in the application jar.
This includes configuration files for <a href="https://www.graalvm.org/22.2/reference-manual/native-image/dynamic-features/Reflection/">reflection</a>, <a href="https://www.graalvm.org/22.2/reference-manual/native-image/dynamic-features/Resources/">resources</a> and <a href="https://www.graalvm.org/22.2/reference-manual/native-image/dynamic-features/DynamicProxy/">dynamic proxies</a>.
This includes configuration files for <a href="https://www.graalvm.org/latest/reference-manual/native-image/dynamic-features/Reflection/">reflection</a>, <a href="https://www.graalvm.org/latest/reference-manual/native-image/dynamic-features/Resources/">resources</a> and <a href="https://www.graalvm.org/latest/reference-manual/native-image/dynamic-features/DynamicProxy/">dynamic proxies</a>.
By embedding these configuration files, your jar is instantly Graal-enabled.
In most cases no further configuration is needed when generating a native image.</p>
</li>
Expand Down Expand Up @@ -6149,6 +6149,35 @@ <h4 id="_option_section_order"><a class="anchor" href="#_option_section_order"><
</div>
</div>
</div>
<div class="sect3">
<h4 id="_validation_trade_offs"><a class="anchor" href="#_validation_trade_offs"></a>8.3.3. Validation Trade-offs</h4>
<div class="paragraph">
<p>Note that setting <code>validate = false</code> means that picocli won&#8217;t validate user input for the group.
For example, even for groups with <code>multiplicity = 1</code>, when the end user specifies the group multiple times, no error is shown.
If the group is a single-value field, only the last occurrence is stored and previous occurrences are silently dropped.</p>
</div>
<div class="paragraph">
<p>If validation is needed, the recommendation is to make the field holding the group a collection, and doing <a href="#_custom_validation">Custom Validation</a>. For example to ensure that this collection holds only a single element:</p>
</div>
<div class="listingblock primary">
<div class="title">Java</div>
<div class="content">
<pre class="rouge highlight"><code data-lang="java"><span class="nd">@ArgGroup</span><span class="o">(</span><span class="n">validate</span> <span class="o">=</span> <span class="kc">false</span><span class="o">,</span> <span class="n">heading</span> <span class="o">=</span> <span class="s">"This is the first section%n"</span><span class="o">,</span> <span class="n">multiplicity</span> <span class="o">=</span> <span class="s">"0..1"</span><span class="o">)</span>
<span class="kd">private</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Section1</span><span class="o">&gt;</span> <span class="n">section1List</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;&gt;();</span>

<span class="nd">@Spec</span> <span class="nc">CommandSpec</span> <span class="n">spec</span><span class="o">;</span>

<span class="c1">// validate in the business logic</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">run</span><span class="o">()</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">section1List</span><span class="o">.</span><span class="na">size</span><span class="o">()</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="o">)</span> <span class="o">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">ParameterException</span><span class="o">(</span><span class="n">spec</span><span class="o">.</span><span class="na">commandLine</span><span class="o">(),</span>
<span class="s">"Group [-a=&lt;a&gt;] [-b=&lt;b&gt;] [-c=&lt;c&gt;] can be specified at most once."</span><span class="o">);</span>
<span class="o">}</span>
<span class="c1">// remaining business logic...</span>
<span class="o">}</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_repeating_composite_argument_groups"><a class="anchor" href="#_repeating_composite_argument_groups"></a>8.4. Repeating Composite Argument Groups</h3>
Expand Down

0 comments on commit d70cc29

Please sign in to comment.