diff --git a/CHANGELOG.md b/CHANGELOG.md index a8197eae3..5807811d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,47 @@ # Changelog ## Unreleased +### Added +- Added `NoSuchArgument` exception that is thrown when too many arguments were given on the command line. Previously, a less specific `UsageError` was thrown instead. +- Added `CliktUtil.exitProcess`, which is a cross-platform way to exit the process with a status code. +- Added `CommandLineParser.tokenize` that splits a string into argv tokens. +- Added `CommandLineParser` that provides functions for parsing and finalizing commands manually for more control. +- Added `Context.invokedSubcommands` that contains all subcommands of the current command that are going to be invoked when `allowMultipleSubcommands` is `true`. +- Added `SuspendingCliktCommand` that has a `suspend fun run` method, allowing you to use coroutines in your commands. +- Added `ChainedCliktCommand` that allows you to return a value from your `run` method and pass it to the next command in the chain. + ## 4.4.0 ### Added - Publish `linuxArm64` and `wasmJs` targets. +### Changed +- In a subcommand with `argument().multiple()`, the behavior is now the same regardless of the value of `allowMultipleSubcommands`: if a token matches a subcommand name, it's now treated as a subcommand rather than a positional argument. +- Due to changes to the internal parsing algorithm, the exact details of error messages when multiple usage errors occur have changed in some cases. +- **Breaking Change:** Moved the following parameters from `CliktCommand`'s constructor; override the corresponding properties instead: + + | removed parameter | replacement property | + |-----------------------------|---------------------------------| + | `help` | `fun help` | + | `epilog` | `fun helpEpilog` | + | `invokeWithoutSubcommand` | `val invokeWithoutSubcommand` | + | `printHelpOnEmptyArgs` | `val printHelpOnEmptyArgs` | + | `helpTags` | `val helpTags` | + | `autoCompleteEnvvar` | `val autoCompleteEnvvar` | + | `allowMultipleSubcommands` | `val allowMultipleSubcommands` | + | `treatUnknownOptionsAsArgs` | `val treatUnknownOptionsAsArgs` | + | `hidden` | `val hiddenFromHelp` | +- The following methods on `CliktCommand` have been renamed: `commandHelp` -> `help`, `commandHelpEpilog` -> `epilog`. The old names are deprecated. +- **Breaking Change:** `CliktCommand.main` and `CliktCommand.parse` are now extension functions rather than methods. + +### Fixed +- Fixed excess arguments not being reported when `allowMultipleSubcommands=true` and a subcommand has excess arguments followed by another subcommand. + +### 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. + +### Removed +- Removed previously deprecated experimental annotations. + ## 4.3.0 ### Added - Added `limit` parameter to `option().counted()` to limit the number of times the option can be used. You can either clamp the value to the limit, or throw an error if the limit is exceeded. ([#483](https://github.com/ajalt/clikt/issues/483)) diff --git a/README.md b/README.md index dac32fd9d..108622182 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ dependencies { #### Multiplatform -Clikt supports the following targets: `jvm`, `mingwX64`, `linuxX64`, `linuxArm64`, `macosX64`, `macosArm64'`, +Clikt supports the following targets: `jvm`, `mingwX64`, `linuxX64`, `linuxArm64`, `macosX64`, `macosArm64`, and `js` and `wasmJs` (for both Node.js and Browsers). [See the docs](https://ajalt.github.io/clikt/advanced/#multiplatform-support) for more information about functionality supported on each target. You'll need to use Gradle 6 or newer. diff --git a/clikt/api/clikt.api b/clikt/api/clikt.api index 1337c9728..8b51218c5 100644 --- a/clikt/api/clikt.api +++ b/clikt/api/clikt.api @@ -1,6 +1,46 @@ +public abstract class com/github/ajalt/clikt/command/ChainedCliktCommand : com/github/ajalt/clikt/core/BaseCliktCommand { + public fun ()V + public fun (Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public abstract fun run (Ljava/lang/Object;)Ljava/lang/Object; +} + +public final class com/github/ajalt/clikt/command/ChainedCliktCommandKt { + public static final fun main (Lcom/github/ajalt/clikt/command/ChainedCliktCommand;Ljava/util/List;Ljava/lang/Object;)Ljava/lang/Object; + public static final fun main (Lcom/github/ajalt/clikt/command/ChainedCliktCommand;[Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; + public static final fun parse (Lcom/github/ajalt/clikt/command/ChainedCliktCommand;Ljava/util/List;Ljava/lang/Object;)Ljava/lang/Object; + public static final fun parse (Lcom/github/ajalt/clikt/command/ChainedCliktCommand;[Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; + public static final fun test (Lcom/github/ajalt/clikt/command/ChainedCliktCommand;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;II)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; + public static final fun test (Lcom/github/ajalt/clikt/command/ChainedCliktCommand;Ljava/util/List;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;II)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; + public static final fun test (Lcom/github/ajalt/clikt/command/ChainedCliktCommand;[Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;II)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; + public static synthetic fun test$default (Lcom/github/ajalt/clikt/command/ChainedCliktCommand;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IIILjava/lang/Object;)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; + public static synthetic fun test$default (Lcom/github/ajalt/clikt/command/ChainedCliktCommand;Ljava/util/List;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IIILjava/lang/Object;)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; + public static synthetic fun test$default (Lcom/github/ajalt/clikt/command/ChainedCliktCommand;[Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IIILjava/lang/Object;)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; +} + +public abstract class com/github/ajalt/clikt/command/SuspendingCliktCommand : com/github/ajalt/clikt/core/BaseCliktCommand { + public fun ()V + public fun (Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public abstract fun run (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public final class com/github/ajalt/clikt/command/SuspendingCliktCommandKt { + public static final fun main (Lcom/github/ajalt/clikt/command/SuspendingCliktCommand;Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun main (Lcom/github/ajalt/clikt/command/SuspendingCliktCommand;[Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun parse (Lcom/github/ajalt/clikt/command/SuspendingCliktCommand;Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun parse (Lcom/github/ajalt/clikt/command/SuspendingCliktCommand;[Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun test (Lcom/github/ajalt/clikt/command/SuspendingCliktCommand;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IILkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun test (Lcom/github/ajalt/clikt/command/SuspendingCliktCommand;Ljava/util/List;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IILkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun test (Lcom/github/ajalt/clikt/command/SuspendingCliktCommand;[Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IILkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun test$default (Lcom/github/ajalt/clikt/command/SuspendingCliktCommand;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IILkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public static synthetic fun test$default (Lcom/github/ajalt/clikt/command/SuspendingCliktCommand;Ljava/util/List;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IILkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public static synthetic fun test$default (Lcom/github/ajalt/clikt/command/SuspendingCliktCommand;[Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IILkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; +} + public final class com/github/ajalt/clikt/completion/CompletionBuiltinsKt { - public static final fun completionOption (Lcom/github/ajalt/clikt/core/CliktCommand;[Ljava/lang/String;Ljava/lang/String;Z)Lcom/github/ajalt/clikt/core/CliktCommand; - public static synthetic fun completionOption$default (Lcom/github/ajalt/clikt/core/CliktCommand;[Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Lcom/github/ajalt/clikt/core/CliktCommand; + public static final fun completionOption (Lcom/github/ajalt/clikt/core/BaseCliktCommand;[Ljava/lang/String;Ljava/lang/String;Z)Lcom/github/ajalt/clikt/core/BaseCliktCommand; + public static synthetic fun completionOption$default (Lcom/github/ajalt/clikt/core/BaseCliktCommand;[Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Lcom/github/ajalt/clikt/core/BaseCliktCommand; } public abstract class com/github/ajalt/clikt/completion/CompletionCandidates { @@ -74,12 +114,11 @@ public final class com/github/ajalt/clikt/completion/CompletionCommand : com/git public fun ()V public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun help (Lcom/github/ajalt/clikt/core/Context;)Ljava/lang/String; + public fun helpEpilog (Lcom/github/ajalt/clikt/core/Context;)Ljava/lang/String; public fun run ()V } -public abstract interface annotation class com/github/ajalt/clikt/completion/ExperimentalCompletionCandidates : java/lang/annotation/Annotation { -} - public final class com/github/ajalt/clikt/core/Abort : com/github/ajalt/clikt/core/ProgramResult { public fun ()V } @@ -92,42 +131,35 @@ public final class com/github/ajalt/clikt/core/BadParameterValue : com/github/aj public fun formatMessage (Lcom/github/ajalt/clikt/output/Localization;Lcom/github/ajalt/clikt/output/ParameterFormatter;)Ljava/lang/String; } -public abstract class com/github/ajalt/clikt/core/CliktCommand : com/github/ajalt/clikt/core/ParameterHolder { +public abstract class com/github/ajalt/clikt/core/BaseCliktCommand : com/github/ajalt/clikt/core/ParameterHolder { public fun ()V - public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/Map;Ljava/lang/String;ZZZ)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/Map;Ljava/lang/String;ZZZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun aliases ()Ljava/util/Map; public fun allHelpParams ()Ljava/util/List; public fun commandHelp (Lcom/github/ajalt/clikt/core/Context;)Ljava/lang/String; public fun commandHelpEpilog (Lcom/github/ajalt/clikt/core/Context;)Ljava/lang/String; - public final fun confirm (Ljava/lang/String;Ljava/lang/Boolean;ZZLjava/util/List;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Boolean; - public static synthetic fun confirm$default (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/lang/String;Ljava/lang/Boolean;ZZLjava/util/List;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/Boolean; + public final fun configureContext (Lkotlin/jvm/functions/Function1;)V public final fun echo ()V public final fun echo (Ljava/lang/Object;ZZ)V - public static synthetic fun echo$default (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/lang/Object;ZZILjava/lang/Object;)V + public static synthetic fun echo$default (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Ljava/lang/Object;ZZILjava/lang/Object;)V public final fun echoFormattedHelp (Lcom/github/ajalt/clikt/core/CliktError;)V - public static synthetic fun echoFormattedHelp$default (Lcom/github/ajalt/clikt/core/CliktCommand;Lcom/github/ajalt/clikt/core/CliktError;ILjava/lang/Object;)V - public fun getCommandHelp ()Ljava/lang/String; - public fun getCommandHelpEpilog ()Ljava/lang/String; + public static synthetic fun echoFormattedHelp$default (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lcom/github/ajalt/clikt/core/CliktError;ILjava/lang/Object;)V + public fun getAllowMultipleSubcommands ()Z + public fun getAutoCompleteEnvvar ()Ljava/lang/String; public final fun getCommandName ()Ljava/lang/String; public final fun getCurrentContext ()Lcom/github/ajalt/clikt/core/Context; public final fun getFormattedHelp (Lcom/github/ajalt/clikt/core/CliktError;)Ljava/lang/String; - public static synthetic fun getFormattedHelp$default (Lcom/github/ajalt/clikt/core/CliktCommand;Lcom/github/ajalt/clikt/core/CliktError;ILjava/lang/Object;)Ljava/lang/String; - public final fun getHelpTags ()Ljava/util/Map; - public final fun getInvokeWithoutSubcommand ()Z + public static synthetic fun getFormattedHelp$default (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lcom/github/ajalt/clikt/core/CliktError;ILjava/lang/Object;)Ljava/lang/String; + public fun getHelpTags ()Ljava/util/Map; + public fun getHiddenFromHelp ()Z + public fun getInvokeWithoutSubcommand ()Z public final fun getMessages ()Ljava/util/List; - public final fun getPrintHelpOnEmptyArgs ()Z + public fun getPrintHelpOnEmptyArgs ()Z + public fun getTreatUnknownOptionsAsArgs ()Z + public fun help (Lcom/github/ajalt/clikt/core/Context;)Ljava/lang/String; + public fun helpEpilog (Lcom/github/ajalt/clikt/core/Context;)Ljava/lang/String; public final fun issueMessage (Ljava/lang/String;)V - public final fun main (Ljava/util/List;)V - public final fun main ([Ljava/lang/String;)V - public final fun parse (Ljava/util/List;Lcom/github/ajalt/clikt/core/Context;)V - public final fun parse ([Ljava/lang/String;Lcom/github/ajalt/clikt/core/Context;)V - public static synthetic fun parse$default (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/util/List;Lcom/github/ajalt/clikt/core/Context;ILjava/lang/Object;)V - public static synthetic fun parse$default (Lcom/github/ajalt/clikt/core/CliktCommand;[Ljava/lang/String;Lcom/github/ajalt/clikt/core/Context;ILjava/lang/Object;)V - public final fun prompt (Ljava/lang/String;Ljava/lang/Object;ZZZLjava/util/Collection;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; - public final fun prompt (Ljava/lang/String;Ljava/lang/String;ZZZLjava/util/Collection;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; - public static synthetic fun prompt$default (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/lang/String;Ljava/lang/Object;ZZZLjava/util/Collection;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/Object; - public static synthetic fun prompt$default (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/lang/String;Ljava/lang/String;ZZZLjava/util/Collection;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/String; public final fun registerArgument (Lcom/github/ajalt/clikt/parameters/arguments/Argument;)V public fun registerOption (Lcom/github/ajalt/clikt/core/GroupableOption;)V public final fun registerOption (Lcom/github/ajalt/clikt/parameters/options/Option;)V @@ -137,16 +169,31 @@ public abstract class com/github/ajalt/clikt/core/CliktCommand : com/github/ajal public final fun registeredParameterGroups ()Ljava/util/List; public final fun registeredSubcommandNames ()Ljava/util/List; public final fun registeredSubcommands ()Ljava/util/List; - public abstract fun run ()V + public final fun resetContext (Lcom/github/ajalt/clikt/core/Context;)Lcom/github/ajalt/clikt/core/Context; + public static synthetic fun resetContext$default (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lcom/github/ajalt/clikt/core/Context;ILjava/lang/Object;)Lcom/github/ajalt/clikt/core/Context; protected final fun shortHelp (Lcom/github/ajalt/clikt/core/Context;)Ljava/lang/String; public fun toString ()Ljava/lang/String; } +public final class com/github/ajalt/clikt/core/BaseCliktCommandKt { + public static final fun context (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/jvm/functions/Function1;)Lcom/github/ajalt/clikt/core/BaseCliktCommand; + public static final fun getTerminal (Lcom/github/ajalt/clikt/core/BaseCliktCommand;)Lcom/github/ajalt/mordant/terminal/Terminal; + public static final fun subcommands (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Ljava/lang/Iterable;)Lcom/github/ajalt/clikt/core/BaseCliktCommand; + public static final fun subcommands (Lcom/github/ajalt/clikt/core/BaseCliktCommand;[Lcom/github/ajalt/clikt/core/BaseCliktCommand;)Lcom/github/ajalt/clikt/core/BaseCliktCommand; +} + +public abstract class com/github/ajalt/clikt/core/CliktCommand : com/github/ajalt/clikt/core/BaseCliktCommand { + public fun ()V + public fun (Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public abstract fun run ()V +} + public final class com/github/ajalt/clikt/core/CliktCommandKt { - public static final fun context (Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/jvm/functions/Function1;)Lcom/github/ajalt/clikt/core/CliktCommand; - public static final fun getTerminal (Lcom/github/ajalt/clikt/core/CliktCommand;)Lcom/github/ajalt/mordant/terminal/Terminal; - public static final fun subcommands (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/lang/Iterable;)Lcom/github/ajalt/clikt/core/CliktCommand; - public static final fun subcommands (Lcom/github/ajalt/clikt/core/CliktCommand;[Lcom/github/ajalt/clikt/core/CliktCommand;)Lcom/github/ajalt/clikt/core/CliktCommand; + public static final fun main (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/util/List;)V + public static final fun main (Lcom/github/ajalt/clikt/core/CliktCommand;[Ljava/lang/String;)V + public static final fun parse (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/util/List;)V + public static final fun parse (Lcom/github/ajalt/clikt/core/CliktCommand;[Ljava/lang/String;)V } public class com/github/ajalt/clikt/core/CliktError : java/lang/RuntimeException { @@ -157,10 +204,14 @@ public class com/github/ajalt/clikt/core/CliktError : java/lang/RuntimeException public final fun getStatusCode ()I } +public final class com/github/ajalt/clikt/core/CliktUtil { + public static final field INSTANCE Lcom/github/ajalt/clikt/core/CliktUtil; + public final fun exitProcess (I)V +} + public final class com/github/ajalt/clikt/core/Context { public static final field Companion Lcom/github/ajalt/clikt/core/Context$Companion; - public synthetic fun (Lcom/github/ajalt/clikt/core/Context;Lcom/github/ajalt/clikt/core/CliktCommand;ZZLjava/lang/String;ZLjava/util/Set;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lcom/github/ajalt/mordant/terminal/Terminal;Lkotlin/jvm/functions/Function1;ZLcom/github/ajalt/clikt/sources/ValueSource;Lkotlin/jvm/functions/Function2;Lcom/github/ajalt/clikt/output/Localization;Lkotlin/jvm/functions/Function1;Ljava/lang/Object;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun ancestors ()Lkotlin/sequences/Sequence; + public synthetic fun (Lcom/github/ajalt/clikt/core/Context;Lcom/github/ajalt/clikt/core/BaseCliktCommand;ZZLjava/lang/String;ZLjava/util/Set;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lcom/github/ajalt/mordant/terminal/Terminal;Lkotlin/jvm/functions/Function1;ZLcom/github/ajalt/clikt/sources/ValueSource;Lkotlin/jvm/functions/Function2;Lcom/github/ajalt/clikt/output/Localization;Lkotlin/jvm/functions/Function1;Ljava/lang/Object;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun callOnClose (Lkotlin/jvm/functions/Function0;)V public final fun close ()V public final fun commandNameWithParents ()Ljava/util/List; @@ -171,13 +222,14 @@ public final class com/github/ajalt/clikt/core/Context { public final fun getAllowInterspersedArgs ()Z public final fun getArgumentFileReader ()Lkotlin/jvm/functions/Function1; public final fun getAutoEnvvarPrefix ()Ljava/lang/String; - public final fun getCommand ()Lcom/github/ajalt/clikt/core/CliktCommand; + public final fun getCommand ()Lcom/github/ajalt/clikt/core/BaseCliktCommand; public final fun getCorrectionSuggestor ()Lkotlin/jvm/functions/Function2; public final fun getErrorEncountered ()Z public final fun getExpandArgumentFiles ()Z public final fun getHelpFormatter ()Lkotlin/jvm/functions/Function1; public final fun getHelpOptionNames ()Ljava/util/Set; - public final fun getInvokedSubcommand ()Lcom/github/ajalt/clikt/core/CliktCommand; + public final fun getInvokedSubcommand ()Lcom/github/ajalt/clikt/core/BaseCliktCommand; + public final fun getInvokedSubcommands ()Ljava/util/List; public final fun getLocalization ()Lcom/github/ajalt/clikt/output/Localization; public final fun getObj ()Ljava/lang/Object; public final fun getOriginalArgv ()Ljava/util/List; @@ -189,14 +241,14 @@ public final class com/github/ajalt/clikt/core/Context { public final fun getTokenTransformer ()Lkotlin/jvm/functions/Function2; public final fun getValueSource ()Lcom/github/ajalt/clikt/sources/ValueSource; public final fun parentNames ()Ljava/util/List; - public final fun selfAndAncestors ()Lkotlin/sequences/Sequence; public final fun setArgumentFileReader (Lkotlin/jvm/functions/Function1;)V public final fun setObj (Ljava/lang/Object;)V + public fun toString ()Ljava/lang/String; } public final class com/github/ajalt/clikt/core/Context$Builder { - public fun (Lcom/github/ajalt/clikt/core/CliktCommand;Lcom/github/ajalt/clikt/core/Context;)V - public synthetic fun (Lcom/github/ajalt/clikt/core/CliktCommand;Lcom/github/ajalt/clikt/core/Context;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lcom/github/ajalt/clikt/core/Context;)V + public synthetic fun (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lcom/github/ajalt/clikt/core/Context;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun getAllowGroupedShortOptions ()Z public final fun getAllowInterspersedArgs ()Z public final fun getArgumentFileReader ()Lkotlin/jvm/functions/Function1; @@ -248,6 +300,7 @@ public final class com/github/ajalt/clikt/core/ContextJvmKt { public final class com/github/ajalt/clikt/core/ContextKt { public static final fun getTheme (Lcom/github/ajalt/clikt/core/Context;)Lcom/github/ajalt/mordant/rendering/Theme; public static final fun registerCloseable (Lcom/github/ajalt/clikt/core/Context;Ljava/lang/AutoCloseable;)Ljava/lang/AutoCloseable; + public static final fun selfAndAncestors (Lcom/github/ajalt/clikt/core/Context;)Lkotlin/sequences/Sequence; } public final class com/github/ajalt/clikt/core/FileNotFound : com/github/ajalt/clikt/core/UsageError { @@ -319,9 +372,14 @@ public final class com/github/ajalt/clikt/core/MutuallyExclusiveGroupException : public class com/github/ajalt/clikt/core/NoOpCliktCommand : com/github/ajalt/clikt/core/CliktCommand { public fun ()V - public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/Map;Ljava/lang/String;ZZ)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/Map;Ljava/lang/String;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun run ()V + public fun (Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun run ()V +} + +public final class com/github/ajalt/clikt/core/NoSuchArgument : com/github/ajalt/clikt/core/UsageError { + public fun (Ljava/util/List;)V + public fun formatMessage (Lcom/github/ajalt/clikt/output/Localization;Lcom/github/ajalt/clikt/output/ParameterFormatter;)Ljava/lang/String; } public final class com/github/ajalt/clikt/core/NoSuchOption : com/github/ajalt/clikt/core/UsageError { @@ -722,17 +780,17 @@ public final class com/github/ajalt/clikt/parameters/arguments/Argument$DefaultI public abstract interface class com/github/ajalt/clikt/parameters/arguments/ArgumentDelegate : com/github/ajalt/clikt/parameters/arguments/Argument, kotlin/properties/PropertyDelegateProvider, kotlin/properties/ReadOnlyProperty { public abstract fun getValue ()Ljava/lang/Object; - public abstract fun getValue (Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; + public abstract fun getValue (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; } public final class com/github/ajalt/clikt/parameters/arguments/ArgumentDelegate$DefaultImpls { public static fun getCompletionCandidates (Lcom/github/ajalt/clikt/parameters/arguments/ArgumentDelegate;)Lcom/github/ajalt/clikt/completion/CompletionCandidates; - public static fun getValue (Lcom/github/ajalt/clikt/parameters/arguments/ArgumentDelegate;Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; + public static fun getValue (Lcom/github/ajalt/clikt/parameters/arguments/ArgumentDelegate;Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; } public final class com/github/ajalt/clikt/parameters/arguments/ArgumentKt { - public static final fun argument (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lcom/github/ajalt/clikt/completion/CompletionCandidates;)Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument; - public static synthetic fun argument$default (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lcom/github/ajalt/clikt/completion/CompletionCandidates;ILjava/lang/Object;)Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument; + public static final fun argument (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lcom/github/ajalt/clikt/completion/CompletionCandidates;)Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument; + public static synthetic fun argument$default (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lcom/github/ajalt/clikt/completion/CompletionCandidates;ILjava/lang/Object;)Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument; public static final fun check (Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lcom/github/ajalt/clikt/parameters/arguments/ArgumentDelegate; public static final fun check (Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lcom/github/ajalt/clikt/parameters/arguments/ArgumentDelegate; public static synthetic fun check$default (Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/github/ajalt/clikt/parameters/arguments/ArgumentDelegate; @@ -790,7 +848,7 @@ public final class com/github/ajalt/clikt/parameters/arguments/ProcessedArgument public static synthetic fun copy$default (Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument;Lkotlin/jvm/functions/Function2;Ljava/lang/String;IZLkotlin/jvm/functions/Function1;Ljava/util/Map;Lcom/github/ajalt/clikt/completion/CompletionCandidates;ILjava/lang/Object;)Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument; public static synthetic fun copy$default (Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;IZLkotlin/jvm/functions/Function1;Ljava/util/Map;Lcom/github/ajalt/clikt/completion/CompletionCandidates;ILjava/lang/Object;)Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument; public static fun getCompletionCandidates (Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument;)Lcom/github/ajalt/clikt/completion/CompletionCandidates; - public static fun getValue (Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument;Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; + public static fun getValue (Lcom/github/ajalt/clikt/parameters/arguments/ProcessedArgument;Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; } public final class com/github/ajalt/clikt/parameters/arguments/ProcessedArgumentImpl : com/github/ajalt/clikt/parameters/arguments/ProcessedArgument { @@ -809,11 +867,11 @@ public final class com/github/ajalt/clikt/parameters/arguments/ProcessedArgument public fun getTransformValidator ()Lkotlin/jvm/functions/Function2; public fun getTransformValue ()Lkotlin/jvm/functions/Function2; public fun getValue ()Ljava/lang/Object; - public fun getValue (Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; + public fun getValue (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; public synthetic fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; public fun parameterHelp (Lcom/github/ajalt/clikt/core/Context;)Lcom/github/ajalt/clikt/output/HelpFormatter$ParameterHelp$Argument; public fun postValidate (Lcom/github/ajalt/clikt/core/Context;)V - public fun provideDelegate (Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/reflect/KProperty;)Lkotlin/properties/ReadOnlyProperty; + public fun provideDelegate (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/reflect/KProperty;)Lkotlin/properties/ReadOnlyProperty; public synthetic fun provideDelegate (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; public fun setName (Ljava/lang/String;)V public fun setValue (Ljava/lang/Object;)V @@ -824,11 +882,11 @@ public final class com/github/ajalt/clikt/parameters/groups/ChoiceGroup : com/gi public fun finalize (Lcom/github/ajalt/clikt/core/Context;Ljava/util/Map;)V public fun getGroupHelp ()Ljava/lang/String; public fun getGroupName ()Ljava/lang/String; - public fun getValue (Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; + public fun getValue (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; public synthetic fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; public fun parameterHelp (Lcom/github/ajalt/clikt/core/Context;)Lcom/github/ajalt/clikt/output/HelpFormatter$ParameterHelp$Group; public fun postValidate (Lcom/github/ajalt/clikt/core/Context;)V - public fun provideDelegate (Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/reflect/KProperty;)Lkotlin/properties/ReadOnlyProperty; + public fun provideDelegate (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/reflect/KProperty;)Lkotlin/properties/ReadOnlyProperty; public synthetic fun provideDelegate (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; } @@ -846,11 +904,11 @@ public final class com/github/ajalt/clikt/parameters/groups/CoOccurringOptionGro public fun finalize (Lcom/github/ajalt/clikt/core/Context;Ljava/util/Map;)V public fun getGroupHelp ()Ljava/lang/String; public fun getGroupName ()Ljava/lang/String; - public fun getValue (Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; + public fun getValue (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; public synthetic fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; public fun parameterHelp (Lcom/github/ajalt/clikt/core/Context;)Lcom/github/ajalt/clikt/output/HelpFormatter$ParameterHelp$Group; public fun postValidate (Lcom/github/ajalt/clikt/core/Context;)V - public fun provideDelegate (Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/reflect/KProperty;)Lkotlin/properties/ReadOnlyProperty; + public fun provideDelegate (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/reflect/KProperty;)Lkotlin/properties/ReadOnlyProperty; public synthetic fun provideDelegate (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; } @@ -877,11 +935,11 @@ public final class com/github/ajalt/clikt/parameters/groups/MutuallyExclusiveOpt public fun finalize (Lcom/github/ajalt/clikt/core/Context;Ljava/util/Map;)V public fun getGroupHelp ()Ljava/lang/String; public fun getGroupName ()Ljava/lang/String; - public fun getValue (Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; + public fun getValue (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/reflect/KProperty;)Ljava/lang/Object; public synthetic fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; public fun parameterHelp (Lcom/github/ajalt/clikt/core/Context;)Lcom/github/ajalt/clikt/output/HelpFormatter$ParameterHelp$Group; public fun postValidate (Lcom/github/ajalt/clikt/core/Context;)V - public fun provideDelegate (Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/reflect/KProperty;)Lkotlin/properties/ReadOnlyProperty; + public fun provideDelegate (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/reflect/KProperty;)Lkotlin/properties/ReadOnlyProperty; public synthetic fun provideDelegate (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; } @@ -910,7 +968,7 @@ public final class com/github/ajalt/clikt/parameters/groups/ParameterGroup$Defau } public abstract interface class com/github/ajalt/clikt/parameters/groups/ParameterGroupDelegate : com/github/ajalt/clikt/parameters/groups/ParameterGroup, kotlin/properties/PropertyDelegateProvider, kotlin/properties/ReadOnlyProperty { - public abstract fun provideDelegate (Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/reflect/KProperty;)Lkotlin/properties/ReadOnlyProperty; + public abstract fun provideDelegate (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/reflect/KProperty;)Lkotlin/properties/ReadOnlyProperty; } public final class com/github/ajalt/clikt/parameters/groups/ParameterGroupDelegate$DefaultImpls { @@ -918,22 +976,20 @@ public final class com/github/ajalt/clikt/parameters/groups/ParameterGroupDelega } public final class com/github/ajalt/clikt/parameters/groups/ParameterGroupKt { - public static final fun provideDelegate (Lcom/github/ajalt/clikt/parameters/groups/OptionGroup;Lcom/github/ajalt/clikt/core/CliktCommand;Lkotlin/reflect/KProperty;)Lkotlin/properties/ReadOnlyProperty; + public static final fun provideDelegate (Lcom/github/ajalt/clikt/parameters/groups/OptionGroup;Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/reflect/KProperty;)Lkotlin/properties/ReadOnlyProperty; } public final class com/github/ajalt/clikt/parameters/options/EagerOptionKt { - public static final fun eagerOption (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/util/Collection;Ljava/lang/String;ZLjava/util/Map;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lcom/github/ajalt/clikt/core/CliktCommand; - public static final fun eagerOption (Lcom/github/ajalt/clikt/core/CliktCommand;[Ljava/lang/String;Ljava/lang/String;ZLjava/util/Map;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lcom/github/ajalt/clikt/core/CliktCommand; - public static synthetic fun eagerOption$default (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/util/Collection;Ljava/lang/String;ZLjava/util/Map;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/github/ajalt/clikt/core/CliktCommand; - public static synthetic fun eagerOption$default (Lcom/github/ajalt/clikt/core/CliktCommand;[Ljava/lang/String;Ljava/lang/String;ZLjava/util/Map;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/github/ajalt/clikt/core/CliktCommand; - public static final fun versionOption (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Lkotlin/jvm/functions/Function1;)Lcom/github/ajalt/clikt/core/CliktCommand; - public static synthetic fun versionOption$default (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/github/ajalt/clikt/core/CliktCommand; + public static final fun eagerOption (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Ljava/util/Collection;Ljava/lang/String;ZLjava/util/Map;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lcom/github/ajalt/clikt/core/BaseCliktCommand; + public static final fun eagerOption (Lcom/github/ajalt/clikt/core/BaseCliktCommand;[Ljava/lang/String;Ljava/lang/String;ZLjava/util/Map;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lcom/github/ajalt/clikt/core/BaseCliktCommand; + public static synthetic fun eagerOption$default (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Ljava/util/Collection;Ljava/lang/String;ZLjava/util/Map;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/github/ajalt/clikt/core/BaseCliktCommand; + public static synthetic fun eagerOption$default (Lcom/github/ajalt/clikt/core/BaseCliktCommand;[Ljava/lang/String;Ljava/lang/String;ZLjava/util/Map;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/github/ajalt/clikt/core/BaseCliktCommand; + public static final fun versionOption (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Lkotlin/jvm/functions/Function1;)Lcom/github/ajalt/clikt/core/BaseCliktCommand; + public static synthetic fun versionOption$default (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/github/ajalt/clikt/core/BaseCliktCommand; } public final class com/github/ajalt/clikt/parameters/options/FlagOptionKt { public static final fun convert (Lcom/github/ajalt/clikt/parameters/options/OptionWithValues;Lkotlin/jvm/functions/Function2;)Lcom/github/ajalt/clikt/parameters/options/OptionWithValues; - public static final fun counted (Lcom/github/ajalt/clikt/parameters/options/OptionWithValues;)Lcom/github/ajalt/clikt/parameters/options/OptionWithValues; - public static final fun counted (Lcom/github/ajalt/clikt/parameters/options/OptionWithValues;I)Lcom/github/ajalt/clikt/parameters/options/OptionWithValues; public static final fun counted (Lcom/github/ajalt/clikt/parameters/options/OptionWithValues;IZ)Lcom/github/ajalt/clikt/parameters/options/OptionWithValues; public static synthetic fun counted$default (Lcom/github/ajalt/clikt/parameters/options/OptionWithValues;IZILjava/lang/Object;)Lcom/github/ajalt/clikt/parameters/options/OptionWithValues; public static final fun flag (Lcom/github/ajalt/clikt/parameters/options/OptionWithValues;[Ljava/lang/String;ZLjava/lang/String;)Lcom/github/ajalt/clikt/parameters/options/OptionWithValues; @@ -1258,12 +1314,56 @@ public final class com/github/ajalt/clikt/parameters/types/UlongKt { public static synthetic fun ulong$default (Lcom/github/ajalt/clikt/parameters/options/OptionWithValues;ZILjava/lang/Object;)Lcom/github/ajalt/clikt/parameters/options/OptionWithValues; } -public final class com/github/ajalt/clikt/parsers/Invocation { +public final class com/github/ajalt/clikt/parsers/ArgumentInvocation { + public fun (Lcom/github/ajalt/clikt/parameters/arguments/Argument;Ljava/util/List;)V + public final fun getArgument ()Lcom/github/ajalt/clikt/parameters/arguments/Argument; + public final fun getValues ()Ljava/util/List; +} + +public final class com/github/ajalt/clikt/parsers/CommandInvocation { + public fun (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Ljava/util/Map;Ljava/util/List;Ljava/util/List;Ljava/util/List;)V + public final fun getArgumentInvocations ()Ljava/util/List; + public final fun getCommand ()Lcom/github/ajalt/clikt/core/BaseCliktCommand; + public final fun getErrors ()Ljava/util/List; + public final fun getOptionInvocations ()Ljava/util/Map; + public final fun getSubcommandInvocations ()Ljava/util/List; +} + +public final class com/github/ajalt/clikt/parsers/CommandLineParseResult { + public fun (Lcom/github/ajalt/clikt/parsers/CommandInvocation;Ljava/util/List;Ljava/util/List;)V + public final fun getExpandedArgv ()Ljava/util/List; + public final fun getInvocation ()Lcom/github/ajalt/clikt/parsers/CommandInvocation; + public final fun getOriginalArgv ()Ljava/util/List; +} + +public final class com/github/ajalt/clikt/parsers/CommandLineParser { + public static final field INSTANCE Lcom/github/ajalt/clikt/parsers/CommandLineParser; + public final fun finalize (Lcom/github/ajalt/clikt/parsers/CommandInvocation;)V + public final fun main (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/jvm/functions/Function1;)V + public final fun mainReturningValue (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public final fun parse (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Ljava/util/List;)Lcom/github/ajalt/clikt/parsers/CommandLineParseResult; + public final fun parseAndRun (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Ljava/util/List;Lkotlin/jvm/functions/Function1;)Lcom/github/ajalt/clikt/parsers/CommandLineParseResult; + public final fun run (Lcom/github/ajalt/clikt/parsers/CommandInvocation;Lkotlin/jvm/functions/Function1;)V + public final fun tokenize (Ljava/lang/String;Ljava/lang/String;Lcom/github/ajalt/clikt/output/Localization;)Ljava/util/List; + public static synthetic fun tokenize$default (Lcom/github/ajalt/clikt/parsers/CommandLineParser;Ljava/lang/String;Ljava/lang/String;Lcom/github/ajalt/clikt/output/Localization;ILjava/lang/Object;)Ljava/util/List; +} + +public final class com/github/ajalt/clikt/parsers/FlatInvocations : kotlin/sequences/Sequence { + public final fun close ()V + public fun iterator ()Ljava/util/Iterator; +} + +public final class com/github/ajalt/clikt/parsers/InvocationKt { + public static final fun flatten (Lcom/github/ajalt/clikt/parsers/CommandInvocation;Z)Lcom/github/ajalt/clikt/parsers/FlatInvocations; + public static synthetic fun flatten$default (Lcom/github/ajalt/clikt/parsers/CommandInvocation;ZILjava/lang/Object;)Lcom/github/ajalt/clikt/parsers/FlatInvocations; +} + +public final class com/github/ajalt/clikt/parsers/OptionInvocation { public fun (Ljava/lang/String;Ljava/util/List;)V public final fun component1 ()Ljava/lang/String; public final fun component2 ()Ljava/util/List; - public final fun copy (Ljava/lang/String;Ljava/util/List;)Lcom/github/ajalt/clikt/parsers/Invocation; - public static synthetic fun copy$default (Lcom/github/ajalt/clikt/parsers/Invocation;Ljava/lang/String;Ljava/util/List;ILjava/lang/Object;)Lcom/github/ajalt/clikt/parsers/Invocation; + public final fun copy (Ljava/lang/String;Ljava/util/List;)Lcom/github/ajalt/clikt/parsers/OptionInvocation; + public static synthetic fun copy$default (Lcom/github/ajalt/clikt/parsers/OptionInvocation;Ljava/lang/String;Ljava/util/List;ILjava/lang/Object;)Lcom/github/ajalt/clikt/parsers/OptionInvocation; public fun equals (Ljava/lang/Object;)Z public final fun getName ()Ljava/lang/String; public final fun getValues ()Ljava/util/List; @@ -1277,9 +1377,6 @@ public final class com/github/ajalt/clikt/sources/ChainedValueSource : com/githu public fun getValues (Lcom/github/ajalt/clikt/core/Context;Lcom/github/ajalt/clikt/parameters/options/Option;)Ljava/util/List; } -public abstract interface annotation class com/github/ajalt/clikt/sources/ExperimentalValueSourceApi : java/lang/annotation/Annotation { -} - public final class com/github/ajalt/clikt/sources/MapValueSource : com/github/ajalt/clikt/sources/ValueSource { public fun (Ljava/util/Map;Lkotlin/jvm/functions/Function2;)V public synthetic fun (Ljava/util/Map;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -1345,9 +1442,11 @@ public final class com/github/ajalt/clikt/testing/CliktCommandTestResult { } public final class com/github/ajalt/clikt/testing/CliktTestingKt { + public static final fun test (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Ljava/util/List;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IILkotlin/jvm/functions/Function1;)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; public static final fun test (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;II)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; public static final fun test (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/util/List;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;II)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; public static final fun test (Lcom/github/ajalt/clikt/core/CliktCommand;[Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;II)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; + public static synthetic fun test$default (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Ljava/util/List;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IILkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; public static synthetic fun test$default (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IIILjava/lang/Object;)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; public static synthetic fun test$default (Lcom/github/ajalt/clikt/core/CliktCommand;Ljava/util/List;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IIILjava/lang/Object;)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; public static synthetic fun test$default (Lcom/github/ajalt/clikt/core/CliktCommand;[Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ZLcom/github/ajalt/mordant/rendering/AnsiLevel;IIILjava/lang/Object;)Lcom/github/ajalt/clikt/testing/CliktCommandTestResult; diff --git a/clikt/build.gradle.kts b/clikt/build.gradle.kts index db1dd7890..330ca46e0 100644 --- a/clikt/build.gradle.kts +++ b/clikt/build.gradle.kts @@ -38,6 +38,8 @@ kotlin { dependencies { api(kotlin("test")) api(libs.kotest) + api(libs.coroutines.core) + api(libs.coroutines.test) } } diff --git a/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/command/ChainedCliktCommand.kt b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/command/ChainedCliktCommand.kt new file mode 100644 index 000000000..816051a2b --- /dev/null +++ b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/command/ChainedCliktCommand.kt @@ -0,0 +1,171 @@ +package com.github.ajalt.clikt.command + +import com.github.ajalt.clikt.core.* +import com.github.ajalt.clikt.parsers.CommandLineParser +import com.github.ajalt.clikt.testing.CliktCommandTestResult +import com.github.ajalt.clikt.testing.test +import com.github.ajalt.mordant.rendering.AnsiLevel + +/** + * A version of [CliktCommand] that returns a value from the [run] function, which is then passed to + * subcommands. + * + * This command works best if you set [allowMultipleSubcommands] to `true`. + */ +abstract class ChainedCliktCommand( + /** + * The name of the program to use in the help output. If not given, it is inferred from the + * class name. + */ + name: String? = null, +) : BaseCliktCommand>(name) { + /** + * Perform actions after parsing is complete and this command is invoked. + * + * This takes the value returned by the previously invoked command and returns a new value. + * + * This is called after command line parsing is complete. If this command is a subcommand, this + * will only be called if the subcommand is invoked. + * + * If one of this command's subcommands is invoked, this is called before the subcommand's + * arguments are parsed. + */ + abstract fun run(value: T): T +} + + +/** + * Parse the command line and print helpful output if any errors occur. + * + * This function calls [parse] and catches any [CliktError]s that are thrown, exiting the process + * with the specified [status code][CliktError.statusCode]. Other errors are allowed to pass + * through. + * + * If you don't want Clikt to exit your process, call [parse] instead. + */ +fun ChainedCliktCommand.main(argv: List, initial: T): T { + return CommandLineParser.mainReturningValue(this) { parse(argv, initial) } +} + +/** + * Parse the command line and print helpful output if any errors occur. + * + * This function calls [parse] and catches any [CliktError]s that are thrown, exiting the process + * with the specified [status code][CliktError.statusCode]. Other errors are allowed to pass + * through. + * + * If you don't want Clikt to exit your process, call [parse] instead. + */ +fun ChainedCliktCommand.main(argv: Array, initial: T): T { + return main(argv.asList(), initial) +} + +/** + * Parse the command line and throw an exception if parsing fails. + * + * You should use [main] instead unless you want to handle output yourself. + */ +fun ChainedCliktCommand.parse(argv: Array, initial: T): T { + return parse(argv.asList(), initial) +} + +/** + * Parse the command line and throw an exception if parsing fails. + * + * You should use [main] instead unless you want to handle output yourself. + */ +fun ChainedCliktCommand.parse(argv: List, initial: T): T { + var value = initial + CommandLineParser.parseAndRun(this, argv) { value = it.run(value) } + return value +} + + +/** + * Test this command, returning a result that captures the output and result status code. + * + * Note that only output printed with [echo][CliktCommand.echo] will be captured. Anything printed + * with [print] or [println] is not. + * + * @param argv The command line to send to the command + * @param stdin Content of stdin that will be read by prompt options. Multiple inputs should be separated by `\n`. + * @param envvars A map of environment variable name to value for envvars that can be read by the command + * @param includeSystemEnvvars Set to true to include the environment variables from the system in addition to those + * defined in [envvars] + * @param ansiLevel Defaults to no colored output; set to [AnsiLevel.TRUECOLOR] to include ANSI codes in the output. + * @param width The width of the terminal, used to wrap text + * @param height The height of the terminal + */ +fun ChainedCliktCommand.test( + argv: String, + initial: T, + stdin: String = "", + envvars: Map = emptyMap(), + includeSystemEnvvars: Boolean = false, + ansiLevel: AnsiLevel = AnsiLevel.NONE, + width: Int = 79, + height: Int = 24, +): CliktCommandTestResult { + val argvArray = CommandLineParser.tokenize(argv) + return test(argvArray, initial, stdin, envvars, includeSystemEnvvars, ansiLevel, width, height) +} + +/** + * Test this command, returning a result that captures the output and result status code. + * + * Note that only output printed with [echo][CliktCommand.echo] will be captured. Anything printed + * with [print] or [println] is not. + * + * @param argv The command line to send to the command + * @param stdin Content of stdin that will be read by prompt options. Multiple inputs should be separated by `\n`. + * @param envvars A map of environment variable name to value for envvars that can be read by the command + * @param includeSystemEnvvars Set to true to include the environment variables from the system in addition to those + * defined in [envvars] + * @param ansiLevel Defaults to no colored output; set to [AnsiLevel.TRUECOLOR] to include ANSI codes in the output. + * @param width The width of the terminal, used to wrap text + * @param height The height of the terminal + */ +fun ChainedCliktCommand.test( + argv: Array, + initial: T, + stdin: String = "", + envvars: Map = emptyMap(), + includeSystemEnvvars: Boolean = false, + ansiLevel: AnsiLevel = AnsiLevel.NONE, + width: Int = 79, + height: Int = 24, +): CliktCommandTestResult { + return test( + argv.asList(), initial, stdin, envvars, includeSystemEnvvars, ansiLevel, width, height + ) +} + +/** + * Test this command, returning a result that captures the output and result status code. + * + * Note that only output printed with [echo][CliktCommand.echo] will be captured. Anything printed + * with [print] or [println] is not. + * + * @param argv The command line to send to the command + * @param stdin Content of stdin that will be read by prompt options. Multiple inputs should be separated by `\n`. + * @param envvars A map of environment variable name to value for envvars that can be read by the command + * @param includeSystemEnvvars Set to true to include the environment variables from the system in addition to those + * defined in [envvars] + * @param ansiLevel Defaults to no colored output; set to [AnsiLevel.TRUECOLOR] to include ANSI codes in the output. + * @param width The width of the terminal, used to wrap text + * @param height The height of the terminal + */ +fun ChainedCliktCommand.test( + argv: List, + initial: T, + stdin: String = "", + envvars: Map = emptyMap(), + includeSystemEnvvars: Boolean = false, + ansiLevel: AnsiLevel = AnsiLevel.NONE, + width: Int = 79, + height: Int = 24, +): CliktCommandTestResult { + return test(argv, stdin, envvars, includeSystemEnvvars, ansiLevel, width, height) { + parse(it, initial) + } +} diff --git a/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/command/SuspendingCliktCommand.kt b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/command/SuspendingCliktCommand.kt new file mode 100644 index 000000000..8c5de46af --- /dev/null +++ b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/command/SuspendingCliktCommand.kt @@ -0,0 +1,156 @@ +package com.github.ajalt.clikt.command + +import com.github.ajalt.clikt.core.* +import com.github.ajalt.clikt.parsers.CommandLineParser +import com.github.ajalt.clikt.testing.CliktCommandTestResult +import com.github.ajalt.clikt.testing.test +import com.github.ajalt.mordant.rendering.AnsiLevel + +/** + * A version of [CliktCommand] that supports a suspending [run] function. + */ +abstract class SuspendingCliktCommand( + /** + * The name of the program to use in the help output. If not given, it is inferred from the + * class name. + */ + name: String? = null, +) : BaseCliktCommand(name) { + /** + * Perform actions after parsing is complete and this command is invoked. + * + * This is called after command line parsing is complete. If this command is a subcommand, this + * will only be called if the subcommand is invoked. + * + * If one of this command's subcommands is invoked, this is called before the subcommand's + * arguments are parsed. + */ + abstract suspend fun run() +} + + +/** + * Parse the command line and print helpful output if any errors occur. + * + * This function calls [parse] and catches any [CliktError]s that are thrown, exiting the process + * with the specified [status code][CliktError.statusCode]. Other errors are allowed to pass + * through. + * + * If you don't want Clikt to exit your process, call [parse] instead. + */ +suspend fun SuspendingCliktCommand.main(argv: List) { + CommandLineParser.main(this) { parse(argv) } +} + +/** + * Parse the command line and print helpful output if any errors occur. + * + * This function calls [parse] and catches any [CliktError]s that are thrown, exiting the process + * with the specified [status code][CliktError.statusCode]. Other errors are allowed to pass + * through. + * + * If you don't want Clikt to exit your process, call [parse] instead. + */ +suspend fun SuspendingCliktCommand.main(argv: Array) = main(argv.asList()) + +/** + * Parse the command line and throw an exception if parsing fails. + * + * You should use [main] instead unless you want to handle output yourself. + */ +suspend fun SuspendingCliktCommand.parse(argv: Array) { + parse(argv.asList()) +} + +/** + * Parse the command line and throw an exception if parsing fails. + * + * You should use [main] instead unless you want to handle output yourself. + */ +suspend fun SuspendingCliktCommand.parse(argv: List) { + CommandLineParser.parseAndRun(this, argv) { it.run() } +} + +/** + * Test this command, returning a result that captures the output and result status code. + * + * Note that only output printed with [echo][CliktCommand.echo] will be captured. Anything printed with [print] or + * [println] is not. + * + * @param argv The command line to send to the command + * @param stdin Content of stdin that will be read by prompt options. Multiple inputs should be separated by `\n`. + * @param envvars A map of environment variable name to value for envvars that can be read by the command + * @param includeSystemEnvvars Set to true to include the environment variables from the system in addition to those + * defined in [envvars] + * @param ansiLevel Defaults to no colored output; set to [AnsiLevel.TRUECOLOR] to include ANSI codes in the output. + * @param width The width of the terminal, used to wrap text + * @param height The height of the terminal + */ +suspend fun SuspendingCliktCommand.test( + argv: String, + stdin: String = "", + envvars: Map = emptyMap(), + includeSystemEnvvars: Boolean = false, + ansiLevel: AnsiLevel = AnsiLevel.NONE, + width: Int = 79, + height: Int = 24, +): CliktCommandTestResult { + val argvArray = CommandLineParser.tokenize(argv) + return test(argvArray, stdin, envvars, includeSystemEnvvars, ansiLevel, width, height) +} + +/** + * Test this command, returning a result that captures the output and result status code. + * + * Note that only output printed with [echo][CliktCommand.echo] will be captured. Anything printed with [print] or + * [println] is not. + * + * @param argv The command line to send to the command + * @param stdin Content of stdin that will be read by prompt options. Multiple inputs should be separated by `\n`. + * @param envvars A map of environment variable name to value for envvars that can be read by the command + * @param includeSystemEnvvars Set to true to include the environment variables from the system in addition to those + * defined in [envvars] + * @param ansiLevel Defaults to no colored output; set to [AnsiLevel.TRUECOLOR] to include ANSI codes in the output. + * @param width The width of the terminal, used to wrap text + * @param height The height of the terminal + */ +suspend fun SuspendingCliktCommand.test( + argv: Array, + stdin: String = "", + envvars: Map = emptyMap(), + includeSystemEnvvars: Boolean = false, + ansiLevel: AnsiLevel = AnsiLevel.NONE, + width: Int = 79, + height: Int = 24, +): CliktCommandTestResult { + return test(argv.asList(), stdin, envvars, includeSystemEnvvars, ansiLevel, width, height) +} + +/** + * Test this command, returning a result that captures the output and result status code. + * + * Note that only output printed with [echo][CliktCommand.echo] will be captured. Anything printed with [print] or + * [println] is not. + * + * @param argv The command line to send to the command + * @param stdin Content of stdin that will be read by prompt options. Multiple inputs should be separated by `\n`. + * @param envvars A map of environment variable name to value for envvars that can be read by the command + * @param includeSystemEnvvars Set to true to include the environment variables from the system in addition to those + * defined in [envvars] + * @param ansiLevel Defaults to no colored output; set to [AnsiLevel.TRUECOLOR] to include ANSI codes in the output. + * @param width The width of the terminal, used to wrap text + * @param height The height of the terminal + */ +suspend fun SuspendingCliktCommand.test( + argv: List, + stdin: String = "", + envvars: Map = emptyMap(), + includeSystemEnvvars: Boolean = false, + ansiLevel: AnsiLevel = AnsiLevel.NONE, + width: Int = 79, + height: Int = 24, +): CliktCommandTestResult { + return test(argv, stdin, envvars, includeSystemEnvvars, ansiLevel, width, height) { + parse(it) + } +} diff --git a/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/BashCompletionGenerator.kt b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/BashCompletionGenerator.kt index 3034516ca..db5d2d30b 100644 --- a/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/BashCompletionGenerator.kt +++ b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/BashCompletionGenerator.kt @@ -1,11 +1,11 @@ package com.github.ajalt.clikt.completion import com.github.ajalt.clikt.completion.CompletionCandidates.Custom.ShellType -import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.core.BaseCliktCommand import com.github.ajalt.clikt.parameters.options.Option internal object BashCompletionGenerator { - fun generateBashOrZshCompletion(command: CliktCommand, zsh: Boolean): String { + fun generateBashOrZshCompletion(command: BaseCliktCommand<*>, zsh: Boolean): String { val commandName = command.commandName val (isTopLevel, funcName) = commandCompletionFuncName(command) val options = command._options @@ -297,7 +297,7 @@ internal object BashCompletionGenerator { } } - private fun commandCompletionFuncName(command: CliktCommand): Pair { + private fun commandCompletionFuncName(command: BaseCliktCommand<*>): Pair { val ancestors = generateSequence(command.currentContext) { it.parent } .map { it.command.commandName } .toList().asReversed() diff --git a/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/CompletionBuiltins.kt b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/CompletionBuiltins.kt index 815b41d4d..e2bbd04d7 100644 --- a/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/CompletionBuiltins.kt +++ b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/CompletionBuiltins.kt @@ -1,6 +1,8 @@ package com.github.ajalt.clikt.completion +import com.github.ajalt.clikt.core.BaseCliktCommand import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.core.Context import com.github.ajalt.clikt.parameters.arguments.argument import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.options.validate @@ -11,13 +13,15 @@ private val choices = arrayOf("bash", "zsh", "fish") /** * Add an option to a command that will print a completion script for the given shell when invoked. */ -fun T.completionOption( +fun > T.completionOption( vararg names: String = arrayOf("--generate-completion"), help: String = "", hidden: Boolean = false, ): T = apply { - registerOption(option(*names, help = help, hidden = hidden, eager = true, - metavar = choices.joinToString("|", prefix = "(", postfix = ")")).validate { + registerOption(option( + *names, help = help, hidden = hidden, eager = true, + metavar = choices.joinToString("|", prefix = "(", postfix = ")") + ).validate { CompletionGenerator.throwCompletionMessage(context.command, it) }) } @@ -26,10 +30,12 @@ fun T.completionOption( * A subcommand that will print a completion script for the given shell when invoked. */ class CompletionCommand( - help: String = "Generate a tab-complete script for the given shell", - epilog: String = "", + private val help: String = "Generate a tab-complete script for the given shell", + private val epilog: String = "", name: String = "generate-completion", -) : CliktCommand(help, epilog, name) { +) : CliktCommand(name) { + override fun help(context: Context): String = help + override fun helpEpilog(context: Context): String = epilog private val shell by argument("shell").choice(*choices) override fun run() { val cmd = currentContext.parent?.command ?: this diff --git a/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/CompletionCandidates.kt b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/CompletionCandidates.kt index b5271fa22..c1d7052e5 100644 --- a/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/CompletionCandidates.kt +++ b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/CompletionCandidates.kt @@ -1,11 +1,5 @@ package com.github.ajalt.clikt.completion -@RequiresOptIn -@Retention(AnnotationRetention.BINARY) -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) -@Deprecated(message = "This opt-in requirement is not used anymore. Remove its usages from your code.") -annotation class ExperimentalCompletionCandidates - /** * Configurations for generating shell autocomplete suggestions */ diff --git a/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/CompletionGenerator.kt b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/CompletionGenerator.kt index 24ed45e2b..04bba838b 100644 --- a/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/CompletionGenerator.kt +++ b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/CompletionGenerator.kt @@ -1,10 +1,14 @@ package com.github.ajalt.clikt.completion -import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.core.BaseCliktCommand import com.github.ajalt.clikt.core.PrintCompletionMessage internal object CompletionGenerator { - fun throwCompletionMessage(command: CliktCommand, shell: String): Nothing { + fun throwCompletionMessage(command: BaseCliktCommand<*>, shell: String): Nothing { + throw getCompletionMessage(command, shell) + } + + fun getCompletionMessage(command: BaseCliktCommand<*>, shell: String): PrintCompletionMessage { val message = when (shell.trim().lowercase()) { "fish" -> FishCompletionGenerator.generateFishCompletion(command = command) "zsh" -> BashCompletionGenerator.generateBashOrZshCompletion( @@ -17,6 +21,6 @@ internal object CompletionGenerator { zsh = false ) } - throw PrintCompletionMessage(message) + return PrintCompletionMessage(message) } } diff --git a/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/FishCompletionGenerator.kt b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/FishCompletionGenerator.kt index 67c18c6e3..dc7b0b9f8 100644 --- a/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/FishCompletionGenerator.kt +++ b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/completion/FishCompletionGenerator.kt @@ -1,17 +1,17 @@ package com.github.ajalt.clikt.completion import com.github.ajalt.clikt.completion.CompletionCandidates.Custom.ShellType -import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.core.BaseCliktCommand import com.github.ajalt.clikt.parameters.options.Option internal object FishCompletionGenerator { - fun generateFishCompletion(command: CliktCommand): String { + fun generateFishCompletion(command: BaseCliktCommand<*>): String { if (!command.hasFishCompletionRequirements) return "" return generateFishCompletionForCommand(command) } - private fun generateFishCompletionForCommand(command: CliktCommand): String = buildString { + private fun generateFishCompletionForCommand(command: BaseCliktCommand<*>): String = buildString { val parentCommandName = command.currentContext.parentNames().lastOrNull() val rootCommandName = command.currentContext.commandNameWithParents().first() val isTopLevel = parentCommandName == null @@ -56,7 +56,7 @@ internal object FishCompletionGenerator { append("-a $commandName ") - val help = command.commandHelp(command.currentContext).replace("'", "\\'") + val help = command.help(command.currentContext).replace("'", "\\'") if (help.isNotBlank()) { append("-d '${help}'") } @@ -171,7 +171,7 @@ internal object FishCompletionGenerator { return joinToString("_", postfix = "_subcommands") { it.replace(Regex("\\W"), "_") } } - private val CliktCommand.hasFishCompletionRequirements: Boolean + private val BaseCliktCommand<*>.hasFishCompletionRequirements: Boolean get() = _arguments.isNotEmpty() || _subcommands.isNotEmpty() || _options.flatMap { it.allNames }.any { it.isValidFishCompletionOption } diff --git a/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/core/BaseCliktCommand.kt b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/core/BaseCliktCommand.kt new file mode 100644 index 000000000..b23ab0713 --- /dev/null +++ b/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/core/BaseCliktCommand.kt @@ -0,0 +1,411 @@ +package com.github.ajalt.clikt.core + +import com.github.ajalt.clikt.output.HelpFormatter +import com.github.ajalt.clikt.parameters.arguments.Argument +import com.github.ajalt.clikt.parameters.arguments.argument +import com.github.ajalt.clikt.parameters.groups.OptionGroup +import com.github.ajalt.clikt.parameters.groups.ParameterGroup +import com.github.ajalt.clikt.parameters.options.Option +import com.github.ajalt.clikt.parameters.options.eagerOption +import com.github.ajalt.clikt.parameters.options.option +import com.github.ajalt.mordant.terminal.Terminal + +/** + * A base class for commands that want to define a custom type for their `run` function. + */ +@Suppress("PropertyName") +@ParameterHolderDsl +abstract class BaseCliktCommand>( + /** + * The name of the program to use in the help output. If not given, it is inferred from the + * class name. + */ + name: String? = null, +) : ParameterHolder { + /** + * The name of this command, used in help output. + * + * By default, this is the lowercase name of the class, with "Command" removed if it's present + */ + val commandName: String = name?.takeIf { it.isNotBlank() } ?: inferCommandName() + + /** + * The help text for this command. + * + * ### Example: + * + * ``` + * class Command: CliktCommand() { + * override fun commandHelp(context: Context): String { + * return context.theme.info("This is a command") + * } + * } + * ``` + */ + open fun help(context: Context): String = "" + + @Deprecated("Method renamed to `help`", ReplaceWith("help(context)")) + open fun commandHelp(context: Context): String = help(context) + + /** + * Help text to display at the end of the help output, after any parameters. + */ + open fun helpEpilog(context: Context): String = "" + + @Deprecated("Method renamed to `helpEpilog`", ReplaceWith("helpEpilog(context)")) + open fun commandHelpEpilog(context: Context): String = helpEpilog(context) + + /** + * Used when this command has subcommands, and this command is called without a subcommand. If + * true, [run] will be called. By default, a [PrintHelpMessage] is thrown instead. + */ + open val invokeWithoutSubcommand: Boolean = false + + /** + * If this command is called with no values on the command line, print a help message (by + * throwing [PrintHelpMessage]) if this is `true`, otherwise run normally. + */ + open val printHelpOnEmptyArgs: Boolean = false + + /** + * Extra information about this command to pass to the help formatter. + */ + open val helpTags: Map = emptyMap() + + /** + * The envvar to use to enable shell autocomplete script generation. Set to null to disable + * generation. + */ + open val autoCompleteEnvvar: String? = "" + + /** + * If true, allow multiple of this command's subcommands to be called sequentially. This will + * disable `allowInterspersedArgs` on the context of this command and its descendants. + */ + open val allowMultipleSubcommands: Boolean = false + + /** + * If true, any options on the command line whose names aren't valid will be parsed as an + * argument rather than reporting an error. You'll need to define an `argument().multiple()` to + * collect these options, or an error will still be reported. Unknown short option flags grouped + * with other flags on the command line will always be reported as errors. + */ + open val treatUnknownOptionsAsArgs: Boolean = false + + /** + * If true, don't display this command in help output when used as a subcommand. + */ + open val hiddenFromHelp: Boolean = false + + internal var _subcommands: List = emptyList() + internal val _options: MutableList