Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GenerateCompletion cannot be used if the parent has an usageHelp Option with scope = INHERIT #1673

Closed
aheritier opened this issue May 4, 2022 · 7 comments

Comments

@aheritier
Copy link

Context

We have CLI (quarkus based but not relevant here) with multiple sub-commands.
We want to provide the classical -h/--help options in all commands but not -v/--version (For the version we are using a dedicated command which is allowing us to @Inject some components which is not possible with a versionProvider).
Thus we want to use an help Option inherited by all sub-commands instead of using mixinStandardHelpOptions with a Command and scope INHERIT)

It gives such kind of code:

@CommandLine.Command(
    name = "foo",
    subcommands = {
        GenerateCompletion.class,
        FooCommand.class,
        BarCommand.class,
        ...
    })
public class EntryCommand {
    @Option(names = {"-h", "--help"}, usageHelp = true, description = "Show this help message and exit.", scope = INHERIT)
    boolean helpRequested;
...
}

Problem

It doesn't work because -h is considered as duplicated between the command we write and the one in GenerateCompletion.

picocli.CommandLine$DuplicateOptionAnnotationsException: Option name '-h' is used by both field boolean foo.EntryCommand.helpRequested and field boolean picocli.CommandLine$AutoHelpMixin.helpRequested

It is similar to #1319 AFAWCS

Workaround

For now, the workaround it to declare the help option with scope = INHERIT in all our subcommands and to declare it with no inheritance in the TopLevel command.

Is there a better solution from your POV @remkop ?

@aheritier
Copy link
Author

(Note: it must be the same for HelpCommand or others default commands you provide)

@remkop remkop added this to the 4.7 milestone May 4, 2022
@remkop
Copy link
Owner

remkop commented May 4, 2022

@aheritier Thank you for raising this.

I can take a look at doing a similar solution as what I did for #1319.

That said, you mention this:

(...) to @Inject some components which is not possible with a versionProvider

This sounds strange. I don't understand why @Inject-ing would not work in the version provider...

I believe Quarkus command mode ensures that picocli has a CommandLine.IFactory that supports CDI.
If the version provider is configured as @Command(versionProvider = MyVersionProvider.class), then when the factory gets an instance of the MyVersionProvider class, it will go through Quarkus CDI, so any @Inject stuff should be honored...

@aheritier
Copy link
Author

Hi @remkop

For the versionProvider issue I will dig a bit more if you think that it should work. If it's not I think that the problem should be reported on Quarkus side? Or on Picocli 1st ?

@remkop
Copy link
Owner

remkop commented May 6, 2022

@aheritier I would guess Quarkus first since it would be a problem with the dependency injection.

@PierreBtz
Copy link

@remkop thanks for the pointer, I opened quarkusio/quarkus#25475 with a reproducer to track this quarkus side.

remkop added a commit that referenced this issue May 11, 2022
@remkop
Copy link
Owner

remkop commented May 11, 2022

@aheritier and @PierreBtz I see that the Quarkus people helped resolve the issue with injection into the IVersionProvider, that is great.

About the original problem:
There may be other cases where an inherited option collides with an option in an existing subcommand.
I added this example to demonstrate how applications can work around this by removing the clashing duplicate option from the subcommand, and then adding the subcommand programmatically instead of via the annotations.

Hope this is useful for others.

@remkop remkop removed this from the 4.7 milestone May 11, 2022
@remkop remkop closed this as completed May 11, 2022
@aheritier
Copy link
Author

Hi @remkop

Awesome. Effectively it is exactly what I was looking for.

In parallel we were also able to implement an IVersionProvider

You rock.

Thanks a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants