Skip to content

Commit

Permalink
Don't print help on empty args when envvars are present (#532)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajalt authored Jul 20, 2024
1 parent d2f7a18 commit 015ee1d
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

### Fixed
- Fixed excess arguments not being reported when `allowMultipleSubcommands=true` and a subcommand has excess arguments followed by another subcommand.
- Commands with `printHelpOnEmptyArgs=true` will no longer print help if an option has a value from an environment variable or value source. ([#382](https://github.com/ajalt/clikt/pull/382))

### Deprecated
- Deprecated `Context.originalArgv`. It will now always return an empty list. If your commands need an argv, you can pass it to them before you run them, or set in on the new `Context.data` map.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.github.ajalt.clikt.parameters.types.int
import com.github.ajalt.clikt.testing.TestCommand
import com.github.ajalt.clikt.testing.parse
import com.github.ajalt.clikt.testing.test
import com.github.ajalt.clikt.testing.withEnv
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.data.blocking.forAll
import io.kotest.data.row
Expand Down Expand Up @@ -81,12 +82,38 @@ class CliktCommandTest {
@Test
@JsName("printHelpOnEmptyArgs__true")
fun `printHelpOnEmptyArgs = true`() {
class C : TestCommand(called = false, printHelpOnEmptyArgs = true)
class C : TestCommand(called = false, printHelpOnEmptyArgs = true) {
val r by option().required()
}
shouldThrow<PrintHelpMessage> {
C().parse("")
}.error shouldBe true
}

@Test
@JsName("printHelpOnEmptyArgs_with_envvars")
fun `printHelpOnEmptyArgs with envvars`() {
class C : TestCommand(called = true, printHelpOnEmptyArgs = true) {
val foo by option(envvar = "FOO")
override fun run_() {
foo shouldBe "bar"
}
}
C().withEnv("FOO" to "bar").parse("")
}

@Test
@JsName("printHelpOnEmptyArgs_with_envvars_and_required_option")
fun `printHelpOnEmptyArgs with envvars and required option`() {
class C : TestCommand(called = false, printHelpOnEmptyArgs = true) {
val foo by option(envvar = "FOO")
val r by option().required()
}
shouldThrow<MissingOption> {
C().withEnv("FOO" to "bar").parse("")
}
}

@Test
@JsName("shortHelp_extraction")
fun `shortHelp extraction`() = forAll(
Expand Down Expand Up @@ -169,10 +196,11 @@ class CliktCommandTest {
@Test
@JsName("command_toString")
fun `command toString`() {
class C : TestCommand(name="cmd") {
class C : TestCommand(name = "cmd") {
init {
context { helpOptionNames = setOf() }
}

val opt by option("-o", "--option")
val int by option().int()
val args by argument().multiple()
Expand Down Expand Up @@ -211,6 +239,7 @@ class CliktCommandTest {
init {
context { helpOptionNames = setOf() }
}

val g by G()
val g2 by G2().cooccurring()
val ge by mutuallyExclusiveOptions(
Expand All @@ -234,6 +263,7 @@ class CliktCommandTest {
init {
context { helpOptionNames = setOf() }
}

val opt by option("-o", "--option")
val args by argument().multiple()
override fun run_() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package com.github.ajalt.clikt.parameters

import com.github.ajalt.clikt.core.*
import com.github.ajalt.clikt.core.BadParameterValue
import com.github.ajalt.clikt.core.MutuallyExclusiveGroupException
import com.github.ajalt.clikt.core.context
import com.github.ajalt.clikt.core.subcommands
import com.github.ajalt.clikt.parameters.groups.OptionGroup
import com.github.ajalt.clikt.parameters.groups.cooccurring
import com.github.ajalt.clikt.parameters.groups.mutuallyExclusiveOptions
import com.github.ajalt.clikt.parameters.groups.single
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.TestSource
import com.github.ajalt.clikt.testing.defaultLocalization
import com.github.ajalt.clikt.testing.parse
import com.github.ajalt.clikt.testing.*
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.data.blocking.forAll
import io.kotest.data.row
Expand All @@ -19,10 +19,6 @@ import kotlin.js.JsName
import kotlin.test.Test

class EnvvarOptionsTest {
private fun <T : CliktCommand> T.withEnv(vararg entries: Pair<String, String?>): T {
return context { readEnvvar = { entries.toMap()[it] } }
}

@Test
@JsName("explicit_envvar")
fun `explicit envvar`() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.github.ajalt.clikt.testing

import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.UsageError
import com.github.ajalt.clikt.core.context
import com.github.ajalt.clikt.output.Localization
import com.github.ajalt.clikt.output.ParameterFormatter

Expand All @@ -11,3 +13,7 @@ val Throwable.formattedMessage: String?
) ?: message

internal val defaultLocalization = object : Localization {}

internal fun <T : CliktCommand> T.withEnv(vararg entries: Pair<String, String?>): T {
return context { readEnvvar = { entries.toMap()[it] } }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.github.ajalt.clikt.parsers

import com.github.ajalt.clikt.core.*
import com.github.ajalt.clikt.parameters.options.Option
import com.github.ajalt.clikt.parameters.options.hasEnvvarOrSourcedValue
import com.github.ajalt.clikt.parameters.options.splitOptionPrefix

internal fun <T : BaseCliktCommand<T>> parseArgv(
Expand Down Expand Up @@ -149,7 +150,9 @@ private class CommandParser<T : BaseCliktCommand<T>>(
}

private fun printHelpOnEmptyArgsIfNecessary(): Boolean {
if (i > tokens.lastIndex && command.printHelpOnEmptyArgs) {
if (i > tokens.lastIndex && command.printHelpOnEmptyArgs
&& command._options.none { it.hasEnvvarOrSourcedValue(context, emptyList()) }
) {
errors += PrintHelpMessage(context, error = true)
return true
}
Expand Down

0 comments on commit 015ee1d

Please sign in to comment.