Adding Options and ArgGroups programmatically

已查看 68 次
跳至第一个未读帖子

Dominik Guhr

未读,
2021年11月2日 12:57:382021/11/2
收件人 picocli
Hey there, and thanks for having me :) 

I hope anybody could help me out here, because I have a problem:

We're creating a keycloak CLI right now. The files are located here: [1] (my branch with latest changes / problem).

Everything worked fine so-far, but as we are loading many options programmatically, I now tried to add these programmatic options to arggroups programmatically, too. Sadly, when I run my code, I always get the following exception:

Exception in thread "main" java.lang.reflect.InvocationTargetExceptionat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566)at io.quarkus.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:53)at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:28)

Caused by: picocli.CommandLine$InitializationException: ArgGroup has no options or positional parameters, and no subgroups: null in null

at picocli.CommandLine$Model$ArgGroupSpec.<init>(CommandLine.java:10059)

at picocli.CommandLine$Model$ArgGroupSpec$Builder.build(CommandLine.java:10512)

at org.keycloak.quarkus.runtime.cli.Picocli.addOption(Picocli.java:312)

at org.keycloak.quarkus.runtime.cli.Picocli.createCommandLine(Picocli.java:244)

at org.keycloak.quarkus.runtime.cli.Picocli.parseAndRun(Picocli.java:75)

at org.keycloak.quarkus.runtime.KeycloakMain.main(KeycloakMain.java:60)

... 6 more

So after googling around a bit, it seems I am doing something wrong when initializing them here: [2] and here: [3]

It would be absolutely great to get some advice on how to do this programmatically, without having to setup xxx properties manually via annotation. :) 
[3]

If you want/need more context, feel free to reach out, I am open to everything and have CodeWithMe installed fwiw ;)

Best regards,
Dominik

Remko Popma

未读,
2021年11月2日 20:11:382021/11/2
收件人 Dominik Guhr、picocli
Hi Dominik,

looking at this snippet around line 308:

if(spec.argGroups().stream().noneMatch(g -> g.heading().equals(mapper.getCategory().getHeading()))){
    spec.addArgGroup(ArgGroupSpec.builder()
            .heading(mapper.getCategory().getHeading())
            .validate(false)
            .build());
}

This calls build() on the ArgGroupSpecBuilder before options are added to it.
Please try adding options (and subgroups) to the builder before calling build() on the builder.
 

--
You received this message because you are subscribed to the Google Groups "picocli" group.
To unsubscribe from this group and stop receiving emails from it, send an email to picocli+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/picocli/7ac89013-cf38-45b6-8865-093fb17c8e5bn%40googlegroups.com.

Dominik Guhr

未读,
2021年11月3日 02:52:582021/11/3
收件人 Remko Popma、picocli
Hey Remko,

thanks for your answer! Makes perfectly sense, after a night of good sleep. Will try it out and come back with the results :)

Dominik Guhr

未读,
2021年11月3日 03:11:352021/11/3
收件人 picocli
Hi Remko,

thanks again for pointing that out. That did the trick. I now created  the method linked [1] which does all the initialization logic. No I am at the point where I get another exception, and I wanted to ask you if this is intended, and if so, if it's possible another way to add options programmatically to an already existing arggroup :)

So, to the point: 
When calling options().add(...) in my code, I get the following exception: 

Caused by: java.lang.UnsupportedOperationException

at java.base/java.util.Collections$UnmodifiableCollection.add(Collections.java:1060)

at org.keycloak.quarkus.runtime.cli.Picocli.lambda$addOptionToArgGroup$4(Picocli.java:376)

at java.base/java.util.Optional.ifPresentOrElse(Optional.java:201)

at org.keycloak.quarkus.runtime.cli.Picocli.addOptionToArgGroup(Picocli.java:375)

Which, when I look at the options() impl, is right because it indeed returns an unmodifiableList. 


Best regards,
Dominik

Remko Popma

未读,
2021年11月3日 03:38:322021/11/3
收件人 picocli
Hi Dominik,

The exception is by design, it is not possible to modify an arggroup after it has been built.
Arggroups are meant to be immutable.

To improve this and make your use case possible without changing that invariant, we can add the following API:
* CommandSpec::removeArgGroup(ArgGroup) - removes the specified group and all its options and positional parameters from this command
* ArgGroupBuilder::new(ArgGroup) - ArgGroupBuilder constructor that adds all options, positional parameters and subgroups of the specified group to the returned builder

This should allow you to remove the old group, construct a new group builder with the same elements as the old group, add new options to the new builder, and then build a group instance and add it to the commandSpec.

I am not sure when I will have time to work on this.
If you are interested, will you be able to provide a pull request?


Dominik Guhr

未读,
2021年11月3日 04:14:272021/11/3
收件人 Remko Popma、picocli
Hey Remko,

Thanks again for the fast response, really appreciated. I think at least for my usecase it'll also possible to "batch-add" all the options to a non-built arggroupbuilder, and then build it, because I know all of them beforehand (variable "mappers" in the caller), so I'll try to add them before building the actual arggroup now. If that doesn't work I'll have a look into your proposal :) 

Best regards,
Dominik

You received this message because you are subscribed to a topic in the Google Groups "picocli" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/picocli/seF0PUrOMVw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to picocli+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/picocli/CAAFrFhSOW7q19c2Y%2Bhx_F768E0dK7xsTBGVodYCXvtbNWW5aUA%40mail.gmail.com.

Dominik Guhr

未读,
2021年11月3日 06:04:132021/11/3
收件人 picocli
Hey, 

so I got it to working now to get the config programmatically, see:

Thanks again for your help leading me on the right track. I am sorry to say that I also don't have the time right now to add your proposal to picocli, given that I never worked with your codebase there would be some ramp-up I can't spare at the moment, because we want to have the quarkus and picocli-based keycloak distribution ready asap. I hope you don't mind, sorry again. 

Best regards,
Dominik

Remko Popma

未读,
2021年11月3日 19:23:202021/11/3
收件人 picocli
Hi Dominik,

No worries. Glad you got it working!
Good luck with Keycloak! (Nice video!)

:-)
Remko


Dominik Guhr

未读,
2021年11月4日 04:14:502021/11/4
收件人 picocli
Thank you Remko! :-) 

Btw: Having such a bunch of option leads to me thinking about some filtering logic. Like <my.sh> <command> --help <--prefix| -p>=http only returns all options with key matching 'http', or e.g. <my.sh> <command> --help <--category| -c>=Database returning only the database options. I don't think such a thing would be possible ootb, would it? I'll look into it later :)  

回复全部
回复作者
转发
0 个新帖子