crossplane-contrib / crossplane-contrib/crossplane-diff
Crossplane client GVK caches in single-version clients are dead code
- Dominant language
- Go
- Stars
- 42
- Forks
- 15
- Avg merge
- 10h 26m
- Merged PRs (30d)
- 33
Description
## Summary
Three of the Crossplane clients populate a \`c.gvks\` cache via \`GetGVKsForGroupKind\` during \`Initialize\` but never read it — the actual list/get paths use a hardcoded single-version GVK. The cache is dead storage today; if Crossplane ever ships a v2 of any of these resources, the hardcoded paths will silently miss the new versions.
## Affected clients
| File | Cached group | Hardcoded list GVK | TODO present? |
|---|---|---|---|
| \`cmd/diff/client/crossplane/composition_client.go\` | \`apiextensions.crossplane.io\` | \`apiextensions.crossplane.io/v1, Composition\` | yes |
| \`cmd/diff/client/crossplane/composition_revision_client.go\` | \`apiextensions.crossplane.io\` | \`apiextensions.crossplane.io/v1, CompositionRevision\` | no (same pattern) |
| \`cmd/diff/client/crossplane/function_client.go\` | \`pkg.crossplane.io\` (was wrong group until #309) | \`pkg.crossplane.io/v1, Function\` | yes |
For comparison, \`definition_client.go\` (XRDs) and \`environment_client.go\` (EnvironmentConfigs) use the same pattern correctly: they call \`listMatchingResources(ctx, c.client, c.gvks, ...)\` to fan out across every discovered version.
## Background
The cache and \`GetGVKsForGroupKind\` were introduced in commit c155e30 to support the v1↔v2 transition for XRDs and EnvironmentConfigs. The pattern was retrofitted onto Composition/CompositionRevision/Function clients but the read side was never wired up. The TODOs at \`composition_client.go:103\` and \`function_client.go:80\` capture the known reason: those clients use typed structs from \`apiextensionsv1\`, so iterating versions requires per-version unstructured→typed conversion code that doesn't exist yet.
## Consequences
- **Today:** zero functional impact — Crossplane only ships v1 of Composition, CompositionRevision, and Function, so the hardcoded GVK matches reality.
- **If Crossplane ships v2 of any of these:** silent diffs against the wrong/missing version. Lookups would either return nothing or fail to decode v2 unstructured into the v1 typed struct.
- **Function client until #309:** the discovery query used the wrong group (\`apiextensions\` instead of \`pkg\`), so \`c.gvks\` was always an empty slice. PR #309 fixed the group, but the field is still unread.
## Resolution options
Pick one:
1. **Delete the dead cache.** Remove the \`gvks\` field, the \`GetGVKsForGroupKind\` call in \`Initialize\`, and any related plumbing from the three clients above. Cheapest fix; defers multi-version support to whenever Crossplane actually ships it.
2. **Wire up multi-version listing.** Use \`c.gvks\` + \`listMatchingResources\` in those clients, and add per-version conversion to the typed structs. Closes the future gap proactively. More work.
Option 1 reflects current reality; option 2 is what the TODOs are gesturing at. Either is fine — picking deliberately is the point.
Contributor guide
Research direction
Start with composition_client.go, composition_revision_client.go, and function_client.go, then compare definition_client.go and environment_client.go for the working cache pattern. Review the TODOs and the two resolution options, including the typed-struct conversion constraint. Done means either removing the unused cache plumbing from all three clients or wiring version-aware listing and conversions consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100