Updated kotlinx.cli (v0.2.1) (#3967)

This commit is contained in:
LepilkinaElena
2020-03-12 19:02:53 +03:00
committed by GitHub
parent 02eb63162f
commit 5ee4fb26f1
3 changed files with 62 additions and 9 deletions
@@ -71,11 +71,14 @@ interface ArgumentValueDelegate<T> {
* Abstract base class for subcommands.
*/
@ExperimentalCli
abstract class Subcommand(val name: String): ArgParser(name) {
abstract class Subcommand(val name: String, val actionDescription: String): ArgParser(name) {
/**
* Execute action if subcommand was provided.
*/
abstract fun execute()
val helpMessage: String
get() = " $name - $actionDescription\n"
}
/**
@@ -309,7 +312,7 @@ open class ArgParser(
*
* @param message error message.
*/
fun printError(message: String): Nothing {
fun printError(message: String): Nothing {
error("$message\n${makeUsage()}")
}
@@ -373,6 +376,7 @@ open class ArgParser(
protected fun parse(args: List<String>): ArgParserResult {
check(parsingState == null) { "Parsing of command line options can be called only once." }
// Add help option.
val helpDescriptor = if (useDefaultHelpShortName) OptionDescriptor<Boolean, Boolean>(
optionFullFormPrefix,
@@ -513,6 +517,13 @@ open class ArgParser(
internal fun makeUsage(): String {
val result = StringBuilder()
result.append("Usage: ${fullCommandName.joinToString(" ")} options_list\n")
if (subcommands.isNotEmpty()) {
result.append("Subcommands: \n")
subcommands.forEach { (_, subcommand) ->
result.append(subcommand.helpMessage)
}
result.append("\n")
}
if (arguments.isNotEmpty()) {
result.append("Arguments: \n")
arguments.forEach {
@@ -48,7 +48,7 @@ Options:
@Test
fun testHelpForSubcommands() {
class Summary: Subcommand("summary") {
class Summary: Subcommand("summary", "Get summary information") {
val exec by option(ArgType.Choice(listOf("samples", "geomean")),
description = "Execution time way of calculation").default("geomean")
val execSamples by option(ArgType.String, "exec-samples",
@@ -96,6 +96,48 @@ Options:
--codesize-normalize -> File with golden results which should be used for normalization { String }
--user, -u -> User access information for authorization { String }
--help, -h -> Usage info
""".trimIndent()
assertEquals(expectedOutput, helpOutput)
}
@Test
fun testHelpMessageWithSubcommands() {
abstract class CommonOptions(name: String, actionDescription: String): Subcommand(name, actionDescription) {
val numbers by argument(ArgType.Int, "numbers", description = "Numbers").vararg()
}
class Summary: CommonOptions("summary", "Calculate summary") {
val invert by option(ArgType.Boolean, "invert", "i", "Invert results")
var result: Int = 0
override fun execute() {
result = numbers.sum()
result = invert?.let { -1 * result } ?: result
}
}
class Subtraction : CommonOptions("sub", "Calculate subtraction") {
var result: Int = 0
override fun execute() {
result = numbers.map { -it }.sum()
}
}
val summaryAction = Summary()
val subtractionAction = Subtraction()
val argParser = ArgParser("testParser")
argParser.subcommands(summaryAction, subtractionAction)
argParser.parse(emptyArray())
val helpOutput = argParser.makeUsage().trimIndent()
println(helpOutput)
val expectedOutput = """
Usage: testParser options_list
Subcommands:
summary - Calculate summary
sub - Calculate subtraction
Options:
--help, -h -> Usage info
""".trimIndent()
assertEquals(expectedOutput, helpOutput)
}
@@ -16,7 +16,7 @@ class SubcommandsTests {
fun testSubcommand() {
val argParser = ArgParser("testParser")
val output by argParser.option(ArgType.String, "output", "o", "Output file")
class Summary: Subcommand("summary") {
class Summary: Subcommand("summary", "Calculate summary") {
val invert by option(ArgType.Boolean, "invert", "i", "Invert results")
val addendums by argument(ArgType.Int, "addendums", description = "Addendums").vararg()
var result: Int = 0
@@ -35,10 +35,10 @@ class SubcommandsTests {
@Test
fun testCommonOptions() {
abstract class CommonOptions(name: String): Subcommand(name) {
abstract class CommonOptions(name: String, actionDescription: String): Subcommand(name, actionDescription) {
val numbers by argument(ArgType.Int, "numbers", description = "Numbers").vararg()
}
class Summary: CommonOptions("summary") {
class Summary: CommonOptions("summary", "Calculate summary") {
val invert by option(ArgType.Boolean, "invert", "i", "Invert results")
var result: Int = 0
@@ -48,7 +48,7 @@ class SubcommandsTests {
}
}
class Subtraction : CommonOptions("sub") {
class Subtraction : CommonOptions("sub", "Calculate subtraction") {
var result: Int = 0
override fun execute() {
@@ -73,7 +73,7 @@ class SubcommandsTests {
fun testRecursiveSubcommands() {
val argParser = ArgParser("testParser")
class Summary: Subcommand("summary") {
class Summary: Subcommand("summary", "Calculate summary") {
val addendums by argument(ArgType.Int, "addendums", description = "Addendums").vararg()
var result: Int = 0
@@ -82,7 +82,7 @@ class SubcommandsTests {
}
}
class Calculation: Subcommand("calc") {
class Calculation: Subcommand("calc", "Execute calculation") {
init {
subcommands(Summary())
}