From 2acf38be3f48ca8429db75fa9d5b37ef82439395 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Mon, 5 Sep 2022 12:38:09 +0300 Subject: [PATCH] fix: auto installing peer dep in a workspace (#5307) * fix: auto installing peer dep in a workspace close #5144 * fix: auto installing peer dep in a workspace * fix: auto installing peer dep in a workspace --- .changeset/twenty-dragons-explode.md | 7 ++++ .../core/test/install/autoInstallPeers.ts | 40 +++++++++++++++++++ packages/resolve-dependencies/src/index.ts | 19 +++++---- 3 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 .changeset/twenty-dragons-explode.md diff --git a/.changeset/twenty-dragons-explode.md b/.changeset/twenty-dragons-explode.md new file mode 100644 index 00000000000..a02eca100dd --- /dev/null +++ b/.changeset/twenty-dragons-explode.md @@ -0,0 +1,7 @@ +--- +"@pnpm/core": patch +"@pnpm/resolve-dependencies": patch +"pnpm": patch +--- + +Auto installing a peer dependency in a workspace that also has it as a dev dependency in another project [#5144](https://github.com/pnpm/pnpm/issues/5144). diff --git a/packages/core/test/install/autoInstallPeers.ts b/packages/core/test/install/autoInstallPeers.ts index a63e16f815b..b740bcecd75 100644 --- a/packages/core/test/install/autoInstallPeers.ts +++ b/packages/core/test/install/autoInstallPeers.ts @@ -1,3 +1,5 @@ +import path from 'path' +import assertProject from '@pnpm/assert-project' import { addDependenciesToPackage, install, mutateModules } from '@pnpm/core' import { prepareEmpty, preparePackages } from '@pnpm/prepare' import { addDistTag, REGISTRY_MOCK_PORT } from '@pnpm/registry-mock' @@ -226,3 +228,41 @@ test('automatically install root peer dependencies', async () => { }) } }) + +test('automatically install peer dependency when it is a dev dependency in another workspace project', async () => { + prepareEmpty() + + await mutateModules([ + { + buildIndex: 0, + manifest: { + name: 'project-1', + devDependencies: { + 'is-positive': '1.0.0', + }, + }, + mutation: 'install', + rootDir: path.resolve('project-1'), + }, + { + buildIndex: 0, + manifest: { + name: 'project-2', + peerDependencies: { + 'is-positive': '1.0.0', + }, + }, + mutation: 'install', + rootDir: path.resolve('project-2'), + }, + ], await testDefaults({ autoInstallPeers: true })) + + const project = assertProject(process.cwd()) + const lockfile = await project.readLockfile() + expect(lockfile.importers['project-1'].devDependencies).toStrictEqual({ + 'is-positive': '1.0.0', + }) + expect(lockfile.importers['project-2'].dependencies).toStrictEqual({ + 'is-positive': '1.0.0', + }) +}) diff --git a/packages/resolve-dependencies/src/index.ts b/packages/resolve-dependencies/src/index.ts index 1f393867c26..8daac805a9a 100644 --- a/packages/resolve-dependencies/src/index.ts +++ b/packages/resolve-dependencies/src/index.ts @@ -135,6 +135,16 @@ export default async function ( } if (updatedManifest != null) { + if (opts.autoInstallPeers) { + if (updatedManifest.peerDependencies) { + const allDeps = getAllDependenciesFromManifest(updatedManifest) + for (const [peerName, peerRange] of Object.entries(updatedManifest.peerDependencies)) { + if (allDeps[peerName]) continue + updatedManifest.dependencies ??= {} + updatedManifest.dependencies[peerName] = peerRange + } + } + } const projectSnapshot = opts.wantedLockfile.importers[project.id] opts.wantedLockfile.importers[project.id] = addDirectDependenciesToLockfile( updatedManifest, @@ -334,14 +344,7 @@ function addDirectDependenciesToLockfile ( return acc }, {}) - let allDepsObj = getAllDependenciesFromManifest(newManifest) - if (autoInstallPeers) { - allDepsObj = { - ...newManifest.peerDependencies, - ...allDepsObj, - } - } - const allDeps = Array.from(new Set(Object.keys(allDepsObj))) + const allDeps = Array.from(new Set(Object.keys(getAllDependenciesFromManifest(newManifest)))) for (const alias of allDeps) { if (directDependenciesByAlias[alias]) {