Skip to content

feat(v1.55.0): add remove-kubernetes-implicit-children codemod - #168

Merged
schultzp2020 merged 5 commits into
mainfrom
feat/v1.55.0/remove-kubernetes-implicit-children
Oct 13, 2026
Merged

schultzp2020 merged 5 commits into
mainfrom
feat/v1.55.0/remove-kubernetes-implicit-children

Conversation

@schultzp2020

@schultzp2020 schultzp2020 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Closes #152.

Summary

@backstage/plugin-kubernetes-react JSX usage

- `Fragment` tag was treated as inert unconditionally

- shorthand fragments (`<>...</>`) were always classified unsafe

- local block-scoped shadows with imported alias names could be misclassified as imported component usages

- intrinsic JSX detection used `firstChar === firstChar.toLowerCase()`, so `_Widget` / `$Comp` were misclassified as inert

+ inert `Fragment` / `React.Fragment` now requires a proven React import binding

+ shorthand fragments are recursively analyzed and treated inert when children are inert

+ target component matches now require proven import-binding identity (semantic references), so unproven/shadowed usages are skipped conservatively

+ intrinsic JSX detection now requires an explicit ASCII lowercase prefix (`/^[a-z]/`), so `_Widget` / `$Comp` stay conservative (TODO path)

Preserved prior shadowed-parameter provenance behavior and extended coverage for sibling/block-local shadows.

Corrective follow-up for review blocker 0526c880: fixed non-letter JSX tag misclassification (_Widget / $Comp).

Added fixture seams:

  • fragment-local-component-todo

  • shorthand-fragment-safe

  • named-alias-shadowed-block-local

  • namespace-alias-shadowed-block-local

  • non-letter-component-todo

Evidence

  • RED before fix (new fixtures):

    • cd codemods/v1.55.0/remove-kubernetes-implicit-children && yarn test

      
      running 12 tests
      
      test fragment-local-component-todo        ... FAILED
      
      test named-alias-shadowed-block-local     ... FAILED
      
      test namespace-alias-shadowed-block-local ... FAILED
      
      test shorthand-fragment-safe              ... FAILED
      
      test non-letter-component-todo            ... FAILED
      
      
  • GREEN after fix:

    • cd codemods/v1.55.0/remove-kubernetes-implicit-children && yarn test

      
      running 12 tests
      
      test effectful-children-todo              ... ok
      
      test fragment-local-component-todo        ... ok
      
      test named-alias-shadowed-block-local     ... ok
      
      test named-alias-shadowed-parameter       ... ok
      
      test named-and-aliased-import             ... ok
      
      test namespace-alias-shadowed-block-local ... ok
      
      test namespace-alias-shadowed-parameter   ... ok
      
      test namespace-import-and-cleanup         ... ok
      
      test noop-idempotent                      ... ok
      
      test noop-other-module                    ... ok
      
      test shorthand-fragment-safe              ... ok
      
      test non-letter-component-todo            ... ok
      
      
      
      test result: ok. 12 passed; 0 failed
      
      
    • yarn format

    • yarn lint

    • yarn test

    • yarn check:changed

  • Performance audit (workflow path, representative mostly inert corpus = codemods/):

    • no-op workflow dry-run (__perf_noop.workflow.yaml) x3: 1.710s, 1.628s, 1.586s (avg 1.641s)

    • real workflow dry-run (workflow.yaml) x3: 3.607s, 3.589s, 3.615s (avg 3.604s)

    • delta: +1.963s, ~2.20x vs no-op; no 10-100x pathological gap from JSSG perf guide.

    • edit/idempotence check on copied corpus:

      • pass 1: 9 files changed (11 insertions(+), 18 deletions(-))

      • pass 2: 0 files changed

Approved clean-source QA (read-only)

  • Local workflow dry-run on Backstage 0863f0349c63fa7475b89aed71b6fb8214791394: rc=0 (~8s), zero exact FixDialog/ContainerCard/PodLogs import candidates, no edits/TODOs; clean SHA/status unchanged.
  • Local workflow dry-run on clean detached community-plugins 4c760a005dd582df1a61aec39ae50ad565f6dbbc: rc=0 (~6s), zero exact target candidates, no edits/TODOs; clean SHA/status unchanged. Original dirty checkout untouched.
  • Positive edits/idempotence are evidenced by fixtures and the synthetic workflow corpus, not real-source mutation; CLI dry-run output lacks explicit per-file counters.

Merge Danger

Door: one-way

Codemod now removes children only when imported component/React fragment identities are proven; ambiguous bindings are left unchanged (or TODO-annotated for effectful paths).

Blast Radius: migration

Only @backstage/remove-kubernetes-implicit-children users are affected.

Main reconciliation and full-suite side effect

  • Merged origin/main at 53b1076 (including feat(v1.55.0): rename connections public API symbols #164 Git-env fixture isolation). Kept README.md byte-for-byte identical to main; yarn.lock differs from main only by this workspace stanza. Preserved the minor changeset.
  • Immutable Yarn install; Husky pre-commit/pre-push dispatchers generated and verified. yarn format, yarn lint, yarn test, yarn check:changed (12/12 package fixtures), and shipped workflow.yaml positive fixture + second-pass idempotence passed.
  • Full yarn test generated an untracked 145-byte codemods/v1.55.0/remove-relations-compatibility-config/tests/flow-inline-comment-preserved-when-catalog-emptied/metrics.json (Git blob 42847c1041d21d4278619381aa2d51455bc1b654). Verified that was the only worktree change, backed it up outside the worktree, and removed only that generated file. No feat(v1.55.0): add remove-relations-compatibility-config codemod #162 source or ignore rules were changed.

@schultzp2020
schultzp2020 marked this pull request as draft October 12, 2026 21:04
@schultzp2020

Copy link
Copy Markdown
Contributor Author

Review-blocked: JSX target matching currently uses imported names textually. A local PodLogs/namespace alias shadowing the import can cause unrelated children to be removed. Add shadowed-binding fixtures, bind JSX identity to @backstage/plugin-kubernetes-react import or conservatively skip, then independent review. Keep draft.

@schultzp2020

Copy link
Copy Markdown
Contributor Author

Fresh review blocker at 352b8c0: inert JSX tag check treats _Widget/$Comp as lowercase intrinsic because first character equals its lowercase form; may remove effectful children. Sole writer adding failing fixture and explicit intrinsic predicate; keep draft pending exact-head CI/review.

@schultzp2020
schultzp2020 marked this pull request as ready for review October 12, 2026 21:43
@schultzp2020
schultzp2020 merged commit 471bf89 into main Oct 13, 2026
2 checks passed
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.

feat: Backstage 1.55.0 migration - Remove unused Kubernetes component children

1 participant