mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-28 02:53:15 -04:00
5
.changeset/tender-phones-hunt.md
Normal file
5
.changeset/tender-phones-hunt.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/resolve-dependencies": patch
|
||||
---
|
||||
|
||||
Dedupe dependencies when one of the packages is updated or a new one is added.
|
||||
@@ -116,6 +116,7 @@ export interface ChildrenByParentDepPath {
|
||||
}
|
||||
|
||||
export interface ResolutionContext {
|
||||
updatedSet: Set<string>
|
||||
defaultTag: string
|
||||
dryRun: boolean
|
||||
forceFullResolution: boolean
|
||||
@@ -241,8 +242,11 @@ export default async function resolveDependencies (
|
||||
.filter(Boolean) as PkgAddress[]
|
||||
|
||||
const newPreferredVersions = { ...preferredVersions }
|
||||
for (const { depPath } of pkgAddresses) {
|
||||
const resolvedPackage = ctx.resolvedPackagesByDepPath[depPath]
|
||||
for (const pkgAddress of pkgAddresses) {
|
||||
if (pkgAddress.updated) {
|
||||
ctx.updatedSet.add(pkgAddress.alias)
|
||||
}
|
||||
const resolvedPackage = ctx.resolvedPackagesByDepPath[pkgAddress.depPath]
|
||||
if (!resolvedPackage) continue // This will happen only with linked dependencies
|
||||
if (!newPreferredVersions[resolvedPackage.name]) {
|
||||
newPreferredVersions[resolvedPackage.name] = {}
|
||||
@@ -271,11 +275,11 @@ async function resolveDependenciesOfDependency (
|
||||
? extendedWantedDep.wantedDependency.updateDepth
|
||||
: options.updateDepth
|
||||
const updateShouldContinue = options.currentDepth <= updateDepth
|
||||
const update = (
|
||||
const update = ((extendedWantedDep.infoFromLockfile?.dependencyLockfile) == null) ||
|
||||
(
|
||||
updateShouldContinue && (
|
||||
(ctx.updateMatching == null) ||
|
||||
((extendedWantedDep.infoFromLockfile?.dependencyLockfile) == null) ||
|
||||
ctx.updateMatching(extendedWantedDep.infoFromLockfile.dependencyLockfile.name ?? extendedWantedDep.wantedDependency.alias)
|
||||
ctx.updateMatching(extendedWantedDep.infoFromLockfile.name!)
|
||||
)
|
||||
) || Boolean(
|
||||
(options.workspacePackages != null) &&
|
||||
@@ -284,14 +288,15 @@ async function resolveDependenciesOfDependency (
|
||||
extendedWantedDep.wantedDependency,
|
||||
{ defaultTag: ctx.defaultTag, registry: ctx.registries.default }
|
||||
)
|
||||
)
|
||||
) || ctx.updatedSet.has(extendedWantedDep.infoFromLockfile.name!)
|
||||
|
||||
const resolveDependencyOpts: ResolveDependencyOptions = {
|
||||
currentDepth: options.currentDepth,
|
||||
parentPkg: options.parentPkg,
|
||||
preferredVersions,
|
||||
workspacePackages: options.workspacePackages,
|
||||
currentPkg: extendedWantedDep.infoFromLockfile ?? undefined,
|
||||
proceed: extendedWantedDep.proceed || updateShouldContinue,
|
||||
proceed: extendedWantedDep.proceed || updateShouldContinue || ctx.updatedSet.size > 0,
|
||||
update,
|
||||
updateDepth,
|
||||
}
|
||||
@@ -478,14 +483,19 @@ function referenceSatisfiesWantedSpec (
|
||||
return semver.satisfies(version, wantedDep.pref, true)
|
||||
}
|
||||
|
||||
interface InfoFromLockfile {
|
||||
dependencyLockfile?: PackageSnapshot
|
||||
type InfoFromLockfile = {
|
||||
depPath: string
|
||||
pkgId: string
|
||||
dependencyLockfile?: PackageSnapshot
|
||||
name?: string
|
||||
version?: string
|
||||
pkgId: string
|
||||
resolution?: Resolution
|
||||
}
|
||||
} & ({
|
||||
dependencyLockfile: PackageSnapshot
|
||||
name: string
|
||||
version: string
|
||||
resolution: Resolution
|
||||
} | {})
|
||||
|
||||
function getInfoFromLockfile (
|
||||
lockfile: Lockfile,
|
||||
|
||||
@@ -109,6 +109,7 @@ export default async function<T> (
|
||||
const linkedDependencies = [] as LinkedDependency[]
|
||||
const resolveCtx = {
|
||||
...ctx,
|
||||
updatedSet: new Set<string>(),
|
||||
linkedDependencies,
|
||||
modulesDir: importer.modulesDir,
|
||||
prefix: importer.rootDir,
|
||||
|
||||
@@ -177,3 +177,19 @@ test('prefer version of package that also satisfies the range of the same packag
|
||||
]
|
||||
)
|
||||
})
|
||||
|
||||
test('dedupe subdependency when a newer version of the same package is installed', async () => {
|
||||
const project = prepareEmpty()
|
||||
|
||||
await addDistTag({ package: 'dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
|
||||
|
||||
const manifest = await addDependenciesToPackage({}, ['dep-of-pkg-with-1-dep@100.0.0', 'pkg-with-1-dep@100.0.0'], await testDefaults())
|
||||
|
||||
await addDistTag({ package: 'dep-of-pkg-with-1-dep', version: '100.1.0', distTag: 'latest' })
|
||||
|
||||
await addDependenciesToPackage(manifest, ['dep-of-pkg-with-1-dep@100.1.0'], await testDefaults())
|
||||
|
||||
const lockfile = await project.readLockfile()
|
||||
expect(lockfile.packages).toHaveProperty(['/dep-of-pkg-with-1-dep/100.1.0'])
|
||||
expect(lockfile.packages).not.toHaveProperty(['/dep-of-pkg-with-1-dep/100.0.0'])
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user