From d99ec0db08e7f83bcd049436d0e3ac66fc0b9825 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Wed, 9 Mar 2022 21:57:54 +0200 Subject: [PATCH 1/5] feat: strict-peer-dependencies is true by default --- .changeset/lazy-falcons-tap.md | 6 ++++++ packages/config/src/index.ts | 2 +- packages/core/src/install/extendInstallOptions.ts | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 .changeset/lazy-falcons-tap.md diff --git a/.changeset/lazy-falcons-tap.md b/.changeset/lazy-falcons-tap.md new file mode 100644 index 00000000000..2cc534d1cc4 --- /dev/null +++ b/.changeset/lazy-falcons-tap.md @@ -0,0 +1,6 @@ +--- +"@pnpm/config": major +"@pnpm/core": major +--- + +`strict-peer-dependencies` is `true` by default. diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 96255ddad2d..6e303113f36 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -208,7 +208,7 @@ export default async ( shrinkwrap: npmDefaults.shrinkwrap, reverse: false, sort: true, - 'strict-peer-dependencies': false, + 'strict-peer-dependencies': true, 'unsafe-perm': npmDefaults['unsafe-perm'], 'use-beta-cli': false, userconfig: npmDefaults.userconfig, diff --git a/packages/core/src/install/extendInstallOptions.ts b/packages/core/src/install/extendInstallOptions.ts index fd6cb53c318..f778ba27eba 100644 --- a/packages/core/src/install/extendInstallOptions.ts +++ b/packages/core/src/install/extendInstallOptions.ts @@ -154,7 +154,7 @@ const defaults = async (opts: InstallOptions) => { symlink: true, storeController: opts.storeController, storeDir: opts.storeDir, - strictPeerDependencies: false, + strictPeerDependencies: true, tag: 'latest', unsafePerm: process.platform === 'win32' || process.platform === 'cygwin' || From 1995b2fb9a476a5380d4f26ea8da9362504eda96 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Wed, 9 Mar 2022 22:12:34 +0200 Subject: [PATCH 2/5] test: fix --- packages/plugin-commands-installation/src/installDeps.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/plugin-commands-installation/src/installDeps.ts b/packages/plugin-commands-installation/src/installDeps.ts index 9ef7168c8f7..b750d2101b1 100644 --- a/packages/plugin-commands-installation/src/installDeps.ts +++ b/packages/plugin-commands-installation/src/installDeps.ts @@ -233,7 +233,10 @@ when running add/update with the --workspace option') rootDir: opts.dir, targetDependenciesField: getSaveType(opts), } - let [updatedImporter] = await mutateModules([mutatedProject], installOpts) + let [updatedImporter] = await mutateModules([mutatedProject], { + ...installOpts, + strictPeerDependencies: opts.autoInstallPeers ? false : installOpts.strictPeerDependencies, + }) if (opts.save !== false) { if (opts.autoInstallPeers && !isEmpty(updatedImporter.peerDependencyIssues?.intersections ?? {})) { logger.info({ From b862145f39ac5b0455e2e98189118860c40a31d0 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Wed, 9 Mar 2022 23:28:47 +0200 Subject: [PATCH 3/5] test: fix --- packages/plugin-commands-installation/src/remove.ts | 1 + packages/pnpm/test/hooks.ts | 4 ++-- packages/pnpm/test/install/hooks.ts | 4 ++-- packages/pnpm/test/monorepo/index.ts | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/plugin-commands-installation/src/remove.ts b/packages/plugin-commands-installation/src/remove.ts index f1db16bbea5..c39a18ea51e 100644 --- a/packages/plugin-commands-installation/src/remove.ts +++ b/packages/plugin-commands-installation/src/remove.ts @@ -65,6 +65,7 @@ export function rcOptionsTypes () { 'shared-workspace-lockfile', 'store', 'store-dir', + 'strict-peer-dependencies', 'virtual-store-dir', ], allTypes) } diff --git a/packages/pnpm/test/hooks.ts b/packages/pnpm/test/hooks.ts index 373e1de49f7..e8843bb2c87 100644 --- a/packages/pnpm/test/hooks.ts +++ b/packages/pnpm/test/hooks.ts @@ -92,10 +92,10 @@ test('filterLog hook filters peer dependency warning', async () => { } ` await fs.writeFile('.pnpmfile.cjs', pnpmfile, 'utf8') - const result = execPnpmSync(['add', '@rollup/pluginutils@3.1.0']) + const result = execPnpmSync(['add', '@rollup/pluginutils@3.1.0', '--no-strict-peer-dependencies']) expect(result.status).toBe(0) expect(result.stdout.toString()).toEqual( expect.not.stringContaining('requires a peer of rollup') ) -}) \ No newline at end of file +}) diff --git a/packages/pnpm/test/install/hooks.ts b/packages/pnpm/test/install/hooks.ts index 77b4e03897a..98bbc9385c1 100644 --- a/packages/pnpm/test/install/hooks.ts +++ b/packages/pnpm/test/install/hooks.ts @@ -607,8 +607,8 @@ test('readPackage hook is used during removal inside a workspace', async () => { `, 'utf8') process.chdir('project') - await execPnpm(['install']) - await execPnpm(['uninstall', 'is-positive']) + await execPnpm(['install', '--no-strict-peer-dependencies']) + await execPnpm(['uninstall', 'is-positive', '--no-strict-peer-dependencies']) process.chdir('..') const lockfile = await readYamlFile('pnpm-lock.yaml') diff --git a/packages/pnpm/test/monorepo/index.ts b/packages/pnpm/test/monorepo/index.ts index ad3fe83769e..baefda99721 100644 --- a/packages/pnpm/test/monorepo/index.ts +++ b/packages/pnpm/test/monorepo/index.ts @@ -1189,7 +1189,7 @@ test('peer dependency is grouped with dependent when the peer is a top dependenc }) } - await execPnpm(['uninstall', 'ajv']) + await execPnpm(['uninstall', 'ajv', '--no-strict-peer-dependencies']) { const lockfile = await readYamlFile(path.resolve('..', WANTED_LOCKFILE)) From 375dd5ff0abe7ac3ca39aa9ae6b1f421c7a48b25 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Thu, 10 Mar 2022 00:35:05 +0200 Subject: [PATCH 4/5] test: fix --- packages/core/test/install/misc.ts | 4 +- .../core/test/install/peerDependencies.ts | 46 ++++++++++--------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/packages/core/test/install/misc.ts b/packages/core/test/install/misc.ts index 05cbbfcf628..2beb51b2173 100644 --- a/packages/core/test/install/misc.ts +++ b/packages/core/test/install/misc.ts @@ -1177,7 +1177,7 @@ test('memory consumption is under control on huge package with many peer depende version: '0.0.0', }, ['@teambit/bit@0.0.30'], - await testDefaults({ fastUnpack: true, lockfileOnly: true }) + await testDefaults({ fastUnpack: true, lockfileOnly: true, strictPeerDependencies: false }) ) expect(await exists('pnpm-lock.yaml')).toBeTruthy() @@ -1193,7 +1193,7 @@ test('memory consumption is under control on huge package with many peer depende version: '0.0.0', }, ['@teambit/react@0.0.30'], - await testDefaults({ fastUnpack: true, lockfileOnly: true }) + await testDefaults({ fastUnpack: true, lockfileOnly: true, strictPeerDependencies: false }) ) expect(await exists('pnpm-lock.yaml')).toBeTruthy() diff --git a/packages/core/test/install/peerDependencies.ts b/packages/core/test/install/peerDependencies.ts index 4298c8ffefc..c09e51142ea 100644 --- a/packages/core/test/install/peerDependencies.ts +++ b/packages/core/test/install/peerDependencies.ts @@ -56,6 +56,7 @@ test('nothing is needlessly removed from node_modules', async () => { prepareEmpty() const opts = await testDefaults({ modulesCacheMaxAge: 0, + strictPeerDependencies: false, }) const manifest = await addDependenciesToPackage({}, ['using-ajv', 'ajv-keywords@1.5.0'], opts) @@ -143,7 +144,7 @@ test('the right peer dependency is used in every workspace package', async () => rootDir: path.resolve('project-2'), }, ] - await mutateModules(importers, await testDefaults({ lockfileOnly: true })) + await mutateModules(importers, await testDefaults({ lockfileOnly: true, strictPeerDependencies: false })) const lockfile = await readYamlFile(path.resolve(WANTED_LOCKFILE)) @@ -161,7 +162,7 @@ test('warning is reported when cannot resolve peer dependency for top-level depe const reporter = jest.fn() - await addDependenciesToPackage({}, ['ajv-keywords@1.5.0'], await testDefaults({ reporter })) + await addDependenciesToPackage({}, ['ajv-keywords@1.5.0'], await testDefaults({ reporter, strictPeerDependencies: false })) expect(reporter).toHaveBeenCalledWith( expect.objectContaining({ @@ -315,7 +316,7 @@ test('warning is reported when cannot resolve peer dependency for non-top-level const reporter = jest.fn() - await addDependenciesToPackage({}, ['abc-grand-parent-without-c'], await testDefaults({ reporter })) + await addDependenciesToPackage({}, ['abc-grand-parent-without-c'], await testDefaults({ reporter, strictPeerDependencies: false })) expect(reporter).toHaveBeenCalledWith( expect.objectContaining({ @@ -360,7 +361,7 @@ test('warning is reported when bad version of resolved peer dependency for non-t const reporter = jest.fn() - await addDependenciesToPackage({}, ['abc-grand-parent-without-c', 'peer-c@2'], await testDefaults({ reporter })) + await addDependenciesToPackage({}, ['abc-grand-parent-without-c', 'peer-c@2'], await testDefaults({ reporter, strictPeerDependencies: false })) expect(reporter).toHaveBeenCalledWith( expect.objectContaining({ @@ -457,9 +458,9 @@ test('top peer dependency is linked on subsequent install', async () => { test('top peer dependency is linked on subsequent install, through transitive peer', async () => { prepareEmpty() - const manifest = await addDependenciesToPackage({}, ['abc-grand-parent@1.0.0'], await testDefaults()) + const manifest = await addDependenciesToPackage({}, ['abc-grand-parent@1.0.0'], await testDefaults({ strictPeerDependencies: false })) - await addDependenciesToPackage(manifest, ['peer-c@1.0.0'], await testDefaults()) + await addDependenciesToPackage(manifest, ['peer-c@1.0.0'], await testDefaults({ strictPeerDependencies: false })) expect(await exists(path.resolve('node_modules/.pnpm/abc-grand-parent@1.0.0_peer-c@1.0.0/node_modules/abc-grand-parent'))).toBeTruthy() }) @@ -498,9 +499,9 @@ test('the list of transitive peer dependencies is kept up to date', async () => test('top peer dependency is linked on subsequent install. Reverse order', async () => { prepareEmpty() - const manifest = await addDependenciesToPackage({}, ['abc-parent-with-ab@1.0.0'], await testDefaults()) + const manifest = await addDependenciesToPackage({}, ['abc-parent-with-ab@1.0.0'], await testDefaults({ strictPeerDependencies: false })) - await addDependenciesToPackage(manifest, ['peer-c@1.0.0'], await testDefaults({ modulesCacheMaxAge: 0 })) + await addDependenciesToPackage(manifest, ['peer-c@1.0.0'], await testDefaults({ modulesCacheMaxAge: 0, strictPeerDependencies: false })) expect(await exists(path.resolve('node_modules/.pnpm/abc-parent-with-ab@1.0.0/node_modules/abc-parent-with-ab'))).toBeFalsy() expect(await exists(path.resolve('node_modules/.pnpm/abc-parent-with-ab@1.0.0_peer-c@1.0.0/node_modules/abc-parent-with-ab'))).toBeTruthy() @@ -519,7 +520,7 @@ test('peer dependencies are linked when running one named installation', async ( prepareEmpty() - const manifest = await addDependenciesToPackage({}, ['abc-grand-parent-with-c', 'abc-parent-with-ab', 'peer-c@2.0.0'], await testDefaults()) + const manifest = await addDependenciesToPackage({}, ['abc-grand-parent-with-c', 'abc-parent-with-ab', 'peer-c@2.0.0'], await testDefaults({ strictPeerDependencies: false })) const pkgVariationsDir = path.resolve('node_modules/.pnpm/abc@1.0.0') @@ -542,7 +543,7 @@ test('peer dependencies are linked when running one named installation', async ( // this part was failing. See issue: https://github.com/pnpm/pnpm/issues/1201 await addDistTag({ package: 'peer-a', version: '1.0.1', distTag: 'latest' }) - await install(manifest, await testDefaults({ update: true, depth: 100 })) + await install(manifest, await testDefaults({ update: true, depth: 100, strictPeerDependencies: false })) }) test('peer dependencies are linked when running two separate named installations', async () => { @@ -550,8 +551,8 @@ test('peer dependencies are linked when running two separate named installations await addDistTag({ package: 'peer-c', version: '1.0.0', distTag: 'latest' }) prepareEmpty() - const manifest = await addDependenciesToPackage({}, ['abc-grand-parent-with-c', 'peer-c@2.0.0'], await testDefaults()) - await addDependenciesToPackage(manifest, ['abc-parent-with-ab'], await testDefaults()) + const manifest = await addDependenciesToPackage({}, ['abc-grand-parent-with-c', 'peer-c@2.0.0'], await testDefaults({ strictPeerDependencies: false })) + await addDependenciesToPackage(manifest, ['abc-parent-with-ab'], await testDefaults({ strictPeerDependencies: false })) const pkgVariationsDir = path.resolve('node_modules/.pnpm/abc@1.0.0') @@ -685,7 +686,7 @@ test('peer dependency is grouped with dependent when the peer is a top dependenc const reporter = sinon.spy() - await addDependenciesToPackage({}, ['ajv@4.10.4', 'ajv-keywords@1.5.0'], await testDefaults({ reporter, lockfileDir: path.resolve('..') })) + await addDependenciesToPackage({}, ['ajv@4.10.4', 'ajv-keywords@1.5.0'], await testDefaults({ reporter, lockfileDir: path.resolve('..'), strictPeerDependencies: false })) expect(reporter.calledWithMatch({ message: `localhost+${REGISTRY_MOCK_PORT}/ajv-keywords@1.5.0 requires a peer of ajv@>=4.10.0 but none was installed.`, @@ -718,8 +719,8 @@ test('peer dependency is grouped correctly with peer installed via separate inst dependencies: { abc: '1.0.0', }, - }, await testDefaults({ reporter, lockfileDir })) - await addDependenciesToPackage(manifest, ['peer-c@2.0.0'], await testDefaults({ reporter, lockfileDir })) + }, await testDefaults({ reporter, lockfileDir, strictPeerDependencies: false })) + await addDependenciesToPackage(manifest, ['peer-c@2.0.0'], await testDefaults({ reporter, lockfileDir, strictPeerDependencies: false })) expect(await exists(path.join('../node_modules/.pnpm/abc@1.0.0_peer-c@2.0.0/node_modules/dep-of-pkg-with-1-dep'))).toBeTruthy() }) @@ -730,7 +731,7 @@ test('peer dependency is grouped with dependent when the peer is a top dependenc process.chdir('_') const lockfileDir = path.resolve('..') - let manifest = await addDependenciesToPackage({}, ['ajv@4.10.4', 'ajv-keywords@1.5.0'], await testDefaults({ lockfileDir })) + let manifest = await addDependenciesToPackage({}, ['ajv@4.10.4', 'ajv-keywords@1.5.0'], await testDefaults({ lockfileDir, strictPeerDependencies: false })) { const lockfile = await readYamlFile(path.resolve('..', WANTED_LOCKFILE)) @@ -746,7 +747,7 @@ test('peer dependency is grouped with dependent when the peer is a top dependenc }) } - manifest = await install(manifest, await testDefaults({ lockfileDir })) + manifest = await install(manifest, await testDefaults({ lockfileDir, strictPeerDependencies: false })) { const lockfile = await readYamlFile(path.resolve('..', WANTED_LOCKFILE)) @@ -774,6 +775,7 @@ test('peer dependency is grouped with dependent when the peer is a top dependenc ], await testDefaults({ lockfileDir, + strictPeerDependencies: false, }) ) @@ -835,7 +837,7 @@ test('external lockfile: peer dependency is grouped with dependent even after a process.chdir('_') const lockfileDir = path.resolve('..') - const manifest = await addDependenciesToPackage({}, ['peer-c@1.0.0', 'abc-parent-with-ab@1.0.0'], await testDefaults({ lockfileDir })) + const manifest = await addDependenciesToPackage({}, ['peer-c@1.0.0', 'abc-parent-with-ab@1.0.0'], await testDefaults({ lockfileDir, strictPeerDependencies: false })) { const lockfile = await readYamlFile(path.resolve('..', WANTED_LOCKFILE)) @@ -851,7 +853,7 @@ test('external lockfile: peer dependency is grouped with dependent even after a }) } - await addDependenciesToPackage(manifest, ['peer-c@2.0.0'], await testDefaults({ lockfileDir })) + await addDependenciesToPackage(manifest, ['peer-c@2.0.0'], await testDefaults({ lockfileDir, strictPeerDependencies: false })) { const lockfile = await readYamlFile(path.resolve('..', WANTED_LOCKFILE)) @@ -1004,7 +1006,7 @@ test('warning is not reported when cannot resolve optional peer dependency', asy const reporter = jest.fn() - await addDependenciesToPackage({}, ['abc-optional-peers@1.0.0', 'peer-c@2.0.0'], await testDefaults({ reporter })) + await addDependenciesToPackage({}, ['abc-optional-peers@1.0.0', 'peer-c@2.0.0'], await testDefaults({ reporter, strictPeerDependencies: false })) expect(reporter).toHaveBeenCalledWith( expect.objectContaining({ @@ -1076,7 +1078,7 @@ test('warning is not reported when cannot resolve optional peer dependency (spec const reporter = jest.fn() - await addDependenciesToPackage({}, ['abc-optional-peers-meta-only@1.0.0', 'peer-c@2.0.0'], await testDefaults({ reporter })) + await addDependenciesToPackage({}, ['abc-optional-peers-meta-only@1.0.0', 'peer-c@2.0.0'], await testDefaults({ reporter, strictPeerDependencies: false })) expect(reporter).toHaveBeenCalledWith( expect.objectContaining({ @@ -1187,7 +1189,7 @@ test('peer dependency that is resolved by a dev dependency', async () => { mutation: 'install', rootDir: process.cwd(), }, - ], await testDefaults({ fastUnpack: false, lockfileOnly: true })) + ], await testDefaults({ fastUnpack: false, lockfileOnly: true, strictPeerDependencies: false })) const lockfile = await project.readLockfile() expect(lockfile.packages['/@types/mongoose/5.7.32'].dev).toBeTruthy() From 86f3b6b97c507a9123b4603e7f924578b4c16372 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Thu, 10 Mar 2022 01:14:46 +0200 Subject: [PATCH 5/5] test: fix --- packages/core/test/install/multipleImporters.ts | 2 +- packages/core/test/lockfile.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/test/install/multipleImporters.ts b/packages/core/test/install/multipleImporters.ts index 22add662637..913c16b8844 100644 --- a/packages/core/test/install/multipleImporters.ts +++ b/packages/core/test/install/multipleImporters.ts @@ -1150,7 +1150,7 @@ test('resolve a subdependency from the workspace and use it as a peer', async () }, }, } - await mutateModules(importers, await testDefaults({ linkWorkspacePackagesDepth: Infinity, workspacePackages })) + await mutateModules(importers, await testDefaults({ linkWorkspacePackagesDepth: Infinity, strictPeerDependencies: false, workspacePackages })) const project = assertProject(process.cwd()) diff --git a/packages/core/test/lockfile.ts b/packages/core/test/lockfile.ts index 49092a4bf5c..7ebe7d9be0a 100644 --- a/packages/core/test/lockfile.ts +++ b/packages/core/test/lockfile.ts @@ -119,10 +119,10 @@ test("lockfile doesn't lock subdependencies that don't satisfy the new specs", a const project = prepareEmpty() // dependends on react-onclickoutside@5.9.0 - const manifest = await addDependenciesToPackage({}, ['react-datetime@2.8.8'], await testDefaults({ fastUnpack: false, save: true })) + const manifest = await addDependenciesToPackage({}, ['react-datetime@2.8.8'], await testDefaults({ fastUnpack: false, save: true, strictPeerDependencies: false })) // dependends on react-onclickoutside@0.3.4 - await addDependenciesToPackage(manifest, ['react-datetime@1.3.0'], await testDefaults({ save: true })) + await addDependenciesToPackage(manifest, ['react-datetime@1.3.0'], await testDefaults({ save: true, strictPeerDependencies: false })) expect( project.requireModule('.pnpm/react-datetime@1.3.0/node_modules/react-onclickoutside/package.json').version