Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/main/kotlin/com/natpryce/konfig/cli.kt
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,12 @@ fun parseArgs(args: Array<String>,
this[opt]?.configKey ?: throw Misconfiguration("unrecognised command-line option $arg")

fun storeNextArg(configNameByOpt: Map<String, CommandLineOption>, opt: String) {
i++
if (i >= args.size) throw Misconfiguration("no argument for $arg command-line option")

properties[configNameByOpt.configNameFor(opt)] = CommandLineProperty(arg, args[i])
if (i + 1 >= args.size || args[i+1].startsWith("-")) {
properties[configNameByOpt.configNameFor(opt)] = CommandLineProperty(arg, "true")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be confusing for non-boolean options. Is there a way to make this type-safe and work for booleans only?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or, generalise it and make it work for any type? That way, it could work for enums as well as booleans.

For example: the CommandLineProperty class could have an optional (nullable) default value field. If it is non-null, that value is used when an explicit argument is not given.

An overload of the CommandLineProperty function for boolean keys could set the default value to true.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about providing a PR on my own for this and my solution would have been to introduce a CommandLineFlag class that is meant for exactly that. However, by now I think that the best solution would be to interpret every booleanType as a flag since nothing else makes sense.

} else {
i++
properties[configNameByOpt.configNameFor(opt)] = CommandLineProperty(arg, args[i])
}
}

when {
Expand All @@ -113,10 +115,10 @@ fun parseArgs(args: Array<String>,
files.add(arg)
}
}

i++
}

return Pair(CommandLineConfiguration(options.asList(), properties), files)
}

Expand Down
18 changes: 11 additions & 7 deletions src/test/kotlin/com/natpryce/unittests/konfig/cli_tests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,7 @@ import com.natpryce.hamkrest.containsSubstring
import com.natpryce.hamkrest.equalTo
import com.natpryce.hamkrest.present
import com.natpryce.hamkrest.throws
import com.natpryce.konfig.CommandLineOption
import com.natpryce.konfig.ConfigurationMap
import com.natpryce.konfig.Key
import com.natpryce.konfig.Misconfiguration
import com.natpryce.konfig.overriding
import com.natpryce.konfig.parseArgs
import com.natpryce.konfig.stringType
import com.natpryce.konfig.*
import org.junit.Assert.assertEquals
import org.junit.Test
import java.io.ByteArrayOutputStream
Expand All @@ -20,6 +14,7 @@ import java.io.ByteArrayOutputStream
class CommandLineParsing {
val optX = Key("opt.x", stringType)
val optY = Key("opt.y", stringType)
val optZ = Key("opt.z", booleanType)

@Test
fun no_options() {
Expand Down Expand Up @@ -70,6 +65,15 @@ class CommandLineParsing {
throws<Misconfiguration>())
}

@Test
fun flag_long_option() {
val (config, args) = parseArgs(arrayOf("--opt-z", "--opt-x", "foo", "bar"), CommandLineOption(optX), CommandLineOption(optZ))

assertThat(config[optX], equalTo("foo"))
assertThat(config[optZ], equalTo(true))
assertThat(args, equalTo(listOf("bar")))
}

@Test
fun defaults() {
val opts = arrayOf(
Expand Down