Multiplatform command line interface parsing for Kotlin

Overview

Clikt (pronounced "clicked") is a multiplatform Kotlin library that makes writing command line interfaces simple and intuitive. It's the "Command Line Interface for Kotlin".

It is designed to make the process of writing command line tools effortless while supporting a wide variety of use cases and allowing advanced customization when needed.

Clikt has:

  • arbitrary nesting of commands
  • composable, type safe parameter values
  • generation of help output and shell autocomplete scripts
  • multiplatform packages for JVM, NodeJS, and native Linux, Windows and MacOS

What does it look like? Here's a complete example of a simple Clikt program:

class Hello : CliktCommand() {
    val count: Int by option(help="Number of greetings").int().default(1)
    val name: String by option(help="The person to greet").prompt("Your name")

    override fun run() {
        repeat(count) {
            echo("Hello $name!")
        }
    }
}

fun main(args: Array<String>) = Hello().main(args)

And here's what it looks like when run:

 $ ./hello --count=3
 Your name: John
 Hello John!
 Hello John!
 Hello John!

The help page is generated for you:

$ ./hello --help
Usage: hello [OPTIONS]

Options:
  --count INT  Number of greetings
  --name TEXT  The person to greet
  -h, --help   Show this message and exit

Errors are also taken care of:

$ ./hello --whoops
Usage: hello [OPTIONS]

Error: no such option: "--whoops".

Documentation

The full documentation can be found on the website.

There are also a number of sample applications. You can run them with the included runsample script.

Installation

Clikt is distributed through Maven Central.

dependencies {
   implementation("com.github.ajalt.clikt:clikt:3.3.0")
}
In version 3.0, the maven coordinates changed. Make sure you're using the new coordinates if you're updating from an older version.
If you're using Maven instead of Gradle, use <artifactId>clikt-jvm</artifactId>

Multiplatform

Clikt supports the following targets: jvm, mingwX64, linuxX64, macosX64, and js (for both NodeJS and Browsers). See the docs for more information about functionality supported on each target. You'll need to use Gradle 6 or newer.

Snapshots

Snapshot builds are also available

You'll need to add the Sonatype snapshots repository:

repositories {
    maven {
        url = uri("https://oss.sonatype.org/content/repositories/snapshots/")
    }
}

License

Copyright 2018-2021 AJ Alt

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Idea: Allow root options to be passed to subcommands

    Idea: Allow root options to be passed to subcommands

    For user convenience, it might make sense to allow passing global options as if they were sub-command options. For example, instead of requiring the user to write

    command --root-option subcommand --sub-option
    

    clikt could allow to write

    command subcommand --root-option --sub-option
    

    This would work unless there is an option name clash between the global command and the sub-command, in which case the sub-command-specific option should take precedence.

    AFAIK there's currently no elegant way to achieve this in clikt, so maybe it makes sense to implement this as a core feature toggle on the context, like subcommandsInheritGlobalOptions or allowGlobalOptionsForSubcommands.

    opened by sschuberth 17
  • Support manual paragraph breaks in help output.

    Support manual paragraph breaks in help output.

    Not an issue, rather a question:

    Example

    CliktCommand(help = "Sentence1.\nSentence2.")
    

    Will generate help text without the newline characters. I have tried \n and \r. Am I asking for the impossible (im not familiar with cli low lvl impl) or am I doing something wrong?

    I am trying this with gitbash on Windows.

    opened by sghpjuikit 17
  • Clikt versions 2.5.0+ not available on JCenter

    Clikt versions 2.5.0+ not available on JCenter

    Following version 2.40, it appears the releases of Clikt on JCenter haven't been kept up-to-date. Would it be possible to make the last few releases available?

    opened by miknoj 13
  • Consider reworking arguments to file()

    Consider reworking arguments to file()

    I'm always having trouble remembering what checks exactly are performed for the different parameters to file(). For example, does exists = false check whether the file does not exist and fail otherwise? (No, it does not.) While that's part of the documentation, I believe this could be made more clear by renaming parameters. How about:

    • exists -> verifyExists
    • fileOkay -> canBeFile
    • folderOkay -> canBeDir
    • writable -> mustBeWritable
    • readable -> mustBeReadable
    opened by sschuberth 13
  • file() verification should be able to expand a leading tilde (~)

    file() verification should be able to expand a leading tilde (~)

    file() currently fails for a path like ~/my-file.txt as ~ is not expanded. It would be great if ~ would be expanded when running on shells that support it similar to like we do here, maybe by introducing an expandTilde parameter to file() which defaults to true.

    opened by sschuberth 11
  • NonInteractiveCliktConsole only reads in the first line from an input file

    NonInteractiveCliktConsole only reads in the first line from an input file

    Currently the NonInteractiveCliktConsole only reads in the first line of any input file passed as the input stream.

    This can be fixed by caching the buffered reader like I have below.

    class NonInteractiveCliktConsole : CliktConsole {
        private val bufferedReader by lazy {
            System.`in`.bufferedReader()
        }
    
        override fun promptForLine(prompt: String, hideInput: Boolean) = try {
            print(prompt, false)
            bufferedReader.readLine()
        } catch (err: IOException) {
            null
        }
    
        override fun print(text: String, error: Boolean) {
            if (error) {
                System.err
            } else {
                System.out
            }.print(text)
        }
    
        override val lineSeparator: String get() = System.lineSeparator()
    }
    

    I'm using version 1.5.0.

    opened by JLLeitschuh 10
  • Options must come before arguments

    Options must come before arguments

    Am I doing something wrong or do I need to specify options before arguments in command? And if so, is it somewhere in the documentation and I am just blind?

    Example code:

    private val files by argument().file().pair()
    private val offsets by argument().int().pair()
    private val length by argument().int()    // should be optional integer
    private val display by option().switch("-f" to First, "-l" to Largest).default(None)
    

    The idea is to be able to do cmd path1 path2 0 0 1024 -f or cmd path1 path2 0 0 -f but it doesn't seem to work unless I put the flag in the front: cmd -f path1 path2 0 0 1024.

    If this is some limitation of the parser it should be stated clearly in the docs. If this should work, can anyone point me in the right direction?

    opened by lsrom 8
  • No such method error in tests (with Kotest)

    No such method error in tests (with Kotest)

    I thing something is wrong between Kotest 4.2.4 and Clikt 3.0.1

    Then I'm wrtiting this class in the test sources directory:

    class ATestCommand : CliktCommand() {
        private val environment: String? by option("-e", "--env")
        override fun run() {
            println("Env: $environment")
        }
    }
    

    gives an intellj error on option:

    Overload resolution ambiguity: 
    public fun ParameterHolder.option(vararg names: String, help: String = ..., metavar: String? = ..., hidden: Boolean = ..., envvar: String? = ..., helpTags: Map<String, String> = ..., completionCandidates: CompletionCandidates? = ..., valueSourceKey: String? = ...): RawOption /* = OptionWithValues<String?, String, String> */ defined in com.github.ajalt.clikt.parameters.options
    public fun ParameterHolder.option(vararg names: String, help: String = ..., metavar: String? = ..., hidden: Boolean = ..., envvar: String? = ..., envvarSplit: Regex? = ..., helpTags: Map<String, String> = ..., completionCandidates: CompletionCandidates? = ...): RawOption /* = OptionWithValues<String?, String, String> */ defined in com.github.ajalt.clikt.parameters.options
    

    Same class in source no problem.

    Noticed that while was trying to figure out why I can't run any test on a command.

    when I run the test:

    class ATestCommandTest() : FunSpec({
        test("test should run without throwing NoSuchMethodError") {
            ATestCommand().parse(emptyArray())
        }
    })
    

    I got the error:

    'com.github.ajalt.clikt.parameters.options.OptionWithValues com.github.ajalt.clikt.parameters.options.OptionWithValuesKt.option$default(com.github.ajalt.clikt.core.ParameterHolder, java.lang.String[], java.lang.String, java.lang.String, boolean, java.lang.String, java.util.Map, com.github.ajalt.clikt.completion.CompletionCandidates, java.lang.String, int, java.lang.Object)'
    java.lang.NoSuchMethodError: 'com.github.ajalt.clikt.parameters.options.OptionWithValues com.github.ajalt.clikt.parameters.options.OptionWithValuesKt.option$default(com.github.ajalt.clikt.core.ParameterHolder, java.lang.String[], java.lang.String, java.lang.String, boolean, java.lang.String, java.util.Map, com.github.ajalt.clikt.completion.CompletionCandidates, java.lang.String, int, java.lang.Object)'
    

    This does not happen if I use JUnit 5 in place of Kotest.

    My build.gradle.kts (useful parts)

    plugins {
        application
        kotlin("jvm") version "1.4.10"
    }
    // ...
    dependencies {
        implementation("com.github.ajalt.clikt:clikt:3.0.1")
        implementation("com.typesafe:config:1.4.0")
    
        testImplementation("io.kotest:kotest-runner-junit5:4.2.4") // for kotest framework
        testImplementation("io.kotest:kotest-assertions-core:4.2.4") // for kotest core jvm assertions
        testImplementation("io.kotest:kotest-property:4.2.4") // for kotest property test
        testImplementation("io.mockk:mockk:1.10.0")
    }
    // ...
    tasks.withType<KotlinCompile>() {
        kotlinOptions.jvmTarget = "11"
    }
    
    tasks.withType<Test>() {
        useJUnitPlatform()
    }
    // ...
    
    

    Thanks

    opened by razvn 8
  • Add localization support

    Add localization support

    Here's my first stab at supporting i18n of Clikt output.

    All exceptions and conversions now pull their strings from a Localization object configured on the current context. Right now, that object is an interface with all default methods. This should allow me to add strings in the future without breaking ABI compatibility. I kept all logic other than simple string interpolation out of the Localization implementation, although that leads to some weirdness when dealing with plurals and lists values.

    For example, the error message when too many arguments are present is currently split into two:

    fun extraArgumentOne(name: String) = "Got unexpected extra argument $name"
    fun extraArgumentMany(name: String, count: Int) = "Got unexpected extra arguments $name"
    

    But languages that pluralize differently than english will need to add some logic to extraArgumentMany anyway, so maybe it's better to combine those two functions.

    Joining sentences together is also introduces some redundancy. For example, the error when you type an option that doesn't exist might include typo corrections. Right now, there are two functions:

    fun noSuchOption(name: String) = "no such option: $name"
    fun noSuchOption(name: String, suggestion: String) = "no such option: $name. $suggestion"
    

    Maybe it would be better to make the suggestion parameter nullable and let the implementations deal with it?

    The last problem is when joining lists. For example, the suggestions for typo correction are a list of names. Right now the prefix and postfix are separate strings, and the caller joins them:

    fun possibleOptionsPrefix() = "(Possible options: "
    fun possibleParameterPostfix() = ")"
    

    That feels clunky. Maybe it would be better to just pass in the list of items and have the implementation join them?

    Finally, there are a couple of places that define strings that aren't in the Localization. The CliktHelpFormatter has a few constructor parameters for things like the usageTitle. We could read those from Localization, but other help formatters might not need those strings, so maybe it's better to leave them separate.

    The other place that doesn't read from Localization is the metavar parameters to option() and convert(). There's no context at the time options are defined, so I'm not sure what to do here. We could change the parameter from String to (Context) -> String, although that's kind of clunky. As-is, you'll have to manually specify the metavar for every option if you want it localized.

    Fixes #227

    opened by ajalt 8
  • Browser target

    Browser target

    Hi,

    any chance of supporting the browser target, even with reduced functionality?

    Would be very handy for me because I like to have a small shell in my SPA-s so I can issue commands manually, no need to build a whole interface. It is very similar to a terminal.

    I've checked kotlinx.cli and it is very "noisy".

    Thanks in advance, tiz

    opened by toth-istvan-zoltan 8
  • Customizing exit codes

    Customizing exit codes

    Thanks for writing this library. I was wondering if you have / would consider making it possible to test error handling and custom return codes?

    The idea is when implementing a CliktComand or including it into another library / framework for their users would want to do the following:

    • Provide a facility for custom exit codes, making it easier for automation down the road to use that to make decisions, for instance some errors might be worth retrying
    • Test that error messages and codes are being generated correctly, this is mostly checking exception logic

    Challenges & Possible Solutions

    Challenges I've encountered so far and some thoughts towards a solution, but those solutions themselves have accompanying issues:

    • main functions in CliktCommand are final making it hard
    • main(List), parse, and run do not return numbers so exit codes can't be seamlessly passed through
    • CliktError, Abort, and friends don't accept return codes -- these should probably be optional parameters (defaulted to current codes)
    • main(List) calls exitProcess making the logic not testable indirectly (less of a concern for library consumers) but going down a path of an extensible and testable strategy it might be worth returning the exit code to main(Array) and it having a single exitProcess:
    fun main(argv: List<String>): Int { /* snip */ }
    
    fun main(argv: Array<String>) = exitProcess(main(argv.asList()))
    

    I can completely understanding being hesitant about adding return parameters to these functions as they're the entry point everyone uses, but the breakage should be very easy to fix. I can create a speculative pull request if you want to see what a possible set of changes might look like and we can see what options there might be.

    What I've Tried

    Below is an example where I've done it from as a consumer of the library, this is within the broader context of me creating a tiny web framework mimicking Dropwizard's single fat jar which allows you to run migrations, start an application server, add custom sub-commands, etc...

    import com.github.ajalt.clikt.core.CliktCommand
    import kotlin.system.exitProcess
    
    abstract class Command (
            help: String = "",
            epilog: String = "",
            name: String? = null,
            invokeWithoutSubcommand: Boolean = false
        ): CliktCommand(
            help = help,
            epilog = epilog,
            name = name,
            invokeWithoutSubcommand = invokeWithoutSubcommand) {
    
        companion object {
            const val SUCCESS = 0
            const val COMMAND_PARSING_ERROR = 1 // used by Clikt
            const val ERROR_WHILE_COMMAND_RUNNING = 2
        }
    
        /**
         * Implement [doRun] and don't use [main]
         */
        final override fun run() {
            val exitCode = try {
                doRun()
            } catch (e: Exception) {
                exceptionHandler(e)
            }
    
            exitProcess(exitCode)
        }
        
        abstract fun doRun(): Int
        
        open fun exceptionHandler(e: Exception) = ERROR_WHILE_COMMAND_RUNNING
    }
    
    opened by saem 8
  • TermUI.prompt() does not work in JS

    TermUI.prompt() does not work in JS

    In JS, the file execution never returns after the prompt() call back to the main thread where it was called from.

    (some internal await / callback issue maybe)

    opened by championswimmer 2
  • Envvars ignored when using printHelpOnEmptyArgs

    Envvars ignored when using printHelpOnEmptyArgs

    When I create a CliktCommand with printHelpOnEmptyArgs set to true, with an option, if I launch my program without any option but with environment variables, they are not considered by the parser and the help message is printed.

    Expected : if environment variables matching defined options exist, they should be considered to don't print the help message (as corresponding options can be filled)

    opened by Pyeroh 0
  • Autocomplete fails to complete filenames with spaces

    Autocomplete fails to complete filenames with spaces

    When I try the autocomplete feature in bash with file names that contain spaces, the completion fails, because the parts of the name are treated separately.

    So if I have a file named file with spaces.txt and type fi, then nothing happens on first TAB (despite no other file matches fi), and on the second TAB I get the list: file spaces.txt with as possible completions, which is the correctly found filename, but the parts sorted alphabetically.

    It looks for me like the result of some missing quotes or something like that, but I know very few of bash autocompletion, so I don't know how to fix it.

    opened by Caralluin 0
  • Design issue: Clikt uses Inheritance instead of Composition

    Design issue: Clikt uses Inheritance instead of Composition

    I think there is a design issue in Clikt, It tries todo too much.

    Ideally I just want to have an argument parser, and use that where-ever its needed. (Command line tools for example).

    But Clikt really requires you to use inheritance and not composition. Composition allows for plug and play of the argument parser, like https://github.com/Kotlin/kotlinx-cli does.

    I actually tried using Clikt initially, but found issues where clikt already defines the main function so I cannot use it directly. Next to that, it requires subclassing, so i cant use clikt in a class that already is subclassing an abstract class.

    All in all, this makes clikt less usable/pluggable. It would be nice if clikt could be use without subclassing. And just as an argument parser tool, not as a command runner tool.

    opened by tjerkw 9
  • OptionGroup options `protected` instead of `internal`

    OptionGroup options `protected` instead of `internal`

    Hi there! Big fan of clikt, this project is awesome. We have made a practice of extending certain clikt classes including CliktCommand to get additional or supportive functionality we've desired.

    One capability we desire is to extend OptionGroup so our CLI can debug log the assigned values passed to all options. Our CLI has a DEBUG flag, and an increasing number of options. It would help greatly with debugging and maintainability to report all assigned settings passed into the OptionGroup.

    https://github.com/ajalt/clikt/blob/master/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/parameters/groups/ParameterGroup.kt#L76

    We don't have a slick way of doing this currently, because access to OptionGroup.options is marked as internal. Any reason this field cannot be made protected instead, so advanced users can access all options in a group dynamically? This is a small change, but it would be a huge help.

    opened by untra 3
  • Automate mkdocs publishing

    Automate mkdocs publishing

    The mkdocs website (https://ajalt.github.io/clikt/) currently shows "3.4.0" while the GitHub sources shows "3.5.0".

    Not a huge deal but automating that process would make sure both pages stay in sync.

    opened by martinbonnin 0
Releases(3.5.1)
  • 3.5.1(Dec 27, 2022)

  • 3.5.0(Jun 12, 2022)

    Added

    • Added hidden parameter to CliktCommand, which will prevent the command from being displayed as a subcommand in help output (#353)
    • Publish artifacts for the macosArm64 target. Note that this target is not tested on CI. (#352)

    Changed

    • Default values for arguments will now be included in help output when showDefaultValues=true is set on your help formatter (#357)

    Fixed

    • Fix flags and other options with defaults not being usable in mutuallyExclusiveOptions (#349)
    • Fix CompletionCommand generating completion for itself (#355)
    Source code(tar.gz)
    Source code(zip)
  • 3.4.2(Apr 25, 2022)

  • 3.4.1(Apr 9, 2022)

  • 3.4.0(Jan 16, 2022)

    Changed

    • Updated Kotlin to 1.6.10
    • unique() now works with any option with a list type, not just multiple() options (#332)

    Fixed

    • Fixed co-occurring option groups returning null when all options in the group are defined in environment variables (#330)
    Source code(tar.gz)
    Source code(zip)
  • 3.3.0(Oct 7, 2021)

    Added

    • Added default parameter to argument().multiple() (#305)
    • Context.originalArgv that allows you to read the command line arguments from within a command's run (#290)
    • context { envarReader = {...} } to set a custom function to read from environment variables (#299)

    Changed

    • defaultLazy values can now reference other parameters, as long the referenced parameters do not also reference other parameters
    • You can now call CliktCommand.context multiple times on the same command, and all builder blocks will be applied
    • Validate values entered to a prompt option, and show another prompt if the validation fails (#288)
    • Updated kotlin to 1.5.31

    Fixed

    • Report error when excess arguments are given to a command with allowMultipleSubcommands=true (#303)
    Source code(tar.gz)
    Source code(zip)
  • 3.2.0(May 14, 2021)

    Added

    • InputStream.isCliktParameterDefaultStdin and OutputStream.isCliktParameterDefaultStdout to check if the streams returned from inputStream/outputStream options are proxying stdin/stdout (#272)

    Changed

    • Make parameters of mutuallyExclusiveOptions covariant to allow validation without explicit type annotations. (#265)
    • Updated kotlin to 1.5.0

    Fixed

    • Reading from an option or argument property on a command that hasn't been invoked will now always throw an IllegalStateException
    Source code(tar.gz)
    Source code(zip)
  • 3.1.0(Dec 12, 2020)

    Added

    • Added required() and defaultLazy() for nullable flag options like switch().
    • Added support for generating autocomplete scripts for Fish shells (thanks to @faogustavo for the initial PR)
    • Added CompletionCommand and CliktCommand.completionOption() that will print an autocomplete script when invoked, as an alternative to using environment variables.

    Changed

    • Updated Kotlin to 1.4.21
    • @argfiles now allow line breaks in quoted values, which are included in the value verbatim. You can now end lines with \ to concatenate them with the following line.
    Source code(tar.gz)
    Source code(zip)
  • 3.0.1(Sep 3, 2020)

  • 3.0.0(Sep 2, 2020)

    Clikt 3.0 is a major release with a number of improvements and a few breaking API changes.

    Highlights of this release

    • Support for Browser JS targets
    • Support for localization of all help output
    • New extensions like help() and check() to make it even easier to setup your commands.

    See the full list of changes here, and a migration guide here.

    Source code(tar.gz)
    Source code(zip)
  • 2.8.0(Jun 20, 2020)

    Added

    • Added error parameter to PrintMessage and PrintHelpMessage. When true, CliktCommand.main will exit with status code 1. (#187)

    Changed

    • When printHelpOnEmptyArgs is true and no arguments are present, or when invokeWithoutSubcommand is false and no subcommand is present, CliktCommand.main will now exit with status code 1 rather than 0.
    • restrictTo now works with any Comparable value, not just Number.
    • CliktCommand.main now accepts Array<out String>, not just Array<String>. (#196)

    Fixed

    • Fixed option values being reset when calling multiple subcommands with allowMultipleSubcommands=true (#190)
    Source code(tar.gz)
    Source code(zip)
  • 2.7.1(May 19, 2020)

  • 2.7.0(May 13, 2020)

    Added

    • Ability to use custom program exit status codes via ProgramResult.
    • inputStream and outputStream conversions for options and arguments. (#157 and #159)
    • splitPair, toMap, and associate extensions on option. (#166)
    • treatUnknownOptionsAsArgs parameter to CliktCommand. (#152)
    • defaultByName function for groupChoice and groupSwitch options. (#171)

    Changed

    • Update Kotlin to 1.3.71
    • Improved command name inference. Now, a class like MyAppCommand will infer its commandName as my-app rather than myappcommand. You can still specify the name manually as before. (#168)

    Fixed

    • Correctly parse short options with attached values that contain =

    Thanks to @sschuberth for his contributions to this release!

    Source code(tar.gz)
    Source code(zip)
  • 2.6.0(Mar 17, 2020)

    Added

    • registeredSubcommands, registeredOptions, registeredArguments, and registeredParameterGroups methods on CliktCommand.
    • Ability to read default option values from configuration files and other sources. Support for Java property files is built in on JVM, see the json sample for an example of reading from other formats.
    • allowMultipleSubcommands parameter to CliktCommand that allows you to pass multiple subcommands in the same call. (docs)
    • Errors from typos in subcommand names will now include suggested corrections. Corrections for options and subcommands are now based on a Jaro-Winkler similarity metric, and can be customized with Context.correctionSuggestor

    Changed

    • Update Kotlin to 1.3.70
    • convert can be called more than once on the same option or argument, including after calls to conversion functions like int and file.
    • wrapValue is now deprecated, since convert can be used in its place instead.
    • CliktCommand.toString now includes the class name
    • Reverted automatic ~ expansion in file() and path() introduced in 2.5.0. If you need this behavior, you can implement it with code like convert { /* expand tidle */ }.file()
    Source code(tar.gz)
    Source code(zip)
  • 2.5.0(Feb 23, 2020)

    Added

    • Clikt is now available as a Kotlin Multiplatform Project, supporting JVM, NodeJS, and native Windows, Linux, and macOS.
    • eagerOption {} function to more easily register eager options.
    • Eager options can now be added to option groups in help out by passing a value for groupName when creating them.
    • canBeSymlink parameter to file() and path() conversions that can be used to disallow symlinks
    • CliktCommand.eagerOption to simplify creating custom eager options

    Changed

    • NoRunCliktCommand was renamed to NoOpCliktCommand. The existing class is deprecated. (#130)
    • The CliktCommand.context property has been deprecated in favor of the new name, currentContext, to avoid confusion with the CliktCommand.context{} method.
    • The parameter names of file() and path() conversions have changed. The existing names are deprecated, and can be converted to the new usages with an IntelliJ inspection. Note that if you are calling these functions with unnamed arguments (e.g. file(true, false)), you'll need to add argument names in order to remove the deprecation warning.

    Fixed

    • file() and path() conversions will now properly expand leading ~ in paths to the home directory for mustExist, canBeFile, and canBeDir checks. The property value is unchanged, and can still begin with a ~. (#131)
    Source code(tar.gz)
    Source code(zip)
  • 2.4.0(Jan 25, 2020)

    Added

    • CompletionCandidates.Fixed now has a secondary convenience constructor that take a vararg of Strings
    • CompletionCadidates.Custom, which allows you to call other binaries or write a script to generate completions. This class is currently experimental. (#79)
    • Option.wrapValue and Argument.wrapValue to make it easier to reuse existing conversion functions.
    • ignoreCase parameter to choice() and enum() conversion functions.

    Changed

    • option() and argument() now take optional completionCandidates parameters to override how completion is generated. The constructor and copy functions of OptionsWithValues and ProcessedArgument have changed to support default values.
    • The overloads of findObject (1 2) that take a default value have been renamed findOrSetObject. The existing names are marked with @Deprecated, and IntelliJ can convert your callsites automatically. (#110)
    • enum() parameters now accept case-insensitive values by default. You change this behavior by passing ignoreCase = false to enum() (#115)

    Fixed

    • groupChoice help output now includes the choices in the help output metavar
    • TermUi.edit* functions could freeze on certain editors (#99, thanks @iampravikant and @sebokopter)
    • Shell completion can now handle command names with dashes. (#104)
    • Arguments with = in them could be incorrectly interpreted as options (#106)
    Source code(tar.gz)
    Source code(zip)
  • 2.3.0(Nov 8, 2019)

    Added

    • option().groupSwitch(), which works like groupChoice(), but uses a switch() option rather than a choice() option.
    • UsageError now has a statusCode parameter (which defaults to 1). If you're using ClicktCommand.main, the value of statusCode will be passed to exitProcess.

    Changed

    • Shell completion code is now printed by throwing a PrintCompletionMessage (a subclass of PrintMessage) rather than calling echo directly.
    Source code(tar.gz)
    Source code(zip)
  • 2.2.0(Sep 29, 2019)

  • 2.1.0(Jun 23, 2019)

    Added

    • Ability to prevent rewrapping individual paragraphs in help output.
    • Added parameter required to Option.multiple() to require at least one instance of the option on the command line.

    Changed

    • CliktCommand.toString() now includes the names and values of all parameters and subcommands,

    Fixed

    • Create subcommand context when helpOptionNames is empty. (#64)
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(May 12, 2019)

  • 1.7.0(Mar 23, 2019)

    Added

    • printHelpOnEmptyArgs parameter to CliktCommand constructor. (#41)

    Fixed

    • Usage errors now correctly print subcommand names. (#47)
    • Arguments with multiple(required=true) now report an error if no argument is given on the command line. (#36)
    Source code(tar.gz)
    Source code(zip)
  • 1.6.0(Jan 15, 2019)

  • 1.5.0(Aug 26, 2018)

    Added

    • Ability to use alternate output streams rather than stdin and stdout by setting Context.console or by passing a console to TermUI functions.
    Source code(tar.gz)
    Source code(zip)
  • 1.4.0(Aug 1, 2018)

  • 1.3.0(Jun 23, 2018)

    Added

    • defaultLazy extension for options and arguments

    Changed

    • main now prints messages to stderr instead of stdout

    Fixed

    • Parameter help messages are now wrapped more consistently
    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Apr 15, 2018)

Small command-line utility to safely merge multiple WhatsApp backups (msgstore.db) into one.

whatsapp-database-merger A small command-line utility that can be used to merge multiple WhatsApp databases (msgstore.db) into one. A few notes: input

Mattia Iavarone 31 Dec 27, 2022
A command line utility to help you investigate the sensitive data associated with Macie findings.

Macie Finding Data Reveal This project contains a command line utility to help you investigate the sensitive data associated with Macie findings.

AWS Samples 8 Nov 16, 2022
A Kotlin-based testing/scraping/parsing library providing the ability to analyze and extract data from HTML

A Kotlin-based testing/scraping/parsing library providing the ability to analyze and extract data from HTML (server & client-side rendered). It places particular emphasis on ease of use and a high level of readability by providing an intuitive DSL. It aims to be a testing lib, but can also be used to scrape websites in a convenient fashion.

null 603 Jan 1, 2023
High level parsing to ensure your input is in the right shape and satisfies all constraints that business logic requires.

Parsix High level parsing to ensure your input is in the right shape and satisfies all constraints that business logic requires. It is highly inspired

null 190 Oct 16, 2022
Handy library to send & receive command with payload between subscribers for Android.

Commander Handy library to send & receive command with payload between subscribers for Android. Features Subscription based No dependency on Framework

Romman Sabbir 3 Oct 19, 2021
Command framework built around Kord, built to be robust and scalable, following Kord's convention and design patterns.

Command framework built around Kord, built to be robust and scalable, following Kord's convention and design patterns.

ZeroTwo Bot 4 Jun 15, 2022
🐫🐍🍢🅿 Multiplatform Kotlin library to convert strings between various case formats including Camel Case, Snake Case, Pascal Case and Kebab Case

KaseChange Multiplatform Kotlin library to convert strings between various case formats Supported Case Formats SCREAMING_SNAKE_CASE snake_case PascalC

PearX Team 67 Dec 30, 2022
Markdown renderer for Kotlin Compose Multiplatform (Android, Desktop)

Markdown renderer for Kotlin Compose Multiplatform (Android, Desktop)

Mike Penz 129 Jan 1, 2023
ASN.1 encoder/decoder for Kotlin/Multiplatform

ASN.1 encoder/decoder for Kotlin/Multiplatform. Supports Android, iOS, JavaScript and plain JVM environments

Sascha Peilicke 2 Mar 10, 2022
Base64 encoder/decoder for Kotlin/Multiplatform

Base64 encoder/decoder for Kotlin/Multiplatform. Supports Android, iOS, JavaScript and plain JVM environments.

Sascha Peilicke 11 Oct 25, 2022
Remove the dependency of compiled kotlin on kotlin-stdlib

Dekotlinify This project aims to take compiled Kotlin Java bytecode (compiled by the standard Kotlin compiler) and remove all references to the Kotlin

Joseph Burton 10 Nov 29, 2022
gRPC and protocol buffers for Android, Kotlin, and Java.

Wire “A man got to have a code!” - Omar Little See the project website for documentation and APIs. As our teams and programs grow, the variety and vol

Square 3.9k Dec 31, 2022
A DSL to handle soft keyboard visibility change event written in Kotlin.

About A DSL to handle soft keyboard visibility change event written in Kotlin. How to use? Step 1. Add it in your root build.gradle at the end of repo

Vinícius Oliveira 17 Jan 7, 2023
Kotlin matrix class which supports determinant, inverse matrix, matmul, etc.

Kotrix is a set of classes that helps people dealing with linear algebra in Kotlin.

Kanguk Lee 5 Dec 8, 2022
Fuzzy string matching for Kotlin (JVM, native, JS, Web Assembly) - port of Fuzzy Wuzzy Python lib

FuzzyWuzzy-Kotlin Fuzzy string matching for Kotlin (JVM, iOS) - fork of the Java fork of of Fuzzy Wuzzy Python lib. For use in on JVM, Android, or Kot

WillowTree, LLC 54 Nov 8, 2022
Multiplaform kotlin library for calculating text differences. Based on java-diff-utils, supports JVM, JS and native targets.

kotlin-multiplatform-diff This is a port of java-diff-utils to kotlin with multiplatform support. All credit for the implementation goes to original a

Peter Trifanov 51 Jan 3, 2023
Multi-module, Kotlin, MVI, Compose, Hilt, Navigation Component, Use-cases, Room, Retrofit

Work in progress Multi-module demo app that gets data from dota2 api. API https://docs.opendota.com/ Players by rank (GET) https://api.opendota.com/ap

Mitch Tabian 321 Dec 27, 2022
recompose is a tool for converting Android layouts in XML to Kotlin code using Jetpack Compose.

recompose is a tool for converting Android layouts in XML to Kotlin code using Jetpack Compose.

Sebastian Kaspari 565 Jan 2, 2023
Dagger Hilt, MVP Moxy, Retrofit, Kotlin coroutine, Sealed class

Dagger Hilt, MVP Moxy, Retrofit, Kotlin coroutine, Sealed class

Dostonjon 1 Nov 2, 2021