Skip to content

Commit

Permalink
respect peer dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
korelstar committed Apr 2, 2021
1 parent 02f7ca0 commit 6b0c75c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 2 deletions.
34 changes: 32 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,11 @@ async function analyzeProjectDependencies(options, pkgData, pkgFile) {
print(options, '\nOptions:', 'verbose')
print(options, sortOptions(options), 'verbose')

const [upgraded, latest] = await vm.upgradePackageDefinitions(current, options)
const peerDependencies = getPeerDependencies(current, options)
print(options, '\nPeerDependencies:', 'verbose')
print(options, peerDependencies, 'verbose')

const [upgraded, latest] = await vm.upgradePackageDefinitions(current, { ...options, peerDependencies })

print(options, '\nFetched:', 'verbose')
print(options, latest, 'verbose')
Expand Down Expand Up @@ -224,6 +228,32 @@ async function analyzeProjectDependencies(options, pkgData, pkgFile) {
return output
}

/** Get peer dependencies from installed packages */
function getPeerDependencies(current, options) {
const basePath = options.cwd || './'
return Object.keys(current).map(pkgName => {
const path = basePath + 'node_modules/' + pkgName + '/package.json'
try {
const pkgData = fs.readFileSync(path)
const pkg = jph.parse(pkgData)
return vm.getCurrentDependencies(pkg, { dep: 'peer', filter: options.filter, reject: options.reject })
}
catch (e) {
print(options, 'Could not read peer dependencies for package ' + pkgName + '. Is this package installed?', 'warn')
return {}
}
}).reduce((acc, peers) => {
Object.entries(peers).forEach(([pkgName, version]) => {
if (acc[pkgName] === undefined) {
acc[pkgName] = []
}
// eslint-disable-next-line fp/no-mutating-methods
acc[pkgName].push(version)
})
return acc
}, {})
}

//
// Program
//
Expand Down Expand Up @@ -535,4 +565,4 @@ function getNcurc({ configFileName, configFilePath, packageFile } = {}) {
return result ? { ...result, args } : null
}

module.exports = { run, getNcurc, ...vm }
module.exports = { run, getNcurc, getPeerDependencies, ...vm }
15 changes: 15 additions & 0 deletions lib/package-managers/npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,27 @@ function satisfiesNodeEngine(versionResult, nodeEngine) {
return versionNodeEngine && semver.satisfies(minVersion, versionNodeEngine)
}

/**
* Returns true if the peer dependencies requirement is satisfied or not specified for a given package version.
*
* @param versionResult Version object returned by pacote.packument.
* @param peerDependencies The list of peer dependencies.
* @returns True if the peer dependencies are satisfied or not specified.
*/
function satisfiesPeerDependencies(versionResult, peerDependencies) {
if (!peerDependencies) return true
const pkgPeerDependencies = peerDependencies[versionResult.name]
if (!pkgPeerDependencies) return true
return pkgPeerDependencies.every(v => semver.satisfies(versionResult.version, v))
}

/** Returns a composite predicate that filters out deprecated, prerelease, and node engine incompatibilies from version objects returns by pacote.packument. */
function filterPredicate(options) {
return _.overEvery([
options.deprecated ? null : o => !o.deprecated,
options.pre ? null : o => !versionUtil.isPre(o.version),
options.enginesNode ? o => satisfiesNodeEngine(o, options.enginesNode) : null,
options.peerDependencies ? o => satisfiesPeerDependencies(o, options.peerDependencies) : null,
])
}

Expand Down

0 comments on commit 6b0c75c

Please sign in to comment.