Skip to content

Commit f3f5d08

Browse files
authored
Add optionalValueLazy (#421)
1 parent 762917e commit f3f5d08

File tree

4 files changed

+56
-5
lines changed

4 files changed

+56
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# Changelog
2+
23
## Unreleased
34
### Added
45
- Added `MordantHelpFormatter.renderAttachedOptionValue` that you can override to change how option values are shown, e.g. if you want option to show as `--option <value>` instead of `--option=<value>`. ([#416](https://github.com/ajalt/clikt/issues/416))
6+
- Added `option().optionalValueLazy{}`, which work like `optionalValue()` but the default value is computed lazily. ([#381](https://github.com/ajalt/clikt/issues/381))
57

68
## 4.0.0
79
### Added

clikt/src/commonMain/kotlin/com/github/ajalt/clikt/parameters/options/TransformEach.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ fun <ValueT> NullableOption<ValueT, ValueT>.varargValues(
114114
* To avoid ambiguity when combined with [arguments][argument], you can set [acceptsUnattachedValue]
115115
* to `false` to require that the option's value be specified like `--foo=bar` rather than `--foo bar`.
116116
*
117+
* You can use [optionalValueLazy] if you need to reference other parameters.
118+
*
117119
* ## Example
118120
*
119121
* ```
@@ -137,3 +139,39 @@ fun <ValueT : Any> NullableOption<ValueT, ValueT>.optionalValue(
137139
it.firstOrNull() ?: default
138140
}.copy(acceptsUnattachedValue = acceptsUnattachedValue)
139141
}
142+
143+
144+
/**
145+
* Allow this option to be specified with or without an explicit value.
146+
*
147+
* If the option is specified on the command line without a value, [default] will be called and its
148+
* return value can be used.
149+
*
150+
* To avoid ambiguity when combined with [arguments][argument], you can set [acceptsUnattachedValue]
151+
* to `false` to require that the option's value be specified like `--foo=bar` rather than `--foo bar`.
152+
*
153+
* You can use [optionalValue] if you don't need to reference other parameters.
154+
*
155+
* ## Example
156+
*
157+
* ```
158+
* val log by option().optionalValueLazy{"verbose"}.default("none")
159+
*
160+
* > ./tool --log=debug
161+
* log level == debug
162+
*
163+
* > ./tool --log
164+
* log level == verbose
165+
*
166+
* > ./tool
167+
* log level == none
168+
* ```
169+
*/
170+
fun <ValueT : Any> NullableOption<ValueT, ValueT>.optionalValueLazy(
171+
acceptsUnattachedValue: Boolean = true,
172+
default: () -> ValueT,
173+
): NullableOption<ValueT, ValueT> {
174+
return transformValues(0..1) {
175+
it.firstOrNull() ?: default()
176+
}.copy(acceptsUnattachedValue = acceptsUnattachedValue)
177+
}

clikt/src/commonTest/kotlin/com/github/ajalt/clikt/parameters/VarargOptionsTest.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ import com.github.ajalt.clikt.core.MissingArgument
44
import com.github.ajalt.clikt.core.NoSuchOption
55
import com.github.ajalt.clikt.core.subcommands
66
import com.github.ajalt.clikt.parameters.arguments.argument
7-
import com.github.ajalt.clikt.parameters.options.default
8-
import com.github.ajalt.clikt.parameters.options.option
9-
import com.github.ajalt.clikt.parameters.options.optionalValue
10-
import com.github.ajalt.clikt.parameters.options.varargValues
7+
import com.github.ajalt.clikt.parameters.options.*
118
import com.github.ajalt.clikt.parameters.types.int
129
import com.github.ajalt.clikt.testing.TestCommand
1310
import com.github.ajalt.clikt.testing.parse
@@ -52,6 +49,18 @@ class VarargOptionsTest {
5249
C().parse(argv)
5350
}
5451

52+
@Test
53+
fun optionalValueLazy() {
54+
class C : TestCommand() {
55+
val o by option().int().default(1)
56+
val p by option().int().optionalValueLazy { o }
57+
override fun run_() {
58+
p shouldBe 2
59+
}
60+
}
61+
C().parse("--o=2 --p")
62+
}
63+
5564
@Test
5665
fun varargValues() = forAll(
5766
row("", null),

docs/options.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ variables](#values-from-environment-variables).
217217

218218
### Options with an Optional Value
219219

220-
You can create options that take zero or one values with [`optionalValue`][optionalValue].
220+
You can create options that take zero or one values with [`optionalValue`][optionalValue] or
221+
[`optionalValueLazy`][optionalValueLazy].
221222

222223
=== "Example"
223224
```kotlin
@@ -1244,6 +1245,7 @@ val opt: Pair<Int, Int> by option("-o", "--opt")
12441245
[mutuallyExclusiveOptions]: api/clikt/com.github.ajalt.clikt.parameters.groups/mutually-exclusive-options.html
12451246
[option]: api/clikt/com.github.ajalt.clikt.parameters.options/option.html
12461247
[optionalValue]: api/clikt/com.github.ajalt.clikt.parameters.options/optional-value.html
1248+
[optionalValueLazy]: api/clikt/com.github.ajalt.clikt.parameters.options/optional-value-lazy.html
12471249
[pair]: api/clikt/com.github.ajalt.clikt.parameters.options/pair.html
12481250
[parameter-types]: parameters.md#parameter-types
12491251
[PrintMessage]: api/clikt/com.github.ajalt.clikt.core/-print-message/index.html

0 commit comments

Comments
 (0)