diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/package.json b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/package.json new file mode 100644 index 0000000000..6a2f1757bc --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/package.json @@ -0,0 +1,7 @@ +{ + "name": "workspace-root", + "private": true, + "workspaces": [ + "vendor/*" + ] +} diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/snapshots.toml new file mode 100644 index 0000000000..81639391ac --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/snapshots.toml @@ -0,0 +1,64 @@ +[[case]] +name = "migration_workspace_member_cwd" +vp = "global" +cwd = "vendor/sub" +steps = [ + { argv = [ + "vp", + "migrate", + "--no-interactive", + "--no-agent", + "--no-editor", + "--no-hooks", + ], comment = "vp migrate rejects a workspace member before it changes files", continue-on-failure = true }, + { argv = [ + "vpt", + "print-file", + "../../package.json", + ], comment = "the workspace root package.json is unchanged", continue-on-failure = true }, + { argv = [ + "vpt", + "print-file", + "package.json", + ], comment = "the workspace member package.json is unchanged", continue-on-failure = true }, + { argv = [ + "vpt", + "stat-file", + "../../pnpm-workspace.yaml", + "--assert", + "missing", + ], comment = "the migration created no package-manager files at the workspace root" }, +] + +[[case]] +name = "migration_workspace_member_explicit_path" +vp = "global" +cwd = "vendor/sub" +steps = [ + { argv = [ + "vp", + "migrate", + ".", + "--no-interactive", + "--no-agent", + "--no-editor", + "--no-hooks", + ], comment = "vp migrate rejects an explicit workspace-member target before it changes files", continue-on-failure = true }, + { argv = [ + "vpt", + "print-file", + "../../package.json", + ], comment = "the workspace root package.json is unchanged", continue-on-failure = true }, + { argv = [ + "vpt", + "print-file", + "package.json", + ], comment = "the workspace member package.json is unchanged", continue-on-failure = true }, + { argv = [ + "vpt", + "stat-file", + "../../pnpm-workspace.yaml", + "--assert", + "missing", + ], comment = "the migration created no package-manager files at the workspace root" }, +] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/snapshots/migration_workspace_member_cwd.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/snapshots/migration_workspace_member_cwd.md new file mode 100644 index 0000000000..bb5d853f6c --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/snapshots/migration_workspace_member_cwd.md @@ -0,0 +1,49 @@ +# migration_workspace_member_cwd + +## `vp migrate --no-interactive --no-agent --no-editor --no-hooks` + +vp migrate rejects a workspace member before it changes files + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +Vite+ cannot migrate a workspace member. Run `vp migrate` from the workspace root at . +``` + +## `vpt print-file ../../package.json` + +the workspace root package.json is unchanged + +``` +{ + "name": "workspace-root", + "private": true, + "workspaces": [ + "vendor/*" + ] +} +``` + +## `vpt print-file package.json` + +the workspace member package.json is unchanged + +``` +{ + "name": "workspace-member", + "private": true, + "devDependencies": { + "vitest": "" + } +} +``` + +## `vpt stat-file ../../pnpm-workspace.yaml --assert missing` + +the migration created no package-manager files at the workspace root + +``` +../../pnpm-workspace.yaml: missing +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/snapshots/migration_workspace_member_explicit_path.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/snapshots/migration_workspace_member_explicit_path.md new file mode 100644 index 0000000000..5857314458 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/snapshots/migration_workspace_member_explicit_path.md @@ -0,0 +1,49 @@ +# migration_workspace_member_explicit_path + +## `vp migrate . --no-interactive --no-agent --no-editor --no-hooks` + +vp migrate rejects an explicit workspace-member target before it changes files + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +Vite+ cannot migrate a workspace member. Run `vp migrate` from the workspace root at . +``` + +## `vpt print-file ../../package.json` + +the workspace root package.json is unchanged + +``` +{ + "name": "workspace-root", + "private": true, + "workspaces": [ + "vendor/*" + ] +} +``` + +## `vpt print-file package.json` + +the workspace member package.json is unchanged + +``` +{ + "name": "workspace-member", + "private": true, + "devDependencies": { + "vitest": "" + } +} +``` + +## `vpt stat-file ../../pnpm-workspace.yaml --assert missing` + +the migration created no package-manager files at the workspace root + +``` +../../pnpm-workspace.yaml: missing +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/vendor/sub/package.json b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/vendor/sub/package.json new file mode 100644 index 0000000000..96df63ca31 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_member_target/vendor/sub/package.json @@ -0,0 +1,7 @@ +{ + "name": "workspace-member", + "private": true, + "devDependencies": { + "vitest": "4.1.10" + } +} diff --git a/docs/guide/migrate.md b/docs/guide/migrate.md index 9de7c63958..a9243c27d7 100644 --- a/docs/guide/migrate.md +++ b/docs/guide/migrate.md @@ -22,6 +22,9 @@ The positional `PATH` argument is optional. - If omitted, `vp migrate` migrates the current directory - If provided, it migrates that target directory instead +- For a monorepo, the target must be the workspace root. Vite+ cannot + migrate one workspace member, because migration updates the package-manager + configuration, the catalogs, and the lockfiles that all members share. ```bash vp migrate diff --git a/packages/cli/src/migration/bin.ts b/packages/cli/src/migration/bin.ts index d856ef8d9d..75a1b5148c 100644 --- a/packages/cli/src/migration/bin.ts +++ b/packages/cli/src/migration/bin.ts @@ -1044,6 +1044,15 @@ async function main() { printHeader(); const workspaceInfoOptional = await detectWorkspace(projectPath); + if ( + workspaceInfoOptional.isMonorepo && + path.resolve(projectPath) !== path.resolve(workspaceInfoOptional.rootDir) + ) { + cancelAndExit( + `Vite+ cannot migrate a workspace member. Run \`vp migrate\` from the workspace root at ${workspaceInfoOptional.rootDir}.`, + 1, + ); + } const initialChangedPaths = await collectChangedFormatPaths(workspaceInfoOptional.rootDir); const preExistingChangedPaths = initialChangedPaths ? new Set(initialChangedPaths) : undefined; const resolvedPackageManager = workspaceInfoOptional.packageManager ?? 'unknown';