Skip to content

Commit

Permalink
fix: Is there a way to not upgrade a package if it's peer depndencies…
Browse files Browse the repository at this point in the history
… are not currently met raineorshine#1418
  • Loading branch information
rbnayax committed Jun 2, 2024
1 parent 2158fb6 commit 0203128
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 19 deletions.
55 changes: 37 additions & 18 deletions src/lib/getIgnoredUpgrades.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { satisfies } from 'semver'
import semver, { satisfies } from 'semver'
import { IgnoredUpgrade } from '../types/IgnoredUpgrade'
import { Index } from '../types/IndexType'
import { Options } from '../types/Options'
import { Version } from '../types/Version'
import { VersionSpec } from '../types/VersionSpec'
import getPeerDependenciesFromRegistry from './getPeerDependenciesFromRegistry'
import upgradePackageDefinitions from './upgradePackageDefinitions'

/** Get all upgrades that are ignored due to incompatible peer dependencies. */
Expand All @@ -13,36 +14,54 @@ export async function getIgnoredUpgrades(
upgradedPeerDependencies: Index<Index<Version>>,
options: Options = {},
) {
const upgradedPackagesWithPeerRestriction = Object.fromEntries(
Object.entries({
...current,
...upgraded,
}).map(([packageName, versionSpec]) => {
return [packageName, semver.minVersion(versionSpec)?.version ?? versionSpec]
}),
)
const [upgradedLatestVersions, latestVersionResults] = await upgradePackageDefinitions(current, {
...options,
peer: false,
peerDependencies: undefined,
loglevel: 'silent',
})

const upgradedPeerDependenciesLatest = await getPeerDependenciesFromRegistry(upgradedLatestVersions, options)
return Object.entries(upgradedLatestVersions)
.filter(([pkgName, newVersion]) => upgraded[pkgName] !== newVersion)
.reduce(
(accum, [pkgName, newVersion]) => ({
.reduce((accum, [pkgName, newVersion]) => {
let reason = Object.entries(upgradedPeerDependencies)
.filter(
([, peers]) =>
peers[pkgName] !== undefined &&
latestVersionResults[pkgName]?.version &&
!satisfies(latestVersionResults[pkgName].version!, peers[pkgName]),
)
.reduce((accumReason, [peerPkg, peers]) => ({ ...accumReason, [peerPkg]: peers[pkgName] }), {} as Index<string>)
if (Object.keys(reason).length === 0) {
const peersOfPkg = upgradedPeerDependenciesLatest?.[pkgName] || {}
reason = Object.entries(peersOfPkg)
.filter(
([peer, peerSpec]) =>
upgradedPackagesWithPeerRestriction[peer] &&
!satisfies(upgradedPackagesWithPeerRestriction[peer], peerSpec),
)
.reduce(
(accumReason, [peerPkg, peerSpec]) => ({ ...accumReason, [pkgName]: `${peerPkg} ${peerSpec}` }),
{} as Index<string>,
)
}
return {
...accum,
[pkgName]: {
from: current[pkgName],
to: newVersion,
reason: Object.entries(upgradedPeerDependencies)
.filter(
([, peers]) =>
peers[pkgName] !== undefined &&
latestVersionResults[pkgName]?.version &&
!satisfies(latestVersionResults[pkgName].version!, peers[pkgName]),
)
.reduce(
(accumReason, [peerPkg, peers]) => ({ ...accumReason, [peerPkg]: peers[pkgName] }),
{} as Index<string>,
),
reason,
},
}),
{} as Index<IgnoredUpgrade>,
)
}
}, {} as Index<IgnoredUpgrade>)
}

export default getIgnoredUpgrades
2 changes: 1 addition & 1 deletion test/peer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ describe('peer dependencies', function () {
return packageName === 'eslint-plugin-unused-imports' ? 'latest' : 'minor'
},
})
upgrades!.should.contain.keys('@vitest/ui', 'vitest')
upgrades!.should.have.all.keys('@vitest/ui', 'vitest')
})
})

0 comments on commit 0203128

Please sign in to comment.