Skip to content

fix(migrate): resolve husky version from catalog during hooks check#1710

Draft
fengmk2 wants to merge 1 commit into
mainfrom
fix/migrate-husky-catalog-version
Draft

fix(migrate): resolve husky version from catalog during hooks check#1710
fengmk2 wants to merge 1 commit into
mainfrom
fix/migrate-husky-catalog-version

Conversation

@fengmk2
Copy link
Copy Markdown
Member

@fengmk2 fengmk2 commented May 29, 2026

Problem

vp migrate's git-hooks preflight could not determine the husky version when it was pinned via a catalog reference. In a pnpm catalog monorepo such as vite-task:

  • package.json"husky": "catalog:"
  • pnpm-workspace.yamlcatalog: { husky: ^9.1.7 } (a compatible v9)

semver.coerce("catalog:") returns null, and the node_modules fallback is empty during migration, so it warned:

⚠ Could not determine husky version from "catalog:" — please specify a semver-compatible version (e.g., "^9.0.0") and re-run migration.

As a result, pre-commit hooks were never configured and husky/lint-staged were left in devDependencies, even though the catalog declared a perfectly compatible version.

Fix

checkUnsupportedHuskyVersion now resolves a catalog: / catalog:<name> spec from the workspace catalog before falling back to node_modules. A new read-only, package-manager-agnostic helper resolveCatalogSpecFromProject looks the spec up in:

  • pnpm-workspace.yaml
  • .yarnrc.yml
  • package.json catalog / catalogs (including Bun's workspaces form)

reusing the existing createCatalogDependencyResolverFromCatalogs. The genuinely-uncoercible path (e.g. "latest" with no catalog entry) still degrades to the same warning.

Testing

  • Added global snap test migration-husky-catalog-version mirroring the real-world vite-task setup. It captured the bug before the fix; after the fix it shows no warning, husky/lint-staged removed, preparevp config, staged config merged into vite.config.ts, and .vite-hooks/pre-commit created.
  • All existing husky/hook global snap tests re-run with no snapshot drift.
  • migration-husky-latest-dist-tag still warns (degradation path intact).
  • 107 migration unit tests pass; vp check (format/lint/type-check) clean.

Note

Low Risk
Narrow change to migration preflight catalog resolution for husky only; read-only lookups and existing fallbacks for non-catalog specs remain unchanged.

Overview
vp migrate no longer fails the git-hooks preflight when husky is declared as catalog: / catalog:<name> in package.json. The migrator resolves that specifier from workspace catalog sources (pnpm-workspace.yaml, .yarnrc.yml, package.json catalog/catalogs, including Bun workspaces) via a new read-only resolveCatalogSpecFromProject, then runs semver checks on the resolved range before falling back to node_modules or the existing “could not determine version” warning.

A global snap test migration-husky-catalog-version locks in the end-to-end behavior: migrate completes with Git hooks configured, husky/lint-staged removed, preparevp config, staged merged into vite.config.ts, and .vite-hooks/pre-commit calling vp staged.

Reviewed by Cursor Bugbot for commit 82f3a2a. Configure here.

`vp migrate`'s git-hooks preflight could not determine the husky version
when it was pinned via a catalog reference (e.g. `"husky": "catalog:"`
in package.json with the real version in `pnpm-workspace.yaml`'s catalog).
`semver.coerce("catalog:")` returns null and the node_modules fallback is
empty during migration, so it warned:

  Could not determine husky version from "catalog:" — please specify a
  semver-compatible version (e.g., "^9.0.0") and re-run migration.

As a result pre-commit hooks were never configured and husky/lint-staged
were left in devDependencies, even when the catalog declared a compatible
v9.

`checkUnsupportedHuskyVersion` now resolves a `catalog:`/`catalog:<name>`
spec from the workspace catalog (pnpm-workspace.yaml, .yarnrc.yml, or
package.json `catalog`/`catalogs`) before falling back to node_modules.
Adds the `migration-husky-catalog-version` global snap test covering the
real-world setup.
@netlify
Copy link
Copy Markdown

netlify Bot commented May 29, 2026

Deploy Preview for viteplus-preview canceled.

Name Link
🔨 Latest commit 82f3a2a
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/6a199ee77a28770008dc648c

@fengmk2 fengmk2 self-assigned this May 29, 2026
@fengmk2
Copy link
Copy Markdown
Member Author

fengmk2 commented May 29, 2026

@cursor review

@fengmk2 fengmk2 added test: e2e Auto run e2e tests test: create-e2e Run `vp create` e2e tests labels May 29, 2026
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 82f3a2a. Configure here.

);
}
return undefined;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New function duplicates existing catalog resolver logic

Low Severity

resolveCatalogSpecFromProject (~54 lines) duplicates the file-reading and resolution logic already present in createCatalogDependencyResolver (lines 1554–1604). The same pnpm-workspace.yaml, .yarnrc.yml, and package.json handling is repeated nearly verbatim. A simpler implementation could iterate over PackageManager values calling createCatalogDependencyResolver for each, reducing this to ~8 lines and ensuring both code paths stay in sync when catalog resolution logic changes.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 82f3a2a. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test: create-e2e Run `vp create` e2e tests test: e2e Auto run e2e tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant