Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "workspace-root",
"private": true,
"workspaces": [
"vendor/*"
]
}
Original file line number Diff line number Diff line change
@@ -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 = "reject migration from a workspace member before changing files", continue-on-failure = true },
{ argv = [
"vpt",
"print-file",
"../../package.json",
], comment = "workspace root remains unchanged", continue-on-failure = true },
{ argv = [
"vpt",
"print-file",
"package.json",
], comment = "workspace member remains unchanged", continue-on-failure = true },
{ argv = [
"vpt",
"stat-file",
"../../pnpm-workspace.yaml",
"--assert",
"missing",
], comment = "no package-manager files are created 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 = "reject an explicit workspace-member target before changing files", continue-on-failure = true },
{ argv = [
"vpt",
"print-file",
"../../package.json",
], comment = "workspace root remains unchanged", continue-on-failure = true },
{ argv = [
"vpt",
"print-file",
"package.json",
], comment = "workspace member remains unchanged", continue-on-failure = true },
{ argv = [
"vpt",
"stat-file",
"../../pnpm-workspace.yaml",
"--assert",
"missing",
], comment = "no package-manager files are created at the workspace root" },
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# migration_workspace_member_cwd

## `vp migrate --no-interactive --no-agent --no-editor --no-hooks`

reject migration from a workspace member before changing files

**Exit code:** 1

```
VITE+ - The Unified Toolchain for the Web

Cannot migrate a workspace member independently. Run `vp migrate` from the workspace root at <workspace>.
```

## `vpt print-file ../../package.json`

workspace root remains unchanged

```
{
"name": "workspace-root",
"private": true,
"workspaces": [
"vendor/*"
]
}
```

## `vpt print-file package.json`

workspace member remains unchanged

```
{
"name": "workspace-member",
"private": true,
"devDependencies": {
"vitest": "<version>"
}
}
```

## `vpt stat-file ../../pnpm-workspace.yaml --assert missing`

no package-manager files are created at the workspace root

```
../../pnpm-workspace.yaml: missing
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# migration_workspace_member_explicit_path

## `vp migrate . --no-interactive --no-agent --no-editor --no-hooks`

reject an explicit workspace-member target before changing files

**Exit code:** 1

```
VITE+ - The Unified Toolchain for the Web

Cannot migrate a workspace member independently. Run `vp migrate` from the workspace root at <workspace>.
```

## `vpt print-file ../../package.json`

workspace root remains unchanged

```
{
"name": "workspace-root",
"private": true,
"workspaces": [
"vendor/*"
]
}
```

## `vpt print-file package.json`

workspace member remains unchanged

```
{
"name": "workspace-member",
"private": true,
"devDependencies": {
"vitest": "<version>"
}
}
```

## `vpt stat-file ../../pnpm-workspace.yaml --assert missing`

no package-manager files are created at the workspace root

```
../../pnpm-workspace.yaml: missing
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "workspace-member",
"private": true,
"devDependencies": {
"vitest": "4.1.10"
}
}
3 changes: 3 additions & 0 deletions docs/guide/migrate.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. Workspace members
cannot be migrated independently because migration updates shared package
manager configuration, catalogs, and lockfiles.

```bash
vp migrate
Expand Down
9 changes: 9 additions & 0 deletions packages/cli/src/migration/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,15 @@ async function main() {
printHeader();

const workspaceInfoOptional = await detectWorkspace(projectPath);
if (
workspaceInfoOptional.isMonorepo &&
path.resolve(projectPath) !== path.resolve(workspaceInfoOptional.rootDir)
) {
cancelAndExit(
`Cannot migrate a workspace member independently. 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';
Expand Down