fix: don't needlessly update subdeps

This commit is contained in:
Zoltan Kochan
2020-05-26 22:15:06 +03:00
parent 768d90a827
commit 71b0cb8fd7
7 changed files with 60 additions and 15 deletions

View File

@@ -0,0 +1,7 @@
---
"supi": patch
---
Subdependencies are not needlessly updated.
Fixes a regression introduced by [cc8a3bd312ea1405a6c79b1d157f0f9ae1be07aa](https://github.com/pnpm/pnpm/commit/cc8a3bd312ea1405a6c79b1d157f0f9ae1be07aa).

View File

@@ -0,0 +1,5 @@
---
"@pnpm/resolve-dependencies": minor
---
A new option added: `forceFullResolution`. When `true`, the whole dependency graph will be walked through during resolution.

View File

@@ -51,6 +51,7 @@ export default async function (
dryRun: boolean,
engineStrict: boolean,
force: boolean,
forceFullResolution: boolean,
hooks: {
readPackage?: ReadPackageHook,
},
@@ -77,6 +78,7 @@ export default async function (
dryRun: opts.dryRun,
engineStrict: opts.engineStrict,
force: opts.force,
forceFullResolution: opts.forceFullResolution,
linkWorkspacePackagesDepth: opts.linkWorkspacePackagesDepth ?? -1,
lockfileDir: opts.lockfileDir,
nodeVersion: opts.nodeVersion,

View File

@@ -121,6 +121,7 @@ export interface ChildrenByParentId {
export interface ResolutionContext {
defaultTag: string,
dryRun: boolean,
forceFullResolution: boolean,
resolvedPackagesByPackageId: ResolvedPackagesByPackageId,
outdatedDependencies: {[pkgId: string]: string},
childrenByParentId: ChildrenByParentId,
@@ -224,7 +225,7 @@ export default async function resolveDependencies (
parentDependsOnPeers: options.parentDependsOnPeers,
preferredDependencies: options.preferredDependencies,
prefix: ctx.prefix,
proceed: options.proceed,
proceed: options.proceed || ctx.forceFullResolution,
registries: ctx.registries,
resolvedDependencies: options.resolvedDependencies,
})
@@ -583,7 +584,7 @@ async function resolveDependency (
if (
!options.parentDependsOnPeer && !pkgResponse.body.updated &&
options.currentDepth === Math.max(0, options.updateDepth) &&
depIsLinked && !ctx.force
depIsLinked && !ctx.force && !options.proceed
) {
return null
}

View File

@@ -583,20 +583,14 @@ async function installInContext (
!R.isEmpty(ctx.wantedLockfile.packages) &&
getPreferredVersionsFromLockfile(ctx.wantedLockfile.packages!) || undefined
)
const updateLockfile = ctx.wantedLockfile.lockfileVersion !== LOCKFILE_VERSION || !opts.currentLockfileIsUpToDate
const defaultUpdateDepth = (() => {
if (opts.force || updateLockfile) return Infinity
if (opts.update) {
return opts.depth
}
return -1
})()
const forceFullResolution = ctx.wantedLockfile.lockfileVersion !== LOCKFILE_VERSION
|| !opts.currentLockfileIsUpToDate
|| opts.force
const _toResolveImporter = toResolveImporter.bind(null, {
defaultUpdateDepth,
defaultUpdateDepth: opts.update ? opts.depth : -1,
lockfileOnly: opts.lockfileOnly,
preferredVersions,
storeDir: ctx.storeDir,
updateLockfile,
virtualStoreDir: ctx.virtualStoreDir,
workspacePackages: opts.workspacePackages,
})
@@ -614,6 +608,7 @@ async function installInContext (
dryRun: opts.lockfileOnly,
engineStrict: opts.engineStrict,
force: opts.force,
forceFullResolution,
hooks: opts.hooks,
linkWorkspacePackagesDepth: opts.linkWorkspacePackagesDepth ?? (opts.saveWorkspaceProtocol ? 0 : -1),
lockfileDir: opts.lockfileDir,
@@ -829,7 +824,6 @@ async function toResolveImporter (
lockfileOnly: boolean,
preferredVersions?: PreferredVersions,
storeDir: string,
updateLockfile: boolean,
virtualStoreDir: string,
workspacePackages: WorkspacePackages,
},
@@ -847,7 +841,7 @@ async function toResolveImporter (
const existingDeps = nonLinkedDependencies
.filter(({ alias }) => !project.wantedDependencies.some((wantedDep) => wantedDep.alias === alias))
let wantedDependencies!: Array<WantedDependency & { isNew?: boolean, updateDepth: number }>
if (!project.manifest || opts.updateLockfile) {
if (!project.manifest) {
wantedDependencies = [
...project.wantedDependencies,
...existingDeps,

View File

@@ -990,7 +990,7 @@ test('all the subdeps of dependencies are linked when a node_modules is partiall
'bar',
'foo',
'foobarqar',
'qar',
'is-positive',
]
)
})

View File

@@ -49,6 +49,42 @@ test('preserve subdeps on update', async (t: tape.Test) => {
})
})
test('preserve subdeps on update when no node_modules is present', async (t: tape.Test) => {
const project = prepareEmpty(t)
await Promise.all([
addDistTag('abc-grand-parent-with-c', '1.0.0', 'latest'),
addDistTag('abc-parent-with-ab', '1.0.0', 'latest'),
addDistTag('bar', '100.0.0', 'latest'),
addDistTag('foo', '100.0.0', 'latest'),
addDistTag('foobarqar', '1.0.0', 'latest'),
addDistTag('peer-c', '1.0.0', 'latest'),
])
const manifest = await addDependenciesToPackage({}, ['foobarqar', 'abc-grand-parent-with-c'], await testDefaults({ lockfileOnly: true }))
await Promise.all([
addDistTag('abc-grand-parent-with-c', '1.0.1', 'latest'),
addDistTag('abc-parent-with-ab', '1.0.1', 'latest'),
addDistTag('bar', '100.1.0', 'latest'),
addDistTag('foo', '100.1.0', 'latest'),
addDistTag('foobarqar', '1.0.1', 'latest'),
])
await install(manifest, await testDefaults({ update: true, depth: 0 }))
const lockfile = await project.readLockfile()
t.ok(lockfile.packages)
t.ok(lockfile.packages['/abc-parent-with-ab/1.0.0_peer-c@1.0.0'], 'preserve version of package that has resolved peer deps')
t.ok(lockfile.packages['/foobarqar/1.0.1'])
t.deepEqual(lockfile.packages['/foobarqar/1.0.1'].dependencies, {
bar: '100.0.0',
foo: '100.0.0',
qar: '100.0.0',
})
})
test('update does not fail when package has only peer dependencies', async (t: tape.Test) => {
prepareEmpty(t)