Updated kotlinx.cli (v0.2.1) (#3967)
This commit is contained in:
@@ -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())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user