[codemod] Add migration CLI - #14690
Conversation
🦋 Changeset detectedLatest commit: 0effaad The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
✅ All changesets look good |
|
Review posted successfully to PR #14690 with a summary and two inline suggestion comments. Summary of what I flagged:
|
@cloudflare/autoconfig
@cloudflare/build-output-utils
@cloudflare/codemods
@cloudflare/config
create-cloudflare
@cloudflare/deploy-helpers
@cloudflare/kv-asset-handler
miniflare
@cloudflare/pages-functions
@cloudflare/pages-shared
@cloudflare/unenv-preset
@cloudflare/vite-plugin
@cloudflare/vitest-pool-workers
@cloudflare/workers-auth
@cloudflare/workers-editor-shared
@cloudflare/workers-utils
wrangler
commit: |
This comment was marked as outdated.
This comment was marked as outdated.
25bcf37 to
0267d3f
Compare
Separate the two unrelated concerns that were sharing `packages/codemod`: - `@cloudflare/codemods` (`packages/codemods`) — the public Vitest migration CLI, run via `npx @cloudflare/codemods vitest`. Bin renamed to `cloudflare-codemods`. - `@cloudflare/shared-ast-primitives` (`packages/shared-ast-primitives`) — the private `recast`-based AST helpers consumed by C3 and autoconfig, restored to `private: true`. Update all `@cloudflare/codemod` consumers in autoconfig and create-cloudflare to import from `@cloudflare/shared-ast-primitives`, and the deploy-package validation set accordingly.
# Conflicts: # pnpm-lock.yaml
Rewrite the Vitest v3→v4 transform on top of `@cloudflare/shared-ast-primitives` (recast) instead of jscodeshift, dropping the `jscodeshift` and `@types/jscodeshift` dev dependencies. The shared library now re-exports the `print`/`types` recast primitives and types `parseJs`/`parseTs` return values so transforms can be authored without a direct recast dependency.
Split the codemod context into `CodemodContext` and a `RunContext` that requires `stagedFiles`, so `transformFiles` always stages in memory. Removes the unreachable direct-to-disk write branch, keeping the ordered run atomic (flushed only after all codemods succeed).
Remove the category grouping and the batch "run every codemod in a category" behaviour. Codemods are now identified by a single `vitest:`-prefixed name (e.g. `vitest:v3-to-v4`) and run one at a time via `runCodemod(name, context)`. The CLI takes a single codemod name as its positional argument.
# Conflicts: # pnpm-lock.yaml
|
Codeowners approval required for this PR:
Show detailed file reviewers |
# Conflicts: # pnpm-lock.yaml
- Rename stale `@cloudflare/vitest-pool-workers` references anywhere in package.json (scripts, `pnpm.overrides`, `resolutions`), not just the four dependency groups, so a migrated project has no leftover references. - Update `vitest-pool-workers` AGENTS.md to drop the removed codemods build.
dario-piotrowicz
left a comment
There was a problem hiding this comment.
LGTM 🙂
I just left a few small nits
workers-devprod
left a comment
There was a problem hiding this comment.
Codeowners reviews satisfied
# Conflicts: # pnpm-lock.yaml
|
Codeowners approval required for this PR:
Show detailed file reviewers |
| { | ||
| name: "vitest:pool-workers-to-vitest-plugin", | ||
| aliases: ["vitest pool workers to vitest plugin", "vitest v1"], | ||
| description: `Rename ${OLD_PACKAGE} to ${NEW_PACKAGE} v1`, | ||
| async run(context) { | ||
| const changedFiles = await transformFiles( | ||
| context, | ||
| SOURCE_PATTERNS, | ||
| (source, filePath) => | ||
| filePath.endsWith("package.json") | ||
| ? renamePackageDependency(source) | ||
| : source.replaceAll(OLD_PACKAGE, NEW_PACKAGE) | ||
| ); | ||
| return { changedFiles }; | ||
| }, | ||
| }, |
There was a problem hiding this comment.
🟡 Running the two Vitest migrations in the wrong order silently leaves configuration unmigrated
The configuration migration only recognises files that still mention the old package name (transformV3ToV4 at packages/codemods/src/codemods/vitest.ts:83), so if the rename migration is run first it quietly does nothing and reports success.
Impact: Users who run the rename step first end up with a renamed but still-unmigrated test configuration and no warning that the second migration did not apply.
Why the second ordering fails: the v3→v4 transform matches on the literal old package specifier
packages/codemods/src/codemods/vitest-v3-to-v4.ts:56-61 only selects import declarations whose source is exactly "@cloudflare/vitest-pool-workers/config". The vitest:pool-workers-to-vitest-plugin codemod rewrites every textual occurrence of @cloudflare/vitest-pool-workers to @cloudflare/vitest-plugin (packages/codemods/src/codemods/vitest.ts:99), including that import specifier. After that rename, matchingImports.length === 0 and transform() returns the source unchanged (packages/codemods/src/codemods/vitest-v3-to-v4.ts:88-90), so transformFiles reports zero changed files and the CLI prints "Project is already up to date." (packages/codemods/src/bin.ts:57-61).
The repo's own test runs them in the correct order (packages/codemods/test/runner.test.ts:59-63), but nothing in the CLI or README (packages/codemods/README.md:11-16) states that order is significant, and each codemod is invoked individually by name.
Prompt for agents
The two Vitest codemods in packages/codemods/src/codemods/vitest.ts are order-dependent: `vitest:v3-to-v4` matches imports from the literal specifier "@cloudflare/vitest-pool-workers/config", while `vitest:pool-workers-to-vitest-plugin` textually rewrites that specifier to "@cloudflare/vitest-plugin". If a user runs the rename first (each codemod is run individually by name from the CLI), the v3→v4 transform becomes a silent no-op and the CLI reports the project as already up to date. Consider either making the v3→v4 transform also recognise the new package specifier (`@cloudflare/vitest-plugin/config`), or having the rename codemod detect a still-v3-shaped config and error/warn, or documenting and enforcing the required ordering in the CLI/README.
Was this helpful? React with 👍 or 👎 to provide feedback.
Makes
@cloudflare/codemodsa public, executable package for running Cloudflare project migrations, and extracts the sharedrecasthelpers into a private@cloudflare/shared-ast-primitiveslibrary.What's included
cloudflare-codemods <codemod>CLI that runs a single named codemod against a project — with--cwd,--files, and--dry-runoptions.vitest:v3-to-v4— migrate@cloudflare/vitest-pool-workersconfiguration from Vitest v3 to v4vitest:pool-workers-to-vitest-plugin— rename@cloudflare/vitest-pool-workersto@cloudflare/vitest-pluginv1@cloudflare/shared-ast-primitives(arecastwrapper shared with C3 and autoconfig) — the existing Vitest v3-to-v4 transform moves out of@cloudflare/vitest-pool-workersand into this package.Codemods are identified and run individually by name (e.g.
npx @cloudflare/codemods vitest:v3-to-v4); there's no category grouping.A picture of a cute animal (not mandatory, but encouraged)