Skip to content

Commit d19e71e

Browse files
bokelleyclaude
andauthored
feat(migrate): --auto-apply mode for mechanically-rewritable codemod findings (#540)
* feat(migrate): --auto-apply mode for mechanically-rewritable codemod findings Extends `python -m adcp.migrate v3-to-v4` with `--auto-apply`: rewrites the ~78% of findings that are mechanically safe (flag_private + flag_numbered with known aliases) while leaving flag_removed findings for human review. - Add NUMBERED_ASSETS_RENAMES dict mapping Assets<N> to semantic aliases - Add _AUTO_APPLY_PUBLIC_SYMBOLS frozenset for safe-rewrite eligibility - Add auto_applied field to Report; route kind==auto_applied there - Two-pass rewrite: (1) numbered asset substitution, (2) generated_poc import path fix for lines where all symbols have public equivalents - Fix pre-existing silent-drop bug: unknown symbols on mixed import lines were silently discarded; now always emit flag_private - --auto-apply implies --apply; enforced before dirty-tree guard - JSON report gains auto_applied array (additive, no version bump) - 16 new tests (total 49, all pass) Closes #512 https://claude.ai/code/session_01MiPRbdJUEFBes5zzUGd5Vb * fix(migrate): apply dx-expert review feedback on --auto-apply - Text report hints at --auto-apply when flag_private/flag_numbered findings remain and the flag was not used (discoverability) - --apply help text cross-links --auto-apply - Dirty-tree error shows --auto-apply when that flag was used - Exit code semantics (0/1/2) documented in argparse description - MIGRATION_v3_to_v4.md: add --auto-apply example + description - 2 new tests for tip-line presence/absence (51 total, all pass) https://claude.ai/code/session_01MiPRbdJUEFBes5zzUGd5Vb * fix(migrate): address code-reviewer findings on --auto-apply Two bugs found in pre-PR review: 1. apply_changes=False guard missing on auto-apply rewrite block. run(apply_changes=False, auto_apply=True) was silently writing files because the auto_apply block only checked `auto_apply and auto_apply_hits` with no apply_changes guard. Fixed by requiring apply_changes too. 2. all_known check excluded numbered-asset symbols on mixed lines. A line like `from ...generated_poc import Assets81, ContextObject` got all_known=False (Assets81 not in GENERATED_POC_SYMBOL_MAP), so ContextObject was flagged even though both symbols are auto-applicable. Fixed: all_known now treats numbered assets as resolvable when auto_apply=True. New tests: - test_dry_run_with_auto_apply_does_not_write_files (regression guard) - test_auto_apply_numbered_plus_known_symbol_same_line (mismatch case) 53 tests total, all pass. https://claude.ai/code/session_01MiPRbdJUEFBes5zzUGd5Vb * chore(migrate): fix orphaned test section header; document scan_file auto_apply contract - Remove misplaced "Pre-existing silent-drop bug fix" section header that sat above the discoverability tests; reattach it immediately before test_mixed_line_unknown_symbol_not_silently_dropped - scan_file docstring now documents that auto_apply=True without apply_changes=True produces findings but never writes files https://claude.ai/code/session_01MiPRbdJUEFBes5zzUGd5Vb * fix(migrate): don't corrupt mixed numbered+unknown imports under --auto-apply Per review on #540 — a generated_poc import mixing a known numbered asset (Assets81) with an unknown one (Assets149) was getting half-rewritten: Input : from adcp.types.generated_poc.core.format import Assets81, Assets149 Output: from adcp.types.generated_poc.core.format import VideoFormatAsset, Assets149 leaving VideoFormatAsset imported from a private module path that doesn't export it — guaranteed ImportError in adopter source. Root cause: step 1 (file-wide Assets<N> substitution) ran before step 2 (import-path safety check) had a chance to veto the line. Fix: line-by-line rewrite. For each generated_poc single-line import, compute the post-numbered-substitution symbol set up-front; only run both substitutions when every symbol on the line is in ``_AUTO_APPLY_PUBLIC_SYMBOLS``. Mixed-unsafe lines are left entirely alone. Non-import lines still get free numbered substitution. Scan-time also fixed: numbered references on a mixed-unsafe import line now report ``flag_numbered`` instead of ``auto_applied`` so the report matches the file content. Adds regression test ``test_auto_apply_mixed_numbered_known_unknown_does_not_corrupt_import``. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8ea85ad commit d19e71e

3 files changed

Lines changed: 757 additions & 70 deletions

File tree

MIGRATION_v3_to_v4.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,23 @@ python -m adcp.migrate v3-to-v4 ./src
1717
# Rewrite in place. Commit first so `git diff` is your review.
1818
python -m adcp.migrate v3-to-v4 ./src --apply
1919

20+
# Also auto-fix safe import rewrites (generated_poc paths + numbered Assets aliases).
21+
# flag_removed findings still require human review.
22+
python -m adcp.migrate v3-to-v4 ./src --auto-apply
23+
2024
# Structured JSON for CI / editor integrations.
2125
python -m adcp.migrate v3-to-v4 ./src --json
2226
```
2327

24-
The CLI exits 1 when there are manual-review findings (removed types, numbered
25-
`Assets` imports, `adcp.types.generated_poc` imports) — wire it into CI to
26-
gate merges until every flagged usage is addressed.
28+
`--auto-apply` implies `--apply` and additionally rewrites the ~78% of findings
29+
that are mechanically safe: `from adcp.types.generated_poc.X import Symbol` lines
30+
where every symbol has a known public alias on `adcp.types`, and `Assets<N>` numbered
31+
classes that have a documented semantic alias (`Assets81 → VideoFormatAsset`, etc.).
32+
`flag_removed` findings always require human attention.
33+
34+
The CLI exits 0 when all remaining findings are mechanical (or none); exits 1 when
35+
`flag_removed` findings remain for human review — wire it into CI to gate merges
36+
until every flagged usage is addressed.
2737

2838
## Audit your exposure first
2939

0 commit comments

Comments
 (0)