https://kotlinlang.org logo
Join SlackCommunities
Powered by
# clikt
  • p

    Phil Richardson

    03/21/2022, 7:38 PM
    That's the pattern I was moving towards instead. Although, it was only when noting the help formatting that it prompted me to ask.
  • a

    AJ Alt

    03/21/2022, 8:08 PM
    Can you give an example of what you'd like the help output to look like? That's probably something we could improve.
  • j

    jw

    10/25/2022, 3:09 PM
    Can I do a choice-based option that allows for a default choice value (if none provided) but is still nullable if the flat is omitted?
    Copy code
    ./cli          --> null
    ./cli --foo    --> default (a)
    ./cli --foo=a  --> a
    ./cli --foo=b  --> b
    a
    s
    • 3
    • 3
  • s

    Sebastian Schuberth

    12/07/2022, 9:27 PM
    Can I somehow use option groups to express that at least one (arbitrary) option of that groups needs to specified, and multiple options from that group are also allowed?
    a
    • 2
    • 4
  • b

    Big Chungus

    01/11/2023, 12:07 AM
    Hi, is there a way to make CliktCommand to treat all args as positional (even
    -h
    )? I'm writing a cli that has an interpreter command which needs to propagate all args, but anything starting wit
    -h
    (e.g.
    -hidon'treallywanthelp
    ) gets eaten up and produces illegal option error. I'm aware of
    --
    and it works, but I'm wondering if there's a way to somehow hack CliktCommand to avoid having that (this particular command is hidden and is reserved for internal use anyways).
    a
    • 2
    • 1
  • b

    Big Chungus

    01/30/2023, 5:32 PM
    I'm thinking of trying to submit a PR with dsl extensions for clikt. Main use-case is more concise setup for kts scripting without having to deal with classes. Can I get some votes on how useful that would be here?
    👍 1
    👎 2
    j
    • 2
    • 18
  • j

    jw

    01/30/2023, 5:38 PM
    that's pretty abstract. can you give an example?
  • j

    jeff

    02/01/2023, 5:26 PM
    Maybe i’m being obtuse, but can I have an option accept a string that includes whitespace? This:
    Copy code
    script --some-option="two words"
    sets
    --some-option
    to
    two
    and then passes
    words
    as an argument
    a
    • 2
    • 2
  • j

    Jim

    03/14/2023, 3:06 AM
    Is there a way to allow an option to be shared by say 2/3 cases in an OptionGroup?
    p
    • 2
    • 6
  • s

    Sebastian Schuberth

    04/19/2023, 9:21 PM
    Can I make a required option not required if another option is specified? My use case is a
    --dry-run
    flag. If it's specified, the output directory does not have to be specified (via
    -o
    ), but it can be specified (as it will not be written to anyway).
    a
    • 2
    • 2
  • d

    Daniel

    04/27/2023, 7:53 AM
    Hi. I have this code:
    Copy code
    fun main(args: Array<String>) = Launcher.subcommands(InitKeystore).main(args)
    
    object Launcher : CliktCommand(help = "", invokeWithoutSubcommand = true) {
    ...
        override fun run() {
            ...
            log("I have done something")
        }
    }
    
    object InitKeystore : CliktCommand(name = "keystore_init", help = "") {
    ...
        override fun run() {
            ...
            log("I have done init")
        }
    }
    When I run it without the
    keystore_init
    subcommand, it launches correctly only the
    Launcher
    , but when I specify the
    keystore_init
    subcommand, I see in my output both the log strings, ie. it runs the main command and then the subcommand ?
    p
    • 2
    • 2
  • p

    Paul Woitaschek

    07/21/2023, 7:32 AM
    Is it possible to render markdown in a prompt?
    s
    a
    • 3
    • 12
  • c

    curioustechizen

    07/28/2023, 2:19 PM
    Is there a way to show a prompt such that the user can select multiple options from the prompt? Something similar to this, but imagine if I wanted to allow selecting multiple languages.
    a
    • 2
    • 2
  • t

    ted

    09/16/2023, 1:21 PM
    Hello, noob question I created a kotlin project and have this app/src/main/kotlin/Main.kt
    Copy code
    class Hello : CliktCommand() {
        val count: Int by option().int().default(1).help("Number of greetings")
        val name: String by option().prompt("Your name").help("The person to greet")
    
        override fun run() {
            repeat(count) {
                echo("Hello $name!")
            }
        }
    }
    
    fun main(args: Array<String>) = Hello().main(args)
    source I can run it from intellij but how do I create the executable
    ./hello
    ?
    • 1
    • 1
  • m

    Marc Plano-Lesay

    11/09/2023, 11:04 AM
    Is there a way to somehow split the top-level command and subcommands in two distinct phases? I'd like to leverage the top-level command for generic arguments (e.g. a
    --verbose
    flag), that I could then inject through Dagger in different subcommands. But from what I understand of Clikt's subcommands, I'd need to have them initialised before the parent's parsing is done, I believe?
    s
    • 2
    • 1
  • s

    Simon Marquis

    11/14/2023, 11:09 AM
    👋 Hi, I'm trying to find a way to mix enum option using
    multiple()
    and
    prompt()
    to allow the user to provide values at runtime if nothing is provided. Unfortunately, this does not seem to be supported. What would be the recommended way to support this kind of behavior? I'm currently using this, but this prevent me from using a prompt
    Copy code
    val flavors: Set<Flavor> by option("-f", "--flavors")
        .enum<Flavor>(ignoreCase = true)
        .multiple(default = listOf(Main)).unique()
    a
    • 2
    • 4
  • e

    Eugen Martynov

    02/05/2024, 11:53 AM
    Hi people, we have json file that has information about teams ownership to gradle module. How would you define with clikt next command line - it has three modes - find module by team name, find team name by module name, validate all modules have at least one team name assigned?
    a
    • 2
    • 5
  • a

    Adam S

    03/14/2024, 9:49 AM
    just curious - does anyone know what was used to create the animation in the Clikt docs? It looks cool, I like the style

    https://github.com/ajalt/clikt/blob/4.2.2/docs/img/animation.png▾

    j
    a
    • 3
    • 4
  • t

    ted

    03/18/2024, 4:31 PM
    Hi can you do this with clikt or another tool? https://camo.githubusercontent.com/ad344bbe77bb90ced4e6e7f1867a1e7076ff59d658aca02d573ccea[…]32d377746715a6c784d576762576d4f49704271584a54692e676966
    a
    p
    • 3
    • 6
  • s

    suresh

    05/19/2024, 10:59 AM
    @AJ Alt Hi, is mordant-coroutines become a mandatory deps for
    2.6.0
    ? I have a gradle build script which uses just the
    TextColors
    and it’s broke after updating to 2.6.0. Things started working fine after adding mordant-coroutines.
    a
    • 2
    • 4
  • e

    efemoney

    09/16/2024, 12:08 PM
    Hello @AJ Alt, is the typesafe option/argument parsing of clikt standalone? I want to run in a main kts script and because of aesthetics I’d like not to define a command class, just parse the incoming args, and use it in script body
    👀 1
    a
    • 2
    • 2
  • k

    kyle

    10/01/2024, 9:13 PM
    im running into a behavior where after printing the output of the command to the terminal, the command hangs for ~90 seconds before it exits gracefully. logging and other debugging indicates my commands finish when i expect them to and i havent figured out how to debug further. anyone experienced this before?
    p
    • 2
    • 4
  • a

    andries.fc

    11/28/2024, 12:41 PM
    Hi @AJ Alt. Is there a way to allow for multiple option groups?. For example, I would like to do something like using a group which groups the
    --schema
    with the
    --schema-script
    :
    Copy code
    --schema accounting --schema-script accounting.sql --schema salestracking --schema-script salestracking.sql
  • a

    Adam Brown

    12/02/2024, 8:45 AM
    Hey I'm trying to get a progress bar to animate inside of a table, but I must be missing something, it renders it once, and then animates it below the table:
    Copy code
    val progressLayout = progressBarLayout {
    			spinner(Spinner.Dots())
    			marquee(terminal.theme.warning("Running conversion"), width = 24, align = TextAlign.CENTER)
    			percentage()
    			progressBar()
    			completed(style = terminal.theme.success)
    		}
    		val progress = progressLayout.animateInCoroutine(t)
    
    		t.println(
    			Panel(
    				expand = true,
    				content = horizontalLayout {
    					column(0) { width = Expand(1) }
    					column(1) {
    						width = Auto
    					}
    					column(2) { width = Expand(1) }
    
    					cell(EmptyWidget)
    					cell(
    						table {
    							captionTop("Input Dictionary")
    							body {
    								row("Input File", path.name)
    								row("Size", inputMetadata.size.toString() + " Bytes")
    								row("Entries", numEntries)
    								row {
    									cell(
    										progressLayout.build(null, 0, TimeSource.Monotonic.markNow())
    									) {
    										columnSpan = 2
    									}
    								}
    							}
    						}
    					)
    					cell(EmptyWidget)
    
    				},
    				title = Text("FDIC Converter")
    			)
    		)
    
    		val scope = CoroutineScope(Dispatchers.Default)
    		scope.launch { progress.execute() }
  • a

    Adam Brown

    12/02/2024, 6:22 PM
    also I guess just more generally, is there any way I can change the value of a field in the table after it's been rendered?
  • a

    Adam Brown

    12/04/2024, 1:28 AM
    Well I couldn't get the progress bar animating in the Panel, but still, both Clikt and mordant are really awesome libraries, thanks! Really made making this little CLI util simple
    K 1
    a
    • 2
    • 8
  • s

    suresh

    12/21/2024, 5:07 AM
    Hi, I am getting the following error when compiling a simple Kotlin Native program using Clikt and Mordant (latest versions and kotlin 2.1.20-Beta1) on GH. I’m unsure whether this is a Kotlin or Clikt issue. Posting it here in case anyone has encountered it before.
    Copy code
    > Task :backend:native:linkDebugTestLinuxX64 FAILED
    The /home/runner/.konan/dependencies/llvm-16.0.0-x86_64-linux-essentials-80/bin/ld.lld command returned non-zero exit code: 1.
    output:
    ld.lld: error: duplicate symbol: kfun:com.github.ajalt.clikt.core#selfAndAncestors__at__com.github.ajalt.clikt.core.Context(){}kotlin.sequences.Sequence<com.github.ajalt.clikt.core.Context>
    >>> defined at Context.kt:0 (/home/runner/work/clikt/clikt/clikt/src/commonMain/kotlin/com/github/ajalt/clikt/core/Context.kt:0)
    >>>            libclikt:clikt-cache.a.o:(kfun:com.github.ajalt.clikt.core#selfAndAncestors__at__com.github.ajalt.clikt.core.Context(){}kotlin.sequences.Sequence<com.github.ajalt.clikt.core.Context>) in archive /home/runner/.konan/kotlin-native-prebuilt-linux-x86_64-2.1.20-Beta1/klib/cache/linux_x64-gSTATIC-pl/clikt:clikt/2bx6m2c1bk30f.1y4oy7igjc182/clikt:clikt-cache/bin/libclikt:clikt-cache.a
    >>> defined at MordantContext.kt:0 (/home/runner/work/clikt/clikt/clikt-mordant/src/commonMain/kotlin/com/github/ajalt/clikt/core/MordantContext.kt:0)
    >>>            libclikt:clikt-mordant-cache.a.o:(.text.kfun:com.github.ajalt.clikt.core#selfAndAncestors__at__com.github.ajalt.clikt.core.Context(){}kotlin.sequences.Sequence<com.github.ajalt.clikt.core.Context>+0x0) in archive /home/runner/.konan/kotlin-native-prebuilt-linux-x86_64-2.1.20-Beta1/klib/cache/linux_x64-gSTATIC-pl/clikt:clikt-mordant/3uo87q16hlqb.wo5fwkyzrtn4/clikt:clikt-mordant-cache/bin/libclikt:clikt-mordant-cache.a
    a
    • 2
    • 2
  • m

    Michael Friend

    01/14/2025, 8:08 PM
    Is there a way to get a value source file as an option rather than hardcoding a path? Id like users to be able to give a path to a config file when calling a command then use that config file (if provided) as a value source for the other options. I thought setting the config option to eager would make it available in init where i could set the value as a value source but that didnt work for me, i also tried setting the value source on the context of the parent command but im guessing thats too late in execution since its not pulling values from the config Here's my first attempt i thought would work because of eager value
    Copy code
    class Pickle : SuspendingCliktCommand() {
      val config by option(eager = true)
        .file()
    
      init {
        context {
          config?.let {
            valueSources(PropertiesValueSource.from(it))
          }
        }
      }
      val test by option()
    
      override suspend fun run() {
        echo(test)
      }
    }
    a
    • 2
    • 2
  • r

    Rob Elliot

    02/26/2025, 4:35 PM
    Is it possible to have a
    mutuallyExclusiveOptions
    where one of the options is an
    OptionGroup
    ? Intuitively it seems like it should be possible, but I can't work out the syntax!
    s
    • 2
    • 1
  • r

    Rob Elliot

    04/01/2025, 1:47 PM
    May I ask about mordant in here? Edit - made my suggestion here: https://github.com/ajalt/mordant/discussions/263