Skip to content

[#2430] Bugfix: annotation processor should allow @Spec in ArgGroup classes - #2538

Open
sharanggupta wants to merge 1 commit into
remkop:mainfrom
sharanggupta:gh-2430-spec-in-arggroup-or-mixin
Open

sharanggupta wants to merge 1 commit into
remkop:mainfrom
sharanggupta:gh-2430-spec-in-arggroup-or-mixin

Conversation

@sharanggupta

Copy link
Copy Markdown

Fixes #2430.

Problem. With the annotation processor enabled, a @Spec CommandSpec spec; field inside an @ArgGroup class fails compilation with @Spec must be enclosed in a @Command, or in a class that implements IVersionProvider but was .... Picocli supports @Spec in ArgGroup classes at runtime since 4.6 (user manual, "@SPEC Annotation" tip), so the processor rejected valid code. The reporter saw this appear in 4.7.7.

Cause. The check in AbstractCommandSpecProcessor.Context.connectModel() has existed since 4.5 (#1134), but before 4.7.7 it passed by accident for ArgGroup classes: @Options inside an ArgGroup class were looked up by the @ArgGroup variable instead of its type, missed the group, fell through to getOrCreateCommandSpecForArg, and that registered a CommandSpec for the ArgGroup class as a side effect. The 4.7.7 fix to look groups up by type removed that side effect and the latent check started to fire.

Fix. As suggested in the issue, the check is removed rather than extended: @Spec is legitimately used in several non-command classes (ArgGroup classes, mixins, IVersionProvider implementations) and picocli injects the CommandSpec at runtime, so there is nothing the processor needs to attach for them. A FINE-level log line replaces the error. I considered relaxing the check to also accept ArgGroup types (keys of argGroupElementsByType) to keep a diagnostic for stray @Spec fields, but that is the same allow-list pattern that produced this false positive and the runtime has no equivalent error; happy to switch to that if you prefer.

Tests. Issue2430Test in picocli-codegen-tests-java9plus compiles the reporter's example (ArgGroup class with @Spec inside a @Mixin) and a variant with the ArgGroup directly on the command; both failed with the exact message above before the change and pass after it. :picocli-codegen:test and :picocli-codegen-tests-java9plus:test are green.

…gGroup classes

The annotation processor raised the compile error "@SPEC must be
enclosed in a @command, or in a class that implements IVersionProvider"
when a `@Spec`-annotated field was declared in an `@ArgGroup` class.
At runtime picocli has supported `@Spec` in ArgGroup classes since 4.6,
so the compile-time check rejected valid code.

Before 4.7.7 the check happened to pass for ArgGroup classes because
options inside such a class were looked up by the `@ArgGroup` variable
rather than by its type, missed the group, and fell through to
`getOrCreateCommandSpecForArg`, which registered a `CommandSpec` for the
ArgGroup class as a side effect. 4.7.7 fixed that lookup, and the latent
check started to fire.

Remove the check, as the maintainer suggested in the issue: `@Spec` is
valid in several places that are not commands (ArgGroup classes, mixins,
IVersionProvider implementations), and picocli injects the `CommandSpec`
at runtime without the processor needing to attach it to a model object.
Elements that are not enclosed in a command are now traced at FINE level
instead of being reported as errors.

Closes remkop#2430

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@Spec must be enclosed in a @Command, or in a class that implements IVersionProvider

1 participant