mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-28 02:53:15 -04:00
6
.changeset/two-cobras-melt.md
Normal file
6
.changeset/two-cobras-melt.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/resolve-dependencies": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
Deduplicate peer dependencies when automatically installing them [#5373](https://github.com/pnpm/pnpm/issues/5373).
|
||||
@@ -148,6 +148,23 @@ test('don\'t install the same missing peer dependency twice', async () => {
|
||||
].sort())
|
||||
})
|
||||
|
||||
// Covers https://github.com/pnpm/pnpm/issues/5373
|
||||
test('prefer the peer dependency version already used in the root', async () => {
|
||||
await addDistTag({ package: '@pnpm/y', version: '2.0.0', distTag: 'latest' })
|
||||
const project = prepareEmpty()
|
||||
await install({
|
||||
peerDependencies: {
|
||||
'@pnpm.e2e/has-y-peer': '1.0.0',
|
||||
'@pnpm/y': '^1.0.0',
|
||||
},
|
||||
}, await testDefaults({ autoInstallPeers: true }))
|
||||
const lockfile = await project.readLockfile()
|
||||
expect(Object.keys(lockfile.packages).sort()).toStrictEqual([
|
||||
'/@pnpm/y/1.0.0',
|
||||
'/@pnpm.e2e/has-y-peer/1.0.0_@pnpm+y@1.0.0',
|
||||
].sort())
|
||||
})
|
||||
|
||||
test('automatically install root peer dependencies', async () => {
|
||||
const project = prepareEmpty()
|
||||
|
||||
|
||||
@@ -387,10 +387,10 @@ async function resolveDependenciesOfImporters (
|
||||
}
|
||||
const pkgAddressesByImportersWithoutPeers = await Promise.all(zipWith(async (importer, { pkgAddresses, postponedResolutionsQueue, postponedPeersResolutionQueue }) => {
|
||||
const newPreferredVersions = { ...importer.preferredVersions }
|
||||
const newParentPkgAliases = { ...importer.parentPkgAliases }
|
||||
const currentParentPkgAliases = {}
|
||||
for (const pkgAddress of pkgAddresses) {
|
||||
if (newParentPkgAliases[pkgAddress.alias] !== true) {
|
||||
newParentPkgAliases[pkgAddress.alias] = pkgAddress
|
||||
if (currentParentPkgAliases[pkgAddress.alias] !== true) {
|
||||
currentParentPkgAliases[pkgAddress.alias] = pkgAddress
|
||||
}
|
||||
if (pkgAddress.updated) {
|
||||
ctx.updatedSet.add(pkgAddress.alias)
|
||||
@@ -402,6 +402,7 @@ async function resolveDependenciesOfImporters (
|
||||
}
|
||||
newPreferredVersions[resolvedPackage.name][resolvedPackage.version] = 'version'
|
||||
}
|
||||
const newParentPkgAliases = { ...importer.parentPkgAliases, ...currentParentPkgAliases }
|
||||
const postponedResolutionOpts = {
|
||||
preferredVersions: newPreferredVersions,
|
||||
parentPkgAliases: newParentPkgAliases,
|
||||
@@ -420,9 +421,10 @@ async function resolveDependenciesOfImporters (
|
||||
const postponedPeersResolution = await Promise.all(
|
||||
postponedPeersResolutionQueue.map((postponedMissingPeers) => postponedMissingPeers(postponedResolutionOpts.parentPkgAliases))
|
||||
)
|
||||
const resolvedPeers = [...childrenResults, ...postponedPeersResolution].reduce((acc, { resolvedPeers }) => Object.assign(acc, resolvedPeers), {})
|
||||
const allMissingPeers = mergePkgsDeps(
|
||||
[
|
||||
...pkgAddresses,
|
||||
...filterMissingPeersFromPkgAddresses(pkgAddresses, currentParentPkgAliases, resolvedPeers),
|
||||
...childrenResults,
|
||||
...postponedPeersResolution,
|
||||
].map(({ missingPeers }) => missingPeers).filter(Boolean)
|
||||
@@ -430,7 +432,7 @@ async function resolveDependenciesOfImporters (
|
||||
return {
|
||||
missingPeers: allMissingPeers,
|
||||
pkgAddresses,
|
||||
resolvedPeers: [...childrenResults, ...postponedPeersResolution].reduce((acc, { resolvedPeers }) => Object.assign(acc, resolvedPeers), {}),
|
||||
resolvedPeers,
|
||||
}
|
||||
}, importers, resolveResults))
|
||||
return {
|
||||
@@ -440,6 +442,22 @@ async function resolveDependenciesOfImporters (
|
||||
}
|
||||
}
|
||||
|
||||
function filterMissingPeersFromPkgAddresses (pkgAddresses: PkgAddress[], currentParentPkgAliases: ParentPkgAliases, resolvedPeers: ResolvedPeers) {
|
||||
return pkgAddresses.map((pkgAddress) => ({
|
||||
...pkgAddress,
|
||||
missingPeers: fromPairs(
|
||||
Object.entries(pkgAddress.missingPeers || {})
|
||||
.filter(([peerName]) => {
|
||||
if (!currentParentPkgAliases[peerName]) return true
|
||||
if (currentParentPkgAliases[peerName] !== true) {
|
||||
resolvedPeers[peerName] = currentParentPkgAliases[peerName] as PkgAddress
|
||||
}
|
||||
return false
|
||||
})
|
||||
),
|
||||
}))
|
||||
}
|
||||
|
||||
function getPublishedByDate (pkgAddresses: PkgAddress[], timeFromLockfile: Record<string, string> = {}): { publishedBy: Date, newTime: Record<string, string> } {
|
||||
const newTime: Record<string, string> = {}
|
||||
for (const pkgAddress of pkgAddresses) {
|
||||
@@ -559,19 +577,7 @@ async function startResolvingPeers (
|
||||
const resolvedPeers = [...childrenResults, ...results].reduce((acc, { resolvedPeers }) => Object.assign(acc, resolvedPeers), {})
|
||||
const allMissingPeers = mergePkgsDeps(
|
||||
[
|
||||
...pkgAddresses.map((pkgAddress) => ({
|
||||
...pkgAddress,
|
||||
missingPeers: fromPairs(
|
||||
Object.entries(pkgAddress.missingPeers || {})
|
||||
.filter(([peerName]) => {
|
||||
if (!currentParentPkgAliases[peerName]) return true
|
||||
if (currentParentPkgAliases[peerName] !== true) {
|
||||
resolvedPeers[peerName] = currentParentPkgAliases[peerName]
|
||||
}
|
||||
return false
|
||||
})
|
||||
),
|
||||
})),
|
||||
...filterMissingPeersFromPkgAddresses(pkgAddresses, currentParentPkgAliases, resolvedPeers),
|
||||
...childrenResults,
|
||||
...results,
|
||||
].map(({ missingPeers }) => missingPeers).filter(Boolean)
|
||||
|
||||
Reference in New Issue
Block a user