Skip to content

PLUGINAPI-190 Promote hidden to a first-class flag on PropertyDefinition - #290

Merged
steve-marion-sonarsource merged 3 commits into
masterfrom
sma/hidden-first-class-flag
May 19, 2026
Merged

PLUGINAPI-190 Promote hidden to a first-class flag on PropertyDefinition#290
steve-marion-sonarsource merged 3 commits into
masterfrom
sma/hidden-first-class-flag

Conversation

@steve-marion-sonarsource

@steve-marion-sonarsource steve-marion-sonarsource commented May 7, 2026

Copy link
Copy Markdown
Contributor

WHY:

The current plugin-api exposes hidden, setScope, and setOnlyScope. However, the effect of hidden is limited and only covers hiding the global variable when defined with scope. It is unusable with a scope. Internally, it is dropped, and its effect comes through the global flag, which disables showing the parameter at the instance level when no scope is defined.
This is against the initial intention described in MMF-339.

WHAT:

Add support for hiding properties independently from their scoped or global definition.
Keep backward compatibility with existing definitions.

HOW:

Keep the hidden value as defined by the builder, and set global to represent whether the property is intended to be configured at the global level.
hidden now has the meaning of hiding the property from the UI by not listing it.
global now has the meaning of allowing get/edit of properties at the instance level.
This allows simplifying the code by removing checks on global and scope that were carrying the hidden meaning before.

A backward-compatible translation is put in place for the legacy @Property(global = false, scope=[]) idiom. It is auto-translated to hidden = true, global = true, configScopes = [] which keep the behavior intact. The annotation itself is intentionally not extended with a hidden field, as it is already considered legacy and the builder should be used instead.

Current behavior — truth table

Builder input valid? Resulting state Effect (no component) Effect (comp = X)
.hidden() .onConfigScopes(X) .onlyOnConfigScopes(X) global configScopes listed settable listed settable
true[]
false[](via isGlobal fallback)
true[X]
false[X]

Proposed behavior — truth table

Builder input valid? Resulting state Effect (no component) Effect (comp = X)
.hidden() .onConfigScopes(X) .onlyOnConfigScopes(X) hidden global configScopes listed settable listed settable
falsetrue[]
truetrue[](via !hidden)
falsetrue[X]
falsefalse[X]
(newly allowed)truetrue[X](via !hidden)(via !hidden)
(newly allowed)truefalse[X](via !hidden)(via !hidden)

@steve-marion-sonarsource
steve-marion-sonarsource requested a review from a team as a code owner May 7, 2026 13:16
@hashicorp-vault-sonar-prod hashicorp-vault-sonar-prod Bot changed the title Promote hidden to a first-class flag on PropertyDefinition PLUGINAPI-190 Promote hidden to a first-class flag on PropertyDefinition May 7, 2026
@hashicorp-vault-sonar-prod

hashicorp-vault-sonar-prod Bot commented May 7, 2026

Copy link
Copy Markdown

PLUGINAPI-190

@sonar-review-alpha

sonar-review-alpha Bot commented May 7, 2026

Copy link
Copy Markdown

Summary

⚠️ The PR description exceeded the analysis limit and was truncated. The review may not reflect all context.

This PR promotes hidden from an implicit side effect to a first-class flag on PropertyDefinition, decoupling visibility from global/scope configuration. Previously, hidden was only settable via the builder but had no field and was immediately overridden; the PR fixes this by storing the hidden flag directly and using it to determine UI visibility independently of the global flag.

A backward-compatibility translation is built into the annotation parser: the legacy pattern @Property(global = false, scopes=[]) is auto-converted to hidden=true, global=true, configScopes=[], preserving existing behavior. Importantly, the @Property annotation itself is not extended with a hidden field—it remains legacy-only and developers should use the builder for new code.

The validation rule preventing hidden + scopes is removed; you can now hide a property at any scope configuration, which was previously impossible.

What reviewers should know

Start by reviewing:

  1. The annotation translation logic in PropertyDefinition.create() (lines 192-207) — this is where backward compatibility lives. The comments explain what each combination means.
  2. The new hidden() getter (lines 359-365) — straightforward but critical for the API.
  3. The removed validation and global-overriding code (around line 670-673) — these constraints no longer apply.

Key decisions to verify:

  • The legacy idiom translation only triggers for global=false with empty scopes. This is the narrow case that represents "hidden but settable at instance level."
  • The hidden field is initialized from builder.hidden in the constructor, ensuring the builder's intent is preserved (this was the bug before).
  • Removed tests that enforced !hidden || no scopes; now hidden properties can have any scope config. The new tests (lines 99-138) validate all combinations work.

Watch for:

  • The backward-compatibility translation assumes existing code using @Property(global=false) with no scopes was trying to hide properties. If real-world plugins use this pattern for a different reason, behavior changes.
  • Tests replace old negative cases with new positive ones—make sure all old constraints are actually obsolete and the new behavior is documented elsewhere (e.g., in Javadoc or MMF-339).

  • Generate Walkthrough
  • Generate Diagram

🗣️ Give feedback

@steve-marion-sonarsource
steve-marion-sonarsource force-pushed the sma/hidden-first-class-flag branch from 11aee1a to 6d8052c Compare May 7, 2026 13:21
sonar-review-alpha[bot]

This comment was marked as outdated.

@steve-marion-sonarsource
steve-marion-sonarsource force-pushed the sma/hidden-first-class-flag branch from 6d8052c to 6365a7c Compare May 7, 2026 16:09
sonar-review-alpha[bot]

This comment was marked as outdated.

@steve-marion-sonarsource

Copy link
Copy Markdown
Contributor Author

Dropping this change.

sonar-review-alpha[bot]

This comment was marked as outdated.

Persist `hidden` as an instance field on PropertyDefinition with a
public `hidden()` getter, so consumers can filter UI listings on it.

Drop the build-time mutex that forbade combining `.hidden()` with
`.onConfigScopes(...)` / `.onlyOnConfigScopes(...)`, and drop the
`if (hidden) global = false` coercion. `hidden` is now orthogonal to
`global` and `configScopes`, enabling per-project-settable properties
that are not exposed in the Settings UI.
@steve-marion-sonarsource
steve-marion-sonarsource force-pushed the sma/hidden-first-class-flag branch from 6365a7c to defbc5f Compare May 12, 2026 07:33
sonar-review-alpha[bot]

This comment was marked as resolved.

@sonarqube-next

Copy link
Copy Markdown

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done!

sonar-review-alpha[bot]

This comment was marked as outdated.

@sonar-review-alpha sonar-review-alpha Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new commit is a one-line comment correction ("not visible but settable at scope only""visible and settable at scope only"). No logic was changed. The previously flagged concern about @Beta on the new hidden() getter and Builder.hidden() is still open.

🗣️ Give feedback

@sonarqube-next

Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

@steve-marion-sonarsource
steve-marion-sonarsource merged commit e7512dd into master May 19, 2026
7 of 9 checks passed
@steve-marion-sonarsource
steve-marion-sonarsource deleted the sma/hidden-first-class-flag branch May 19, 2026 14:13
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.

3 participants