Improve resolution of catalog dependencies#168
Conversation
…endencies of included packages within the same monorepo
PR SummaryMedium Risk Overview Adds comprehensive Vitest coverage for default and named catalogs, missing entries, YAML parse failures, and fallback/unchanged behaviors. Written by Cursor Bugbot for commit 79a12a9. This will update automatically on new commits. Configure here. |
There was a problem hiding this comment.
Pull request overview
Improves catalog dependency resolution in manifest processing by loading pnpm-style catalogs from pnpm-workspace.yaml (when present) before falling back to Bun-style catalogs in package.json, preventing failures when isolating projects inside pnpm workspaces.
Changes:
- Added
loadCatalogSource()helper to read catalogs frompnpm-workspace.yamlfirst, then fall back topackage.json. - Updated
resolveCatalogDependencies()to use the new catalog source loader. - Added a comprehensive Vitest suite for catalog resolution behavior across pnpm and Bun formats.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/lib/manifest/helpers/resolve-catalog-dependencies.ts | Adds YAML-based catalog loading from pnpm-workspace.yaml with fallback to package.json. |
| src/lib/manifest/helpers/resolve-catalog-dependencies.test.ts | Introduces tests covering pnpm-workspace and package.json catalog resolution scenarios. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@royalty37 I'm curious, why would you want to use forceNpm if you're using a PNPM workspace? Are you deploying to a target that does not support PNPM? With the forceNpm you're loosing locked versions since it's not a perfect translation... |
|
@royalty37 In any case I think the PR seems fine. If you format the code so it passes checks I'll merge it |
|
@0x80 Sorry for delay. Have fixed the formatting issue. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| describe("resolveCatalogDependencies", () => { | ||
| let tmpDir: string; | ||
|
|
||
| afterEach(async () => { | ||
| if (tmpDir) { | ||
| await fs.remove(tmpDir); | ||
| } | ||
| }); |
There was a problem hiding this comment.
Mocks (mockLogger.debug/mockLogger.warn) aren’t reset between tests, so assertions like toHaveBeenCalledWith can become order-dependent as more cases are added. Add a beforeEach that calls vi.clearAllMocks() (or at least resets the logger mocks) to keep each test independent.
| catalogSourceCache.set(workspaceRootDir, loadPromise); | ||
| return loadPromise; |
There was a problem hiding this comment.
catalogSourceCache stores the in-flight loadPromise, but if reading/parsing ends up throwing (e.g., missing/invalid root package.json or other transient FS error), the rejected promise will stay cached and all subsequent calls for the same workspaceRootDir will immediately rethrow without retry. Consider deleting the cache entry on rejection (or only caching on success) so a later call can recover if the underlying files become readable.
| catalogSourceCache.set(workspaceRootDir, loadPromise); | |
| return loadPromise; | |
| const cachedLoadPromise = loadPromise.catch((error) => { | |
| catalogSourceCache.delete(workspaceRootDir); | |
| throw error; | |
| }); | |
| catalogSourceCache.set(workspaceRootDir, cachedLoadPromise); | |
| return cachedLoadPromise; |
| lodash: "^4.0.0", | ||
| }); | ||
| }); | ||
|
|
There was a problem hiding this comment.
The test suite covers YAML-only and package.json-only scenarios, but it doesn’t currently assert the documented precedence when both pnpm-workspace.yaml and package.json define catalogs. Add a test where both files exist with different versions for the same dependency and verify the YAML value wins (since loadCatalogSource checks YAML first).
| it("prefers pnpm-workspace.yaml over package.json when both define the same catalog dependency", async () => { | |
| tmpDir = await createTempWorkspace({ | |
| workspaceYaml: { | |
| packages: ["packages/*"], | |
| catalog: { | |
| react: "^18.3.1", | |
| }, | |
| }, | |
| packageJson: { | |
| name: "root", | |
| version: "0.0.0", | |
| pnpm: { | |
| catalog: { | |
| react: "^18.2.0", | |
| }, | |
| }, | |
| }, | |
| }); | |
| const result = await resolveCatalogDependencies( | |
| { react: "catalog:" }, | |
| tmpDir, | |
| ); | |
| expect(result).toEqual({ react: "^18.3.1" }); | |
| }); |
|
@cursor review |
Bugbot couldn't runBugbot is not enabled for your user on this team. Ask your team administrator to increase your team's hard limit for Bugbot seats or add you to the allowlist in the Cursor dashboard. |
|
@cursor review |
Bugbot couldn't runBugbot is not enabled for your user on this team. Ask your team administrator to increase your team's hard limit for Bugbot seats or add you to the allowlist in the Cursor dashboard. |
|
@cursor review |
Bugbot couldn't runBugbot is not enabled for your user on this team. Ask your team administrator to increase your team's hard limit for Bugbot seats or add you to the allowlist in the Cursor dashboard. |
|
@royalty37 please also address the issues that copilot found |
When using the forceNpm flag with a project inside a pnpm workspace, catalog dependencies were not being resolved for dependencies of packages within my monorepo causing lockfile generation to fail.
Update to read catalogs from 'pnpm-workspace.yaml'.
Refactored
resolveCatalogDependenciesto extract catalog loading into a newloadCatalogSourcehelper that:pnpm-workspace.yamlfirst — readscatalog/catalogsfields if thefile exists and contains them
package.json— readscatalog/catalogsfrom root orworkspaces.catalog(Bun format)