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

Could not use same option in different classes #1440

Closed
nemetsSY opened this issue Oct 5, 2021 · 3 comments
Closed

Could not use same option in different classes #1440

nemetsSY opened this issue Oct 5, 2021 · 3 comments
Labels
theme: annotation-proc An issue or change related to the annotation processor type: bug 🐛
Milestone

Comments

@nemetsSY
Copy link

nemetsSY commented Oct 5, 2021

Can not use the same option in different classes if set up kapt to use picocli annotation processor.
I'm getting DuplicateOptionAnnotationsException even if classes are separate commands.
It looks that there is an error when processing INHERIT options, check is perfrmed for all classes, not for sub-commands only.

Here is a code to reproduce:

import picocli.CommandLine
import picocli.CommandLine.Command
import picocli.CommandLine.Model.CommandSpec
import picocli.CommandLine.Spec

@Command(name = "Command1", subcommands = [ CommandLine.HelpCommand::class ],
        description = ["Command 1 description"])
class Command1 {

    @Spec
    lateinit var spec: CommandSpec

    @CommandLine.Option(names = ["--option"],
            scope = CommandLine.ScopeType.INHERIT,
            description = ["If set to true, will not ask questions and configurations, e.g. to overwrite a file. We don't recommend setting this option to true unless you are working in a scripted environment"])
    var option: String = ""
}
import picocli.CommandLine
import picocli.CommandLine.Command
import picocli.CommandLine.Model.CommandSpec
import picocli.CommandLine.Spec

@Command(name = "Command1", subcommands = [ CommandLine.HelpCommand::class ],
        description = ["Command 1 description"])
class Command2 {
    @Spec
    lateinit var spec: CommandSpec

    @CommandLine.Option(names = ["--option"],
            scope = CommandLine.ScopeType.INHERIT,
            description = ["If set to true, will not ask questions and configurations, e.g. to overwrite a file. We don't recommend setting this option to true unless you are working in a scripted environment"])
    var option: String = ""
}

and build.gradle.kts file:

plugins {
    kotlin("jvm") version "1.5.31"
    kotlin("kapt") version "1.5.31"
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib"))
    implementation("info.picocli:picocli:4.6.1")
    kapt("info.picocli:picocli-codegen:4.6.1")
}

kapt {
    arguments {
        arg("project", "${project.group}/${project.name}")
    }
}
@remkop
Copy link
Owner

remkop commented Oct 5, 2021

Thank you for raising this!

I'm about to go on holidays to visit family. It may take me a while before I can take a look at this.

@remkop remkop added theme: annotation-proc An issue or change related to the annotation processor type: bug 🐛 labels Nov 13, 2021
@remkop remkop added this to the 4.6.3 milestone Nov 13, 2021
remkop added a commit that referenced this issue Jan 18, 2022
@remkop
Copy link
Owner

remkop commented Jan 18, 2022

Thank you for your patience.
I was able to reproduce the issue thanks to your sample code.
Started to investigate this...

@remkop remkop closed this as completed in ed222fe Jan 18, 2022
@remkop
Copy link
Owner

remkop commented Jan 18, 2022

The cause of the issue was that both commands had picocli.CommandLine.HelpCommand as a subclass.
In the annotation processor, only one CommandSpec instance was created for this HelpCommand, and this instance was shared between both Command1 and Command2.

When the inherited --option was added to Command1 it was also added to its subcommand.
When the other inherited option with the same name --option was added to Command2 it was also added to its subcommand.
The problem was that while there should have been separate CommandSpec instances for these subcommands, they were pointing to the same single instance, resulting in the DuplicateOptionAnnotationsException.

The solution was to ensure that the annotation processor did not try to reuse CommandSpec instances for subcommands.

This will be included in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: annotation-proc An issue or change related to the annotation processor type: bug 🐛
Projects
None yet
Development

No branches or pull requests

2 participants