Phil Richardson
11/24/2021, 2:32 PMobj
in a set of chainable sub-commands.
My outer most CliktCommmand should set obj
directly, but sub-commands may want to replace this instance.
I want to maintain the sub-command separation though, so any sub-command should not need to know which parent context the actual object is set in.
Given this, I cannot use currentContext.obj
to set the new instance in a sub-command, that future CliktCommands in the chain can access.
This is natural, as it will set it on the sub-commands context, not a parents.
I also cannot use findOrSetObject
on currentContext
as this will correctly identify that the current instance in the correct parent context
But it is going to find one set in a parent, so will return the current value, ignoring the block provided.
There is no replacement logic, a currentContext.findAndSetObject
if you will.
Is there a simple way to implement such replacement logic?Phil Richardson
11/24/2021, 2:35 PMfindAndSetObject
would find the nearest one, and if there is non, setting obj
on the current commands context, not a parent (like findOrSetObject
does)AJ Alt
11/24/2021, 9:03 PMfindOrSetObject
will set the object on the context it's called on if it can't find one. It will never affect a parent context.
As far as changing the parent object, there isn't anything built in. I think the best approach would be to make the context object itself mutable. Something like class Ctx(var state: MyState)
, then val ctx by requireObject<Ctx>()
and ctx.state = newState
.andries.fc
01/08/2022, 5:56 PMAJ Alt
01/10/2022, 5:26 PMCliktCommand(name="mycommand")
https://ajalt.github.io/clikt/api/clikt/com.github.ajalt.clikt.core/-clikt-command/index.htmlandries.fc
01/12/2022, 4:02 PMdarkmoon_uk
01/30/2022, 7:06 AM-
character. Clikt then tries to interpret this as an option. Is there an idiomatic way to differentiate options from arguments that legitimately begin with -
?AJ Alt
02/01/2022, 5:34 PMNikky
02/25/2022, 2:09 PMPhil Richardson
03/19/2022, 9:19 PMgroupSwitch
to help select a security toggle and then provides each toggles associated required parameters.
My app will be a Hadoop client if it helps any, so my security selection under a Kerberos enabled cluster would be from the following 3 presents choices
1: A default mechanism, in which all that is delegated to the hadoop libraries (it will have options, but they are not relevant or hampering me right now)
2: User supplies a Kerberos principal & keytab as options
3: User supplies a Kerberos principal & associated password as options
As we can see, options 2 & 3 share a common parameter principal
, whilst option 1 does not require it as input. Principal would be a required parameter were the switch for 2/3 is used.
So the principal is not generic to the application, so I don't want to ask for it outside of the groupSwitch
However, if I request principal
in both OptionGroup
classes, we get an error that the option is duplicated
From my reading of how it works, a ChoiceGroup
is inherently single
when they are a required option, unlike with Mutually Exclusive Options, were they are optional. However, i can't use single
with a ChoiceGroup
to enforce that characteristic.
I can't use either Mutually Exclusive Options or Co-Occurring exclusively that I can see, given the desire to have a switch act as the driver to collect additional options or not.
Is there a pattern that would support this? i.e. allowing a --principal
parameter to exist in both option groups, yet it be considered unique as it would only be possible for one of the duplicates to be exposed?
Side node. groupSwitch
help formatting is very very odd.
When used with groupSwitch
the name
parameter of the OptionGroup
is used in the help formatter, but not the help
parameter.
The option groups are documented above the Options:
and the switches below it. So putting the help text for each option in the name
parameter feels very odd.
The switches in the Options:
section are not really conveyed that they are switches either.
Almost all other self-documenting elements in Clikt feel intuitive, but those for groupSwitch
feel quite out of placeAJ Alt
03/21/2022, 5:58 PMvalidate{}
or check{}
on the options, or in your run
method.Phil Richardson
03/21/2022, 7:38 PMAJ Alt
03/21/2022, 8:08 PMjw
10/25/2022, 3:09 PM./cli --> null
./cli --foo --> default (a)
./cli --foo=a --> a
./cli --foo=b --> b
Sebastian Schuberth
12/07/2022, 9:27 PMBig Chungus
01/11/2023, 12:07 AM-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).Big Chungus
01/30/2023, 5:32 PMjw
01/30/2023, 5:38 PMjeff
02/01/2023, 5:26 PMscript --some-option="two words"
sets --some-option
to two
and then passes words
as an argumentJim
03/14/2023, 3:06 AMSebastian Schuberth
04/19/2023, 9:21 PM--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).Daniel
04/27/2023, 7:53 AMfun 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 ?Paul Woitaschek
07/21/2023, 7:32 AMcurioustechizen
07/28/2023, 2:19 PMted
09/16/2023, 1:21 PMclass 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
?Marc Plano-Lesay
11/09/2023, 11:04 AM--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?Simon Marquis
11/14/2023, 11:09 AMmultiple()
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
val flavors: Set<Flavor> by option("-f", "--flavors")
.enum<Flavor>(ignoreCase = true)
.multiple(default = listOf(Main)).unique()
Eugen Martynov
02/05/2024, 11:53 AMAdam S
03/14/2024, 9:49 AMhttps://github.com/ajalt/clikt/blob/4.2.2/docs/img/animation.png▾
ted
03/18/2024, 4:31 PM