diff --git a/src/main/kotlin/com/xenomachina/argparser/ArgParser.kt b/src/main/kotlin/com/xenomachina/argparser/ArgParser.kt index 134daad..54441ee 100644 --- a/src/main/kotlin/com/xenomachina/argparser/ArgParser.kt +++ b/src/main/kotlin/com/xenomachina/argparser/ArgParser.kt @@ -38,7 +38,8 @@ import kotlin.reflect.KProperty class ArgParser( args: Array, mode: Mode = Mode.GNU, - helpFormatter: HelpFormatter? = DefaultHelpFormatter() + helpFormatter: HelpFormatter? = DefaultHelpFormatter(), + version: String? = null ) { enum class Mode { @@ -619,6 +620,13 @@ class ArgParser( throw ShowHelpException(helpFormatter, delegates.toList()) }.default(Unit).registerRoot() } + if (version != null) { + option("-v", "--version", + errorName = "VERSION", // This should never be used, but we need to say something + help = "show the version and exit") { + throw ShowVersionException(version) + }.default(Unit).registerRoot() + } } private val builtinDelegateCount = delegates.size diff --git a/src/main/kotlin/com/xenomachina/argparser/Exceptions.kt b/src/main/kotlin/com/xenomachina/argparser/Exceptions.kt index ec46221..bdc5015 100644 --- a/src/main/kotlin/com/xenomachina/argparser/Exceptions.kt +++ b/src/main/kotlin/com/xenomachina/argparser/Exceptions.kt @@ -33,6 +33,18 @@ class ShowHelpException internal constructor( } } +/** + * Indicates that the user requested that the version should be shown (with the + * `--version` option, for example). + */ +class ShowVersionException internal constructor( + private val version: String +) : SystemExitException("version was requested", 0) { + override fun printUserMessage(writer: Writer, programName: String?, columns: Int) { + writer.write(version) + } +} + /** * Indicates that an unrecognized option was supplied. * diff --git a/src/test/kotlin/com/xenomachina/argparser/ArgParserTest.kt b/src/test/kotlin/com/xenomachina/argparser/ArgParserTest.kt index 66e428f..65631dc 100644 --- a/src/test/kotlin/com/xenomachina/argparser/ArgParserTest.kt +++ b/src/test/kotlin/com/xenomachina/argparser/ArgParserTest.kt @@ -1126,6 +1126,20 @@ This is the epilogue. Lorem ipsum dolor sit amet, consectetur adipiscing elit. D } } + test("Version") { + class Args(parser: ArgParser) { + val flag by parser.flagging(help = TEST_HELP) + } + + shouldThrow { + Args(parserOf("--version", + version = "1.0.0")).flag + }.run { + val help = StringWriter().apply { printUserMessage(this, "program_name", 60) }.toString() + help shouldBe "1.0.0" + } + } + test("Implicit long flag name") { class Args(parser: ArgParser) { val flag1 by parser.flagging(help = TEST_HELP) @@ -1680,8 +1694,9 @@ class Circle : Shape() fun parserOf( vararg args: String, mode: ArgParser.Mode = ArgParser.Mode.GNU, - helpFormatter: HelpFormatter? = DefaultHelpFormatter() -) = ArgParser(args, mode, helpFormatter) + helpFormatter: HelpFormatter? = DefaultHelpFormatter(), + version: String? = null +) = ArgParser(args, mode, helpFormatter, version) /** * Helper function for getting the static (not runtime) type of an expression. This is useful for verifying that the