Commit Graph
4 Commits
Author SHA1 Message Date
Altay 581a17de66 fix(reporter): restore colored script output performance (#16821)
Avoid per-fragment sanitization when output contains only printable text,
tabs and SGR sequences. Preserve the existing sanitizer for other controls.

Closes pnpm/tasks#119
2026-10-10 18:38:52 +02:00
Zoltan Kochan f79f8638e2 feat(run): keep script colors in streamed output and sanitize it (#16694)
When `pnpm run` or `pnpm exec` prints a script's output under the
project's name (--stream, --parallel, concurrent recursive runs, pipeline
tasks), the child's stdout is piped, so most tools turned their colors
off. pnpm now sets FORCE_COLOR=1 for these children when its own output
is in color through the default or append-only reporter, keeping a
FORCE_COLOR that is already set.

Colored child output exposed rendering bugs in the v12 reporter, fixed
here:

- cut_line counted escape bytes as visible characters and could split a
  color code. It now uses console::truncate_str.
- Lines are split only on \n, so a \r progress bar reached the in-place
  frame with embedded carriage returns. printable_script_line keeps the
  last non-empty \r frame.
- Cursor movement, OSC links and other control characters from a child
  are dropped by a small ECMA-48 escape parser (the locked console
  0.16.3 iterator misses OSC and private-marker CSI). Only SGR sequences
  whose parameters are digits, ';' or ':' count as colors, and they
  are kept only when pnpm renders in color. A line that keeps a color
  ends with a reset so it cannot bleed into the next line or prefix.

run_stage wrote the [ELIFECYCLE] line with eprintln! while the default
reporter redrew its frame in place, so the next redraw moved the cursor
over the wrong rows. A streamed run now emits it as an error-level pnpm
log, which the reporter adds to the frame. An inherited run still writes
it to stderr.

The v11 reporter had the same cursor-code problem (a TODO in
reportLifecycleScripts.ts). It now keeps only SGR sequences, using
node:util stripVTControlCharacters for the rest, and appends the same
reset. v11 already splits \r into separate lines, and FORCE_COLOR is a
v12-only feature.
2026-10-07 15:54:14 +02:00
Zoltan Kochan 4edeef9176 style(ts): port the perfectionist lint rules to ESLint (#16415)
Add TypeScript ports of the perfectionist rules that the Rust workspace
enforces through dylint.toml to @pnpm/eslint-config, with the same limits,
and fix every finding that needs no refactor.

The size and shape rules (function length, cognitive complexity, nesting,
local bindings, file length) are enforced for packages that already meet
them. The packages that do not are listed in PENDING_SIZE_AND_SHAPE_REFACTOR
in eslint.config.mjs and are refactored in follow-up changes.

The custom rules mirror perfectionist's semantics rather than reusing
sonarjs or max-lines-per-function, so that one limit means the same thing
in both codebases: a closure is a level of the body that contains it, a
nested function declaration is measured on its own, and a test-framework
callback plays the role of a #[test] function.

Bugs found and fixed along the way:
- a registry error body cut at exactly 64 KiB lost its truncation marker
- removing a dependency could leave dangling .bin shims
- constructor/__proto__ names crashed the projects graph, were skipped by
  the injected-deps syncer, and were dropped from writeWantedLockfile's
  returned lockfile

The CI chunk runner learns to run the node:test suite of the ESLint
config package.
2026-09-30 15:10:08 +02:00
Zoltan Kochan fc2f33912e refactor: move the TypeScript pnpm CLI into a pnpm11/ directory (#12537)
The TypeScript pnpm CLI freezes at v11; pnpm 12 will be the Rust pacquet
port. To make that split legible, all TypeScript source, test, and build
directories move under a new top-level pnpm11/ directory. The name states
the version boundary rather than implying a behavioral fork, since the two
stacks are meant to behave identically.

Scope is source-only: the shared workspace root stays at the repo root.
pnpm-workspace.yaml, package.json, pnpm-lock.yaml, .pnpmfile.cjs,
.meta-updater, __patches__, .changeset, .husky, and the lint/spell configs
remain in place, so one pnpm workspace and one Cargo workspace still span
all three products. pnpr/client and pacquet/tasks/registry-mock stay as
cross-product workspace members.

Rewiring the move required:
- pnpm-workspace.yaml globs prefixed with pnpm11/
- root package.json script paths, eslint.config.mjs, tsconfig.lint.json,
  .gitignore, and CODEOWNERS updated
- .meta-updater/src/index.ts literals repointed (pnpm11/pnpm/package.json,
  pnpm11/__utils__, pnpm11/__typings__, and the main package directory)
- regenerated every moved package's repository/homepage URL via meta-updater
- pnpm11/pnpm/bundle-deps.ts and __utils__/scripts/src/typecheck-only.ts
  climb one more level to reach the repo root

.meta-updater stays at the repo root because @pnpm/meta-updater resolves
its config at <cwd>/.meta-updater/main.mjs.

TS CI (.github/workflows/ci.yml) now only runs when pnpm11/-relevant paths
change, via a dorny/paths-filter changes job plus a TS CI / Success
aggregate gate; branch protection should require only that gate.
2026-06-20 14:36:25 +02:00