fix: improve error message on peer dependency issues (#3650)

This commit is contained in:
Zoltan Kochan
2021-08-06 23:53:00 +03:00
committed by GitHub
parent 92ed1272ef
commit 135d538278
3 changed files with 35 additions and 12 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/resolve-dependencies": patch
---
Include the path to the project in which the peer dependency is missing.

View File

@@ -227,6 +227,7 @@ function resolvePeersOfNode<T extends PartialResolvedPackage> (
: resolvePeers({
currentDepth: node.depth,
dependenciesTree: ctx.dependenciesTree,
lockfileDir: ctx.lockfileDir,
nodeId,
parentPkgs,
resolvedPackage,
@@ -369,6 +370,7 @@ function resolvePeersOfChildren<T extends PartialResolvedPackage> (
function resolvePeers<T extends PartialResolvedPackage> (
ctx: {
currentDepth: number
lockfileDir: string
nodeId: string
parentPkgs: ParentRefs
resolvedPackage: T
@@ -391,7 +393,7 @@ function resolvePeers<T extends PartialResolvedPackage> (
) {
continue
}
const friendlyPath = nodeIdToFriendlyPath(ctx.nodeId, ctx.dependenciesTree)
const friendlyPath = nodeIdToFriendlyPath(ctx)
const message = `${friendlyPath ? `${friendlyPath}: ` : ''}${packageFriendlyId(ctx.resolvedPackage)} \
requires a peer of ${peerName}@${peerVersionRange} but none was installed.`
if (ctx.strictPeerDependencies) {
@@ -405,7 +407,7 @@ requires a peer of ${peerName}@${peerVersionRange} but none was installed.`
}
if (!semver.satisfies(resolved.version, peerVersionRange)) {
const friendlyPath = nodeIdToFriendlyPath(ctx.nodeId, ctx.dependenciesTree)
const friendlyPath = nodeIdToFriendlyPath(ctx)
const message = `${friendlyPath ? `${friendlyPath}: ` : ''}${packageFriendlyId(ctx.resolvedPackage)} \
requires a peer of ${peerName}@${peerVersionRange} but version ${resolved.version} was installed.`
if (ctx.strictPeerDependencies) {
@@ -426,13 +428,28 @@ function packageFriendlyId (manifest: {name: string, version: string}) {
return `${manifest.name}@${manifest.version}`
}
function nodeIdToFriendlyPath<T extends PartialResolvedPackage> (nodeId: string, dependenciesTree: DependenciesTree<T>) {
function nodeIdToFriendlyPath<T extends PartialResolvedPackage> (
{
dependenciesTree,
lockfileDir,
nodeId,
rootDir,
}: {
dependenciesTree: DependenciesTree<T>
lockfileDir: string
nodeId: string
rootDir: string
}
) {
const parts = splitNodeId(nodeId).slice(0, -1)
const result = scan((prevNodeId, pkgId) => createNodeId(prevNodeId, pkgId), '>', parts)
.slice(2)
.map((nid) => (dependenciesTree[nid].resolvedPackage as ResolvedPackage).name)
.join(' > ')
return result
const projectPath = path.relative(lockfileDir, rootDir)
if (projectPath) {
result.unshift(projectPath)
}
return result.join(' > ')
}
interface ParentRefs {

View File

@@ -156,16 +156,17 @@ test('the right peer dependency is used in every workspace package', async () =>
test('warning is reported when cannot resolve peer dependency for top-level dependency', async () => {
prepareEmpty()
const reporter = sinon.spy()
const reporter = jest.fn()
await addDependenciesToPackage({}, ['ajv-keywords@1.5.0'], await testDefaults({ reporter }))
const logMatcher = sinon.match({
message: 'ajv-keywords@1.5.0 requires a peer of ajv@>=4.10.0 but none was installed.',
})
const reportedTimes = reporter.withArgs(logMatcher).callCount
expect(reportedTimes).toBe(1)
expect(reporter).toBeCalledWith(
expect.objectContaining({
level: 'warn',
name: 'pnpm',
message: 'ajv-keywords@1.5.0 requires a peer of ajv@>=4.10.0 but none was installed.',
})
)
})
test('strict-peer-dependencies: error is thrown when cannot resolve peer dependency for top-level dependency', async () => {