Files
pnpm/clippy.toml
T
Florent Destremau 0d1597b3a5 fix(cli): stop aborting when stdout is a closed pipe (#16932)
`println!` panics when its write fails, and the release profile builds
with `panic = "abort"`. When the reader of pnpm's stdout had exited, as
in `pnpm --version | true` or `pnpm config list | head -0`, pnpm raised
SIGABRT: exit code 134 and a core dump.

`pnpm-diagnostics` now exports `println!` and `print!` macros next to the
stderr ones from pnpm/pnpm#16916. A write whose reader closed the pipe is
dropped and the command finishes with its own exit status. Any other
failed write is kept, and `main` flushes stdout and fails the command
with it through `report_fatal_error`, so the NDJSON reporter still gets
a JSON record. Every `print!`/`println!` of the binary and the direct
stdout writes of `outdated`, `cat-file`, `cat-index`, `sbom`, `audit`
and `completion` go through them. clippy's `print_stdout` restriction
lint now rejects the std macros, with the same crate-level opt-outs as
`print_stderr`. The watch agent of `pnpm pipeline --watch` stops with
exit 0 once a write finds its reader gone, so `pnpm pipeline --watch |
head -1` does not hang. `run`, `exec`, `audit` and `sbom` print their
no-projects-matched notice through one helper, which keeps
`run_recursive` within perfectionist's length limit.

The tracking issue asked for pnpm to exit 0 at the first failed write,
as pnpm 11 does. Exiting is the wrong default:

- `outdated` and `audit` carry their verdict in the exit status. An
  `exit(0)` turned `pnpm outdated | head` from 1 into 0, and would let
  `pnpm audit | head` pass a CI job under `pipefail`.
- `clean` prints "Removing <path>" before each removal, and the prune
  report of `audit` comes before its write to pnpm-workspace.yaml. An
  `exit(0)` there ends the command with work undone and a success code.
- No command computes much after its first stdout write: `list`, `why`
  and the registry queries render their whole output, then print it once.

pnpm 11.28.5 shows both failures: `outdated | true` exits 0 with an
outdated dependency, and `clean --lockfile | true` removes nothing and
exits 0.

Restoring the default SIGPIPE disposition is still not an option: pnpm
writes to its children's stdin and relies on the `BrokenPipe` error to
notice a child that stopped reading.

Closes pnpm/tasks#132
2026-10-15 13:19:17 +02:00

4 lines
150 B
TOML

# `print_stderr` and `print_stdout` guard the shipped binary against a closed stderr or stdout.
# Tests may print freely.
allow-print-in-tests = true