diff --git a/.changeset/friendly-taxis-shave.md b/.changeset/friendly-taxis-shave.md new file mode 100644 index 0000000000..fc6c7c53cb --- /dev/null +++ b/.changeset/friendly-taxis-shave.md @@ -0,0 +1,5 @@ +--- +"@pnpm/resolve-dependencies": patch +--- + +The workspace protocol should work in subdependencies. diff --git a/packages/resolve-dependencies/src/resolveDependencies.ts b/packages/resolve-dependencies/src/resolveDependencies.ts index b71bab0712..3f23a34e2b 100644 --- a/packages/resolve-dependencies/src/resolveDependencies.ts +++ b/packages/resolve-dependencies/src/resolveDependencies.ts @@ -117,7 +117,6 @@ export interface ChildrenByParentDepPath { } export interface ResolutionContext { - alwaysTryWorkspacePackages?: boolean defaultTag: string dryRun: boolean forceFullResolution: boolean @@ -351,8 +350,6 @@ async function resolveChildren ( ).length ) const wantedDependencies = getNonDevWantedDependencies(parentPkg.pkg) - workspacePackages = workspacePackages && ctx.linkWorkspacePackagesDepth > parentDepth - ? workspacePackages : undefined const children = await resolveDependencies(ctx, preferredVersions, wantedDependencies, { currentDepth: parentDepth + 1, @@ -589,7 +586,7 @@ async function resolveDependency ( let pkgResponse!: PackageResponse try { pkgResponse = await ctx.storeController.requestPackage(wantedDependency, { - alwaysTryWorkspacePackages: ctx.alwaysTryWorkspacePackages, + alwaysTryWorkspacePackages: ctx.linkWorkspacePackagesDepth >= options.currentDepth, currentPackageId: currentPkg.pkgId, currentResolution: currentPkg.resolution, defaultTag: ctx.defaultTag, diff --git a/packages/resolve-dependencies/src/resolveDependencyTree.ts b/packages/resolve-dependencies/src/resolveDependencyTree.ts index 163fec2f24..4354803136 100644 --- a/packages/resolve-dependencies/src/resolveDependencyTree.ts +++ b/packages/resolve-dependencies/src/resolveDependencyTree.ts @@ -75,7 +75,6 @@ export default async function ( const wantedToBeSkippedPackageIds = new Set() const ctx = { - alwaysTryWorkspacePackages: (opts.linkWorkspacePackagesDepth ?? -1) >= 0, childrenByParentDepPath: {} as ChildrenByParentDepPath, currentLockfile: opts.currentLockfile, defaultTag: opts.tag, diff --git a/packages/supi/test/install/multipleImporters.ts b/packages/supi/test/install/multipleImporters.ts index 1a9e4285a6..eec8beea88 100644 --- a/packages/supi/test/install/multipleImporters.ts +++ b/packages/supi/test/install/multipleImporters.ts @@ -975,6 +975,7 @@ test('remove dependencies of a project that was removed from the workspace (duri }) test('do not resolve a subdependency from the workspace by default', async () => { + await addDistTag('dep-of-pkg-with-1-dep', '100.1.0', 'latest') preparePackages([ { location: 'project', @@ -1162,3 +1163,76 @@ test('resolve a subdependency from the workspace and use it as a peer', async () expect(wantedLockfile.packages['/abc-parent-with-ab/1.0.0'].dependencies?.['peer-a']).toBe('link:peer-a') expect(wantedLockfile.packages['/abc/1.0.0_peer-a@1.0.1+peer-b@1.0.0'].dependencies?.['peer-a']).toBe('link:peer-a') }) + +test('resolve a subdependency from the workspace, when it uses the workspace protocol', async () => { + preparePackages([ + { + location: '.', + package: { + pnpm: { + overrides: { + 'dep-of-pkg-with-1-dep': 'workspace:*', + }, + }, + }, + }, + { + location: 'project', + package: { name: 'project' }, + }, + { + location: 'dep-of-pkg-with-1-dep', + package: { name: 'dep-of-pkg-with-1-dep' }, + }, + ]) + + const importers: MutatedProject[] = [ + { + buildIndex: 0, + manifest: { + name: 'project', + version: '1.0.0', + + dependencies: { + 'pkg-with-1-dep': '100.0.0', + }, + }, + mutation: 'install', + rootDir: path.resolve('project'), + }, + { + buildIndex: 0, + manifest: { + name: 'dep-of-pkg-with-1-dep', + version: '100.1.0', + }, + mutation: 'install', + rootDir: path.resolve('dep-of-pkg-with-1-dep'), + }, + ] + const workspacePackages = { + 'dep-of-pkg-with-1-dep': { + '100.1.0': { + dir: path.resolve('dep-of-pkg-with-1-dep'), + manifest: { + name: 'dep-of-pkg-with-1-dep', + version: '100.1.0', + }, + }, + }, + } + await mutateModules(importers, await testDefaults({ linkWorkspacePackagesDepth: -1, workspacePackages })) + + const project = assertProject(process.cwd()) + + const wantedLockfile = await project.readLockfile() + expect(wantedLockfile.packages['/pkg-with-1-dep/100.0.0'].dependencies?.['dep-of-pkg-with-1-dep']).toBe('link:dep-of-pkg-with-1-dep') + + await rimraf('node_modules') + + // Testing that headless installation does not fail with links in subdeps + await mutateModules(importers, await testDefaults({ + frozenLockfile: true, + workspacePackages, + })) +})