fix: install on partially up-to-date lockfile

This commit is contained in:
Zoltan Kochan
2020-05-24 01:30:31 +03:00
parent 06b8a7aaa2
commit e2c4fdad51
3 changed files with 29 additions and 6 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/resolve-dependencies": patch
---
Don't remove resolved peer dependencies from dependencies when lockfile is partially up-to-date.

View File

@@ -452,16 +452,22 @@ function getInfoFromLockfile (
return null
}
const dependencyLockfile = lockfile.packages?.[depPath]
let dependencyLockfile = lockfile.packages?.[depPath]
if (dependencyLockfile) {
if (dependencyLockfile.peerDependencies && dependencyLockfile.dependencies) {
// This is done to guarantee that the dependency will be relinked with the
// up-to-date peer dependencies
// Covered by test: "peer dependency is grouped with dependency when peer is resolved not from a top dependency"
R.keys(dependencyLockfile.peerDependencies).forEach((peer) => {
delete dependencyLockfile.dependencies![peer]
})
const dependencies: Record<string, string> = {}
for (const [depName, ref] of Object.entries(dependencyLockfile.dependencies ?? {})) {
if (dependencyLockfile.peerDependencies[depName]) continue
dependencies[depName] = ref
}
dependencyLockfile = {
...dependencyLockfile,
dependencies,
}
}
return {

View File

@@ -81,17 +81,29 @@ test('nothing is needlessly removed from node_modules', async (t: tape.Test) =>
})
test('peer dependency is grouped with dependent when the peer is a top dependency', async (t: tape.Test) => {
prepareEmpty(t)
const project = prepareEmpty(t)
const reporter = sinon.spy()
await addDependenciesToPackage({}, ['ajv@4.10.4', 'ajv-keywords@1.5.0'], await testDefaults({ reporter }))
const manifest = await addDependenciesToPackage({}, ['ajv@4.10.4', 'ajv-keywords@1.5.0'], await testDefaults({ reporter }))
t.notOk(reporter.calledWithMatch({
message: `localhost+${REGISTRY_MOCK_PORT}/ajv-keywords/1.5.0 requires a peer of ajv@>=4.10.0 but none was installed.`,
}), 'no warning is logged about unresolved peer dep')
t.ok(await exists(path.resolve(`node_modules/.pnpm/ajv-keywords@1.5.0_ajv@4.10.4/node_modules/ajv-keywords`)), 'dependent is grouped with top peer dep')
await mutateModules([
{
buildIndex: 0,
manifest,
mutation: 'install',
rootDir: process.cwd(),
},
], await testDefaults({ preferFrozenLockfile: false }))
const lockfile = await project.readLockfile()
t.ok(lockfile.packages['/ajv-keywords/1.5.0_ajv@4.10.4'].dependencies['ajv'], 'peer dep is still linked after repeat install')
})
test('the right peer dependency is used in every workspace package', async (t: tape.Test) => {