mirror of
https://github.com/pnpm/pnpm.git
synced 2026-05-18 22:02:53 -04:00
fix: render peer dependency issues on strict error (#11450)
Fixes #11439. When `strictPeerDependencies: true` causes `ERR_PNPM_PEER_DEP_ISSUES`, the peer dependency issues are again rendered inline — using the **same format as `pnpm peers check`** — so users (and CI tools like Renovate) can see what failed without running another command. The non-strict warning path is unchanged: it still emits the short "Run `pnpm peers check`" hint. ### Behavior `strictPeerDependencies: true`: ``` ERR_PNPM_PEER_DEP_ISSUES Unmet peer dependencies ✕ unmet peer react Installed: 17.0.2 Wanted: ^18.2.0: react-dom@18.2.0 hint: To disable failing on peer dependency issues, add the following to pnpm-workspace.yaml in your project root: strictPeerDependencies: false ``` `strictPeerDependencies: false` (unchanged): ``` WARN Issues with peer dependencies found. Run "pnpm peers check" to list them. ``` ### Implementation - Added a new `@pnpm/deps.inspection.peers-issues-renderer` package at `deps/inspection/peers-issues-renderer/`, alongside its data producer `@pnpm/deps.inspection.peers-checker`. It exposes a single `renderPeerIssues()` that emits the flat issue list previously inlined in `pnpm peers check`. - Removed the duplicated formatter from `deps/inspection/commands/src/peers.ts` and made the `pnpm peers check` command consume the new renderer. - `cli/default-reporter/src/reportError.ts`: `reportPeerDependencyIssuesError` now calls the shared `renderPeerIssues()` and prefixes the hint block with the rendered output. Tests strip ANSI escapes before substring assertions so they stay correct under `FORCE_COLOR=1`. Result: a single renderer is shared between the install error and the `pnpm peers check` command — output is identical between the two paths.
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
"@pnpm/cli.meta": "workspace:*",
|
||||
"@pnpm/config.reader": "workspace:*",
|
||||
"@pnpm/core-loggers": "workspace:*",
|
||||
"@pnpm/deps.inspection.peers-issues-renderer": "workspace:*",
|
||||
"@pnpm/error": "workspace:*",
|
||||
"@pnpm/installing.dedupe.issues-renderer": "workspace:*",
|
||||
"@pnpm/installing.dedupe.types": "workspace:*",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Config } from '@pnpm/config.reader'
|
||||
import type { Log } from '@pnpm/core-loggers'
|
||||
import { renderPeerIssues } from '@pnpm/deps.inspection.peers-issues-renderer'
|
||||
import type { PnpmError } from '@pnpm/error'
|
||||
import { renderDedupeCheckIssues } from '@pnpm/installing.dedupe.issues-renderer'
|
||||
import type { DedupeCheckIssues } from '@pnpm/installing.dedupe.types'
|
||||
@@ -461,9 +462,7 @@ function reportPeerDependencyIssuesError (
|
||||
msg: { issuesByProjects: PeerDependencyIssuesByProjects }
|
||||
): ErrorInfo {
|
||||
const hasMissingPeers = getHasMissingPeers(msg.issuesByProjects)
|
||||
const hints: string[] = [
|
||||
'Run "pnpm peers check" to list the peer dependency issues.',
|
||||
]
|
||||
const hints: string[] = []
|
||||
if (hasMissingPeers) {
|
||||
hints.push(`To auto-install peer dependencies, add the following to "pnpm-workspace.yaml" in your project root:
|
||||
|
||||
@@ -471,11 +470,12 @@ function reportPeerDependencyIssuesError (
|
||||
}
|
||||
hints.push(`To disable failing on peer dependency issues, add the following to pnpm-workspace.yaml in your project root:
|
||||
|
||||
strictPeerDependencies: false
|
||||
`)
|
||||
strictPeerDependencies: false`)
|
||||
const formattedHints = hints.map((hint) => `hint: ${hint}`).join('\n')
|
||||
const rendered = renderPeerIssues(msg.issuesByProjects)
|
||||
return {
|
||||
title: err.message,
|
||||
body: hints.map((hint) => `hint: ${hint}`).join('\n'),
|
||||
body: rendered ? `${rendered}\n${formattedHints}` : formattedHints,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { stripVTControlCharacters as stripAnsi } from 'node:util'
|
||||
|
||||
import { expect, test } from '@jest/globals'
|
||||
import { toOutput$ } from '@pnpm/cli.default-reporter'
|
||||
import { peerDependencyIssuesLogger } from '@pnpm/core-loggers'
|
||||
@@ -44,7 +46,7 @@ test('print peer dependency issues warning', async () => {
|
||||
expect.assertions(1)
|
||||
|
||||
const output = await firstValueFrom(output$)
|
||||
expect(output).toContain('pnpm peers check')
|
||||
expect(stripAnsi(output)).toContain('pnpm peers check')
|
||||
})
|
||||
|
||||
test('print peer dependency issues error', async () => {
|
||||
@@ -81,8 +83,10 @@ test('print peer dependency issues error', async () => {
|
||||
})
|
||||
logger.error(err, err)
|
||||
|
||||
expect.assertions(1)
|
||||
expect.assertions(3)
|
||||
|
||||
const output = await firstValueFrom(output$)
|
||||
expect(output).toContain('pnpm peers check')
|
||||
const output = stripAnsi(await firstValueFrom(output$))
|
||||
expect(output).toContain('unmet peer a')
|
||||
expect(output).toContain('Installed: 2')
|
||||
expect(output).toContain('b@1.0.0')
|
||||
})
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
{
|
||||
"path": "../../core/types"
|
||||
},
|
||||
{
|
||||
"path": "../../deps/inspection/peers-issues-renderer"
|
||||
},
|
||||
{
|
||||
"path": "../../installing/dedupe/issues-renderer"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user