mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-28 02:53:15 -04:00
fix: improve error message on peer dependency issues (#3650)
This commit is contained in:
5
.changeset/friendly-toes-relax.md
Normal file
5
.changeset/friendly-toes-relax.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/resolve-dependencies": patch
|
||||
---
|
||||
|
||||
Include the path to the project in which the peer dependency is missing.
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
Reference in New Issue
Block a user