Skip to content

Commit

Permalink
[#1566][#1571] DOC clarify use of variables in default values and ord…
Browse files Browse the repository at this point in the history
…ering between default values and default value provider
  • Loading branch information
remkop committed Feb 11, 2022
1 parent b9c65e4 commit f0262b4
Show file tree
Hide file tree
Showing 2 changed files with 221 additions and 86 deletions.
24 changes: 24 additions & 0 deletions docs/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1854,6 +1854,27 @@ Defining a default value by assigning a value at the field declaration has limit
* picocli's annotation processors can only detect default values in annotations, not in the field declaration. Your application may not work correctly with future features like documentation generated from the annotations.
====

=== Variables in Default Values
The default value itself may also contain <<Custom Variables, variables>>. For example:


.Java
[source,java,role="primary"]
----
@Option(names = "-c", defaultValue = "${COUNT:-123}")
int count;
----

.Kotlin
[source,kotlin,role="secondary"]
----
@Option(names = ["-c"], defaultValue = "\${COUNT:-123}")
lateinit count: int
----

Picocli will look up the value of the `COUNT` variable in the system properties, environment variables, and resource bundle, and finally use value `123` if no value is found for any of these lookups.


=== Default Provider
Finally, you can specify a default provider in the `@Command` annotation:

Expand Down Expand Up @@ -1897,6 +1918,9 @@ See the
https://github.com/remkop/picocli/blob/master/picocli-examples/src/main/java/picocli/examples/defaultprovider/[default provider examples]
for example implementations.

NOTE: If the command has a default provider configured, and the option or positional parameter has a default value configured, then picocli will first try to find the value in the default provider.
If the default provider has no value for that option or positional parameter, then the default value configured on the option or positional parameter is used.


=== PropertiesDefaultProvider
From picocli 4.1, applications can use the built-in `PropertiesDefaultProvider`
Expand Down
283 changes: 197 additions & 86 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1710,81 +1710,156 @@
});
});
</script>
<style>
.hidden {
display: none;
}

.switch {
border-width: 1px 1px 0 1px;
border-style: solid;
border-color: #7a2518;
display: inline-block;
}

.switch--item {
padding: 10px;
background-color: #ffffff;
color: #7a2518;
display: inline-block;
cursor: pointer;
}

.switch--item.selected {
background-color: #7a2519;
color: #ffffff;
}

</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
<script type="text/javascript">
function addBlockSwitches() {
$('.primary').each(function() {
primary = $(this);
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
primary.children('.title').remove();
});
$('.secondary').each(function(idx, node) {
secondary = $(node);
primary = findPrimary(secondary);
switchItem = createSwitchItem(secondary, primary.children('.switch'));
switchItem.content.addClass('hidden');
findPrimary(secondary).append(switchItem.content);
secondary.remove();
});
}

function createBlockSwitch(primary) {
blockSwitch = $('<div class="switch"></div>');
primary.prepend(blockSwitch);
return blockSwitch;
}

function findPrimary(secondary) {
candidate = secondary.prev();
while (!candidate.is('.primary')) {
candidate = candidate.prev();
}
return candidate;
}

function createSwitchItem(block, blockSwitch) {
blockName = block.children('.title').text();
content = block.children('.content').first().append(block.next('.colist'));
item = $('<div class="switch--item">' + blockName + '</div>');
item.on('click', '', content, function(e) {
$(this).addClass('selected');
$(this).siblings().removeClass('selected');
e.data.siblings('.content').addClass('hidden');
e.data.removeClass('hidden');
});
blockSwitch.append(item);
return {'item': item, 'content': content};
}

$(addBlockSwitches);

</script>
<style>

.hidden {

display: none;

}



.switch {

border-width: 1px 1px 0 1px;

border-style: solid;

border-color: #7a2518;

display: inline-block;

}



.switch--item {

padding: 10px;

background-color: #ffffff;

color: #7a2518;

display: inline-block;

cursor: pointer;

}



.switch--item.selected {

background-color: #7a2519;

color: #ffffff;

}



</style>

<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>

<script type="text/javascript">

function addBlockSwitches() {

$('.primary').each(function() {

primary = $(this);

createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");

primary.children('.title').remove();

});

$('.secondary').each(function(idx, node) {

secondary = $(node);

primary = findPrimary(secondary);

switchItem = createSwitchItem(secondary, primary.children('.switch'));

switchItem.content.addClass('hidden');

findPrimary(secondary).append(switchItem.content);

secondary.remove();

});

}



function createBlockSwitch(primary) {

blockSwitch = $('<div class="switch"></div>');

primary.prepend(blockSwitch);

return blockSwitch;

}



function findPrimary(secondary) {

candidate = secondary.prev();

while (!candidate.is('.primary')) {

candidate = candidate.prev();

}

return candidate;

}



function createSwitchItem(block, blockSwitch) {

blockName = block.children('.title').text();

content = block.children('.content').first().append(block.next('.colist'));

item = $('<div class="switch--item">' + blockName + '</div>');

item.on('click', '', content, function(e) {

$(this).addClass('selected');

$(this).siblings().removeClass('selected');

e.data.siblings('.content').addClass('hidden');

e.data.removeClass('hidden');

});

blockSwitch.append(item);

return {'item': item, 'content': content};

}



$(addBlockSwitches);



</script>


</head>
<body class="article toc2 toc-left">
Expand Down Expand Up @@ -1840,10 +1915,11 @@ <h1>picocli - a mighty tiny command line interface</h1>
<ul class="sectlevel2">
<li><a href="#defaultValue-annotation">5.1. <code>defaultValue</code> Annotation</a></li>
<li><a href="#_field_values">5.2. Field Values</a></li>
<li><a href="#_default_provider">5.3. Default Provider</a></li>
<li><a href="#_propertiesdefaultprovider">5.4. PropertiesDefaultProvider</a></li>
<li><a href="#fallbackValue-annotation">5.5. <code>fallbackValue</code> Annotation</a></li>
<li><a href="#_was_a_value_defaulted">5.6. Was a Value Defaulted?</a></li>
<li><a href="#_variables_in_default_values">5.3. Variables in Default Values</a></li>
<li><a href="#_default_provider">5.4. Default Provider</a></li>
<li><a href="#_propertiesdefaultprovider">5.5. PropertiesDefaultProvider</a></li>
<li><a href="#fallbackValue-annotation">5.6. <code>fallbackValue</code> Annotation</a></li>
<li><a href="#_was_a_value_defaulted">5.7. Was a Value Defaulted?</a></li>
</ul>
</li>
<li><a href="#_multiple_values">6. Multiple Values</a>
Expand Down Expand Up @@ -4491,7 +4567,30 @@ <h3 id="_field_values"><a class="anchor" href="#_field_values"></a>5.2. Field Va
</div>
</div>
<div class="sect2">
<h3 id="_default_provider"><a class="anchor" href="#_default_provider"></a>5.3. Default Provider</h3>
<h3 id="_variables_in_default_values"><a class="anchor" href="#_variables_in_default_values"></a>5.3. Variables in Default Values</h3>
<div class="paragraph">
<p>The default value itself may also contain <a href="#_custom_variables">variables</a>. For example:</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">@Option</span><span class="o">(</span><span class="n">names</span> <span class="o">=</span> <span class="s">"-c"</span><span class="o">,</span> <span class="n">defaultValue</span> <span class="o">=</span> <span class="s">"${COUNT:-123}"</span><span class="o">)</span>
<span class="kt">int</span> <span class="n">count</span><span class="o">;</span></code></pre>
</div>
</div>
<div class="listingblock secondary">
<div class="title">Kotlin</div>
<div class="content">
<pre class="rouge highlight"><code data-lang="kotlin"><span class="nd">@Option</span><span class="p">(</span><span class="n">names</span> <span class="p">=</span> <span class="p">[</span><span class="s">"-c"</span><span class="p">],</span> <span class="n">defaultValue</span> <span class="p">=</span> <span class="s">"\${COUNT:-123}"</span><span class="p">)</span>
<span class="k">lateinit</span> <span class="n">count</span><span class="p">:</span> <span class="n">int</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Picocli will look up the value of the <code>COUNT</code> variable in the system properties, environment variables, and resource bundle, and finally use value <code>123</code> if no value is found for any of these lookups.</p>
</div>
</div>
<div class="sect2">
<h3 id="_default_provider"><a class="anchor" href="#_default_provider"></a>5.4. Default Provider</h3>
<div class="paragraph">
<p>Finally, you can specify a default provider in the <code>@Command</code> annotation:</p>
</div>
Expand Down Expand Up @@ -4537,9 +4636,21 @@ <h3 id="_default_provider"><a class="anchor" href="#_default_provider"></a>5.3.
<a href="https://github.com/remkop/picocli/blob/master/picocli-examples/src/main/java/picocli/examples/defaultprovider/">default provider examples</a>
for example implementations.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If the command has a default provider configured, and the option or positional parameter has a default value configured, then picocli will first try to find the value in the default provider. If the default provider has no value for that option or positional parameter, then the default value configured on the option or positional parameter is used.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_propertiesdefaultprovider"><a class="anchor" href="#_propertiesdefaultprovider"></a>5.4. PropertiesDefaultProvider</h3>
<h3 id="_propertiesdefaultprovider"><a class="anchor" href="#_propertiesdefaultprovider"></a>5.5. PropertiesDefaultProvider</h3>
<div class="paragraph">
<p>From picocli 4.1, applications can use the built-in <code>PropertiesDefaultProvider</code>
implementation that loads default values from a properties file.</p>
Expand Down Expand Up @@ -4591,7 +4702,7 @@ <h3 id="_propertiesdefaultprovider"><a class="anchor" href="#_propertiesdefaultp
</div>
</div>
<div class="sect3">
<h4 id="_propertiesdefaultprovider_format"><a class="anchor" href="#_propertiesdefaultprovider_format"></a>5.4.1. PropertiesDefaultProvider Format</h4>
<h4 id="_propertiesdefaultprovider_format"><a class="anchor" href="#_propertiesdefaultprovider_format"></a>5.5.1. PropertiesDefaultProvider Format</h4>
<div class="paragraph">
<p>The <code>PropertiesDefaultProvider</code> expects the properties file to be in the standard java <code>.properties</code> <a href="https://en.wikipedia.org/wiki/.properties">format</a>.</p>
</div>
Expand All @@ -4608,7 +4719,7 @@ <h4 id="_propertiesdefaultprovider_format"><a class="anchor" href="#_propertiesd
</div>
</div>
<div class="sect3">
<h4 id="_subcommands_default_values"><a class="anchor" href="#_subcommands_default_values"></a>5.4.2. Subcommands Default Values</h4>
<h4 id="_subcommands_default_values"><a class="anchor" href="#_subcommands_default_values"></a>5.5.2. Subcommands Default Values</h4>
<div class="paragraph">
<p>The default values for options and positional parameters of subcommands can be included in the
properties file for the top-level command, so that end users need to maintain only a single file.
Expand All @@ -4627,7 +4738,7 @@ <h4 id="_subcommands_default_values"><a class="anchor" href="#_subcommands_defau
</div>
</div>
<div class="sect2">
<h3 id="fallbackValue-annotation"><a class="anchor" href="#fallbackValue-annotation"></a>5.5. <code>fallbackValue</code> Annotation</h3>
<h3 id="fallbackValue-annotation"><a class="anchor" href="#fallbackValue-annotation"></a>5.6. <code>fallbackValue</code> Annotation</h3>
<div class="paragraph">
<p>If an option is defined with <code>arity = "0..1"</code>, it <a href="#_optional_values">may or may not have a parameter value</a>.
If such an option is specified without a value on the command line, it is assigned the fallback value.</p>
Expand Down Expand Up @@ -4703,7 +4814,7 @@ <h3 id="fallbackValue-annotation"><a class="anchor" href="#fallbackValue-annotat
</div>
</div>
<div class="sect2">
<h3 id="_was_a_value_defaulted"><a class="anchor" href="#_was_a_value_defaulted"></a>5.6. Was a Value Defaulted?</h3>
<h3 id="_was_a_value_defaulted"><a class="anchor" href="#_was_a_value_defaulted"></a>5.7. Was a Value Defaulted?</h3>
<div class="paragraph">
<p>Sometimes an application is interested in knowing whether an option value was specified on the command line, or whether the default value was assigned.</p>
</div>
Expand Down Expand Up @@ -18445,4 +18556,4 @@ <h3 id="_source"><a class="anchor" href="#_source"></a>37.2. Source</h3>
handleTocOnResize();
</script>
</body>
</html>
</html>

0 comments on commit f0262b4

Please sign in to comment.