Skip to content

Commit

Permalink
Add toString implementation for options and arguments (#435)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajalt committed Aug 1, 2023
1 parent a18431f commit b2922a7
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 48 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Changelog

## Unreleased

### Added
- Added `toString` implementations to options and arguments. ([#434](https://github.com/ajalt/clikt/issues/434))
## 4.2.0
### Added
- Added `requireConfirmation` parameter to `option().prompt()` ([#426](https://github.com/ajalt/clikt/issues/426))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -495,45 +495,16 @@ abstract class CliktCommand(
override fun toString() = buildString {
append("<${this@CliktCommand.classSimpleName()} name=$commandName")

if (_options.isNotEmpty() || _arguments.isNotEmpty() || _subcommands.isNotEmpty()) {
append(" ")
}

if (_options.isNotEmpty()) {
append("options=[")
for ((i, option) in _options.withIndex()) {
if (i > 0) append(" ")
append(option.longestName())
if (_context != null && option is OptionDelegate<*>) {
try {
val value = option.value
append("=").append(value)
} catch (_: IllegalStateException) {
}
}
}
append("]")
_options.joinTo(this, prefix=" options=[", postfix = "]")
}


if (_arguments.isNotEmpty()) {
append(" arguments=[")
for ((i, argument) in _arguments.withIndex()) {
if (i > 0) append(" ")
append(argument.name)
if (_context != null && argument is ProcessedArgument<*, *>) {
try {
val value = argument.value
append("=").append(value)
} catch (_: IllegalStateException) {
}
}
}
append("]")
_arguments.joinTo(this, prefix=" arguments=[", postfix = "]")
}

if (_subcommands.isNotEmpty()) {
_subcommands.joinTo(this, " ", prefix = " subcommands=[", postfix = "]")
_subcommands.joinTo(this, prefix = " subcommands=[", postfix = "]")
}

append(">")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,11 @@ class ProcessedArgumentImpl<AllT, ValueT> internal constructor(
transformValidator = validator
)
}

override fun toString(): String = buildString {
append(name)
runCatching { value }.onSuccess { append("=").append(it) }
}
}

typealias RawArgument = ProcessedArgument<String, String>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ internal fun Option.hasEnvvarOrSourcedValue(
context: Context,
invocations: List<Invocation>,
): Boolean {

val envvar = (this as? OptionWithValues<*, *, *>)?.envvar
val final = this.getFinalValue(context, invocations, envvar)
return final !is FinalValue.Parsed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,11 @@ private class OptionWithValuesImpl<AllT, EachT, ValueT>(
transformValidator = validator
)
}

override fun toString(): String = buildString {
append(longestName())
runCatching { value }.onSuccess { append("=").append(it) }
}
}

typealias NullableOption<EachT, ValueT> = OptionWithValues<EachT?, EachT, ValueT>
Expand Down Expand Up @@ -406,7 +411,7 @@ fun ParameterHolder.option(
* ```
*/
fun <AllT, EachT, ValueT> OptionWithValues<AllT, EachT, ValueT>.help(
help: String
help: String,
): OptionWithValues<AllT, EachT, ValueT> {
return help { help }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,25 +165,29 @@ class CliktCommandTest {
@Test
@JsName("command_toString")
fun `command toString`() {
class Cmd : TestCommand() {
class C : TestCommand(name="cmd") {
init {
context { helpOptionNames = setOf() }
}
val opt by option("-o", "--option")
val int by option().int()
val arg by argument()
val args by argument().multiple()
}

class Sub : TestCommand() {
val foo by option()
}

Cmd().toString() shouldBe "<Cmd name=cmd options=[--option --int] arguments=[ARG]>"
Cmd().apply { parse("--int=123 bar") }
.toString() shouldBe "<Cmd name=cmd options=[--option=null --int=123 --help] arguments=[ARG=bar]>"
Cmd().apply { parse("foo") }
.toString() shouldBe "<Cmd name=cmd options=[--option=null --int=null --help] arguments=[ARG=foo]>"
C().toString().shouldBe(
"<C name=cmd options=[--option, --int] arguments=[ARGS]>"
)
C().parse("--int=123 bar baz").toString().shouldBe(
"<C name=cmd options=[--option=null, --int=123] arguments=[ARGS=[bar, baz]]>"
)

Cmd().subcommands(Sub()).apply { parse("-ooo bar sub --foo=baz") }.toString().shouldBe(
"<Cmd name=cmd options=[--option=oo --int=null --help] arguments=[ARG=bar] " +
"subcommands=[<Sub name=sub options=[--foo=baz --help]>]>"
C().subcommands(Sub()).parse("-ooo bar sub --foo=baz").toString().shouldBe(
"<C name=cmd options=[--option=oo, --int=null] arguments=[ARGS=[bar]] " +
"subcommands=[<Sub name=sub options=[--foo=baz]>]>"
)
}

Expand All @@ -200,6 +204,9 @@ class CliktCommandTest {
}

class Cmd : TestCommand() {
init {
context { helpOptionNames = setOf() }
}
val g by G()
val g2 by G2().cooccurring()
val ge by mutuallyExclusiveOptions(
Expand All @@ -208,9 +215,29 @@ class CliktCommandTest {
)
}

Cmd().toString() shouldBe "<Cmd name=cmd options=[--option --foo --bar --e1 --e2]>"
Cmd().apply { parse("-oo --foo=f --e1=1") }
.toString() shouldBe "<Cmd name=cmd options=[--option=o --foo=f --bar=null --e1=1 --e2=null --help]>"
Cmd().toString().shouldBe(
"<Cmd name=cmd options=[--option, --foo, --bar, --e1, --e2]>"
)
Cmd().parse("-oo --foo=f --e1=1").toString().shouldBe(
"<Cmd name=cmd options=[--option=o, --foo=f, --bar=null, --e1=1, --e2=null]>"
)
}

@Test
@JsName("parameter_toString")
fun `parameter toString`() {
class C : TestCommand() {
init {
context { helpOptionNames = setOf() }
}
val opt by option("-o", "--option")
val args by argument().multiple()
override fun run_() {
registeredOptions().single().toString() shouldBe "--option=foo"
registeredArguments().single().toString() shouldBe "ARGS=[bar, baz]"
}
}
C().parse("-o foo bar baz")
}

// https://github.com/ajalt/clikt/issues/64
Expand Down

0 comments on commit b2922a7

Please sign in to comment.