@@ -7,11 +7,11 @@ import com.github.ajalt.clikt.parsers.OptionParser
7
7
import kotlin.properties.ReadOnlyProperty
8
8
import kotlin.reflect.KProperty
9
9
10
- class MutuallyExclusiveOptions <OptT , OutT >(
10
+ class MutuallyExclusiveOptions <OptT : Any , OutT >(
11
11
internal val options : List <OptionDelegate <OptT ?>>,
12
12
override val groupName : String? ,
13
13
override val groupHelp : String? ,
14
- private val transform : (OptT ? ) -> OutT
14
+ internal val transformAll : (List < OptT > ) -> OutT
15
15
) : ParameterGroupDelegate<OutT> {
16
16
init {
17
17
require(options.size > 1 ) { " must provide at least two options to a mutually exclusive group" }
@@ -22,17 +22,13 @@ class MutuallyExclusiveOptions<OptT, OutT>(
22
22
override fun getValue (thisRef : CliktCommand , property : KProperty <* >): OutT = value
23
23
24
24
override fun finalize (context : Context , invocationsByOption : Map <Option , List <OptionParser .Invocation >>) {
25
- if (invocationsByOption.size > 1 ) {
26
- throw MutuallyExclusiveGroupException (options.map { o -> o.names.maxBy { it.length }!! })
27
- }
28
-
29
25
for ((option, invocations) in invocationsByOption) {
30
26
check(option in options) { " Internal Clikt Error: finalizing unregistered option [${option.names} ]" }
31
27
option.finalize(context, invocations)
32
28
}
33
29
34
- val values = options.filter { it.value != null }.map { it.value }
35
- value = transform (values.firstOrNull() )
30
+ val values = options.mapNotNull { it.value }
31
+ value = transformAll (values)
36
32
}
37
33
38
34
override operator fun provideDelegate (thisRef : CliktCommand , prop : KProperty <* >): ReadOnlyProperty <CliktCommand , OutT > {
@@ -47,15 +43,15 @@ class MutuallyExclusiveOptions<OptT, OutT>(
47
43
return this
48
44
}
49
45
50
- fun <T > copy (transform : (OptT ? ) -> T ) = MutuallyExclusiveOptions (options, groupName, groupHelp, transform )
46
+ fun <T > copy (transformAll : (List < OptT > ) -> T ) = MutuallyExclusiveOptions (options, groupName, groupHelp, transformAll )
51
47
}
52
48
53
49
/* *
54
50
* Declare a set of two or more mutually exclusive options.
55
51
*
56
52
* If none of the options are given on the command line, the value of this delegate will be null.
57
53
* If one option is given, the value will be that option's value.
58
- * If more than one option is given, a [UsageError] is thrown .
54
+ * If more than one option is given, the value of the last one is used .
59
55
*
60
56
* All options in the group must have a name specified. All options must be nullable (they cannot
61
57
* use [flag], [required] etc.). If you want flags, you should use [switch] instead.
@@ -80,20 +76,33 @@ fun <T : Any> ParameterHolder.mutuallyExclusiveOptions(
80
76
name : String? = null,
81
77
help : String? = null
82
78
): MutuallyExclusiveOptions <T , T ?> {
83
- return MutuallyExclusiveOptions (listOf (option1, option2) + options, name, help) { it }
79
+ return MutuallyExclusiveOptions (listOf (option1, option2) + options, name, help) { it.lastOrNull() }
80
+ }
81
+
82
+ /* *
83
+ * If more than one of the group's options are given on the command line, throw a [MutuallyExclusiveGroupException]
84
+ */
85
+ fun <T : Any > MutuallyExclusiveOptions <T , T ?>.single (): MutuallyExclusiveOptions <T , T ?> = copy {
86
+ if (it.size > 1 ) {
87
+ throw MutuallyExclusiveGroupException (options.map { o -> o.longestName()!! })
88
+ }
89
+ it.lastOrNull()
84
90
}
85
91
86
92
/* *
87
93
* Make a [mutuallyExclusiveOptions] group required. If none of the options in the group are given,
88
94
* a [UsageError] is thrown.
89
95
*/
90
- fun <T : Any > MutuallyExclusiveOptions <T , T ?>.required (): MutuallyExclusiveOptions <T , T > = copy {
91
- it ? : throw UsageError (" Must provide one of ${options.joinToString { it.names.maxBy { it.length }!! }} " )
96
+ fun <T : Any > MutuallyExclusiveOptions <T , T ?>.required (): MutuallyExclusiveOptions <T , T > {
97
+ return copy {
98
+ transformAll(it)
99
+ ? : throw UsageError (" Must provide one of ${options.joinToString { it.longestName()!! }} " )
100
+ }
92
101
}
93
102
94
103
/* *
95
104
* If none of the options in a [mutuallyExclusiveOptions] group are given on the command line, us [value] for the group.
96
105
*/
97
- fun <T : Any > MutuallyExclusiveOptions <T , T ?>.default (value : T ): MutuallyExclusiveOptions <T , T > = copy {
98
- it ? : value
106
+ fun <T : Any > MutuallyExclusiveOptions <T , T ?>.default (value : T ): MutuallyExclusiveOptions <T , T > {
107
+ return copy { transformAll(it) ? : value }
99
108
}
0 commit comments