Skip to content

Commit

Permalink
Add optionalValueLazy (#421)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajalt committed Jul 10, 2023
1 parent 762917e commit f3f5d08
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Changelog

## Unreleased
### Added
- 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))
- Added `option().optionalValueLazy{}`, which work like `optionalValue()` but the default value is computed lazily. ([#381](https://github.com/ajalt/clikt/issues/381))

## 4.0.0
### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ fun <ValueT> NullableOption<ValueT, ValueT>.varargValues(
* To avoid ambiguity when combined with [arguments][argument], you can set [acceptsUnattachedValue]
* to `false` to require that the option's value be specified like `--foo=bar` rather than `--foo bar`.
*
* You can use [optionalValueLazy] if you need to reference other parameters.
*
* ## Example
*
* ```
Expand All @@ -137,3 +139,39 @@ fun <ValueT : Any> NullableOption<ValueT, ValueT>.optionalValue(
it.firstOrNull() ?: default
}.copy(acceptsUnattachedValue = acceptsUnattachedValue)
}


/**
* Allow this option to be specified with or without an explicit value.
*
* If the option is specified on the command line without a value, [default] will be called and its
* return value can be used.
*
* To avoid ambiguity when combined with [arguments][argument], you can set [acceptsUnattachedValue]
* to `false` to require that the option's value be specified like `--foo=bar` rather than `--foo bar`.
*
* You can use [optionalValue] if you don't need to reference other parameters.
*
* ## Example
*
* ```
* val log by option().optionalValueLazy{"verbose"}.default("none")
*
* > ./tool --log=debug
* log level == debug
*
* > ./tool --log
* log level == verbose
*
* > ./tool
* log level == none
* ```
*/
fun <ValueT : Any> NullableOption<ValueT, ValueT>.optionalValueLazy(
acceptsUnattachedValue: Boolean = true,
default: () -> ValueT,
): NullableOption<ValueT, ValueT> {
return transformValues(0..1) {
it.firstOrNull() ?: default()
}.copy(acceptsUnattachedValue = acceptsUnattachedValue)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import com.github.ajalt.clikt.core.MissingArgument
import com.github.ajalt.clikt.core.NoSuchOption
import com.github.ajalt.clikt.core.subcommands
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.optionalValue
import com.github.ajalt.clikt.parameters.options.varargValues
import com.github.ajalt.clikt.parameters.options.*
import com.github.ajalt.clikt.parameters.types.int
import com.github.ajalt.clikt.testing.TestCommand
import com.github.ajalt.clikt.testing.parse
Expand Down Expand Up @@ -52,6 +49,18 @@ class VarargOptionsTest {
C().parse(argv)
}

@Test
fun optionalValueLazy() {
class C : TestCommand() {
val o by option().int().default(1)
val p by option().int().optionalValueLazy { o }
override fun run_() {
p shouldBe 2
}
}
C().parse("--o=2 --p")
}

@Test
fun varargValues() = forAll(
row("", null),
Expand Down
4 changes: 3 additions & 1 deletion docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ variables](#values-from-environment-variables).

### Options with an Optional Value

You can create options that take zero or one values with [`optionalValue`][optionalValue].
You can create options that take zero or one values with [`optionalValue`][optionalValue] or
[`optionalValueLazy`][optionalValueLazy].

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

0 comments on commit f3f5d08

Please sign in to comment.