* fix: signal the script's process group when pnpm has no terminal A signal aimed at pnpm alone is the only kind that reaches it without a controlling terminal, and both runners relayed it to the shell that runs the script. A shell that stays the script's parent, as dash does for a command like `node server.js`, dies from SIGTERM at once and holds a SIGINT until its child exits, so the script never heard that it should stop, and a container runtime then killed it outright. Without a controlling terminal each script now gets a process group of its own, pnpm relays its signals to that group, and after a relayed signal it waits for the group to empty before ending, so the script's shutdown completes even though its shell is gone. With a terminal nothing changes: the child stays in the foreground group, where the terminal's own signals reach it and it may read the terminal. pnpm v12 decides this in spawn_child and waits in SpawnedChild::wait, which the output pump now goes through too; members that became pnpm's children, as they do when pnpm is PID 1, are reaped along the way. pnpm v11 spawns the shell detached and polls ps for live members of the group. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(cli): decide the exec process-group test by the terminal it has The process-group check ran under whatever terminal the harness had, so it held on a developer's terminal and failed on CI, which has none. It now runs pacquet on a pseudo-terminal for the foreground case and in a session without one for the own-group case. The terminal helpers of the interrupt tests move to the suite's utilities for that. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(cli): run the remaining foreground-group checks on a terminal The filtered-run and serialized-task process-group checks made the same assumption as the exec one: that the harness holds a terminal. They now run pacquet on a pseudo-terminal too. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(executor): assert the foreground group only at a terminal The unit test assumed the test process holds a terminal. It now checks the contract for whichever case it runs in: a shared group at a terminal, the child's own group without one. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(npm-lifecycle): probe the process group without ps, and raise the death signal after the wait The group wait asked ps and took any failure for an empty group, so a container without a usable ps cut the shutdown short. The group is now probed the way the kernel counts it, with a signal of 0, and on Linux a member that exited but is not reaped yet, as happens when pnpm is a container's PID 1, is told apart through /proc. A shell killed by the relayed signal made the runner raise that signal on pnpm at once, before the group wait, and pnpm's own listener was already consumed, so pnpm died while the script was still shutting down. The raise now comes after the wait. An onSpawn observer that throws signals the whole group too. The tests observe the runner's exit rather than its output: a script that outlives the runner keeps the shared pipe open, which hid this. A failed setsid in the test helper fails the spawn. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(npm-lifecycle): give up the group wait when the group cannot be observed A probe error other than "no such process", such as a permission error from a member that changed user, made the group count as live on every poll, so the wait never ended. Such an error now rejects the wait and the runner goes on. A /proc entry that vanished between the listing and the read has exited; one whose state cannot be read counts as live. The runner's doc says that a script's death signal, raised after the wait, ends pnpm before the callback unless something handles it. The tests kill the detached process group whatever way they end. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(npm-lifecycle): leave unreadable /proc entries out of the group An entry whose state cannot be read is not a member pnpm can observe: it exited since the listing, or it belongs to another user under a restricted process table. Counting it as live kept the wait going on every poll. The test helper kills the detached group as soon as the runner has exited, before waiting for the output pipe a survivor would hold open, and its timeout kills the group rather than the runner alone. The cleanup helper is shared through `@pnpm/prepare` and accepts only a group that is gone already. Two narrating comments in the Rust tests are gone. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(npm-lifecycle): cover the process-table scan with a table of its own The scan takes the process table's path, so a test can supply one with a zombie, a live member and an entry whose state cannot be read, and show that the wait ends for the first, goes on for the second, and does not mistake the third for a member. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(npm-lifecycle): helpers after their use, and a bump for the shared cleanup helper The process-table test's helpers follow the tests that call them, and the one that writes the table states what it creates and returns. The changeset lists `@pnpm/prepare`, which gained the shared cleanup helper. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(npm-lifecycle): keep only the non-obvious part of the table helper's doc Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(npm-lifecycle): clear the losing deadline timer Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
518 lines
7.9 KiB
JSON
518 lines
7.9 KiB
JSON
{
|
|
"ignorePaths": [
|
|
"**/nodeReleaseKeys.ts",
|
|
"**/nodeReleaseKeys.d.ts",
|
|
"**/node_release_keys.rs",
|
|
"bench-work-env/**"
|
|
],
|
|
"words": [
|
|
"abrt",
|
|
"adduser",
|
|
"adipiscing",
|
|
"agentkeepalive",
|
|
"agentkeepalive's",
|
|
"aliasless",
|
|
"amet",
|
|
"andreineculau",
|
|
"APFS",
|
|
"appdata",
|
|
"applyq",
|
|
"archy",
|
|
"argumentless",
|
|
"armv",
|
|
"AUTHTOKEN",
|
|
"autocheckpoint",
|
|
"autocompleting",
|
|
"autofix",
|
|
"autofixed",
|
|
"autoinstalled",
|
|
"autozoom",
|
|
"babek",
|
|
"Backblaze",
|
|
"badheaders",
|
|
"baires",
|
|
"basedirs",
|
|
"bdist",
|
|
"behaviour",
|
|
"blabla",
|
|
"Bluesky",
|
|
"brasileiro",
|
|
"bryntum",
|
|
"btrfs",
|
|
"buildx",
|
|
"cafile",
|
|
"cafs",
|
|
"camelcase",
|
|
"canonicalizer",
|
|
"cantopen",
|
|
"canva",
|
|
"CDPATH",
|
|
"cerbos",
|
|
"certfile",
|
|
"chcp",
|
|
"chmods",
|
|
"clonedeep",
|
|
"clonefile",
|
|
"cmds",
|
|
"Codeberg",
|
|
"codegen",
|
|
"codeload",
|
|
"codenames",
|
|
"codesign",
|
|
"colorterm",
|
|
"compdef",
|
|
"COMPREPLY",
|
|
"comver",
|
|
"cooldown",
|
|
"copyfiles",
|
|
"corejs",
|
|
"corepack",
|
|
"corge",
|
|
"cowsay",
|
|
"Creds",
|
|
"cryptiles",
|
|
"cves",
|
|
"CWORD",
|
|
"cwsay",
|
|
"cyclonedx",
|
|
"cygdrive",
|
|
"deburr",
|
|
"dedup",
|
|
"denoland",
|
|
"denolib",
|
|
"dependson",
|
|
"deptype",
|
|
"desugared",
|
|
"desugars",
|
|
"devextreme",
|
|
"devowl",
|
|
"dgimuvys",
|
|
"didyoumean",
|
|
"dirtyforms",
|
|
"diskusage",
|
|
"dislink",
|
|
"dpkg",
|
|
"drivelist",
|
|
"duplexify",
|
|
"eacces",
|
|
"eagain",
|
|
"ebadplatform",
|
|
"ebusy",
|
|
"eexist",
|
|
"ehrkoext",
|
|
"eintegrity",
|
|
"eisdir",
|
|
"elifecycle",
|
|
"elit",
|
|
"embedder",
|
|
"embedders",
|
|
"emfile",
|
|
"enametoolong",
|
|
"endregion",
|
|
"eneedauth",
|
|
"enoent",
|
|
"enotdir",
|
|
"enotempty",
|
|
"enten",
|
|
"eotp",
|
|
"eperm",
|
|
"epipe",
|
|
"erofs",
|
|
"errcode",
|
|
"esac",
|
|
"etamponi",
|
|
"exdev",
|
|
"execa",
|
|
"exploitability",
|
|
"fakehash",
|
|
"fellback",
|
|
"fetchings",
|
|
"filenamify",
|
|
"filesystem",
|
|
"filesystems",
|
|
"fnumber",
|
|
"foobarqar",
|
|
"foofoo",
|
|
"footgun",
|
|
"forgejo",
|
|
"fsevents",
|
|
"fslib",
|
|
"gabor",
|
|
"garply",
|
|
"gcttmf",
|
|
"getaddrinfo",
|
|
"getattr",
|
|
"ghes",
|
|
"ghsa",
|
|
"ghsas",
|
|
"gitdir",
|
|
"gitea",
|
|
"globalconfig",
|
|
"globstar",
|
|
"gnueabihf",
|
|
"gpgsign",
|
|
"grault",
|
|
"gruntfile",
|
|
"gwhitney",
|
|
"haptics",
|
|
"hardlink",
|
|
"hardlinked",
|
|
"hardlinking",
|
|
"hardlinks",
|
|
"hashbang",
|
|
"hashless",
|
|
"highmaps",
|
|
"hikljmi",
|
|
"hoistable",
|
|
"homepath",
|
|
"hosters",
|
|
"hostnames",
|
|
"htpasswd",
|
|
"hyperdrive",
|
|
"idempotency",
|
|
"imagetools",
|
|
"imurmurhash",
|
|
"inodes",
|
|
"invalidformat",
|
|
"ionicons",
|
|
"isexe",
|
|
"istvan",
|
|
"italiano",
|
|
"jega",
|
|
"jhcg",
|
|
"jnbpamcxayl",
|
|
"journaled",
|
|
"junyi",
|
|
"kebabcase",
|
|
"kevva",
|
|
"keyfile",
|
|
"keyid",
|
|
"keytype",
|
|
"killcb",
|
|
"kochan",
|
|
"koorchik",
|
|
"LASTEXITCODE",
|
|
"ldid",
|
|
"ldni",
|
|
"ledgered",
|
|
"leniolabs",
|
|
"libc",
|
|
"libnpmpublish",
|
|
"libnpx",
|
|
"libpnpm",
|
|
"libsql",
|
|
"libzip",
|
|
"licence",
|
|
"licences",
|
|
"lifecycles",
|
|
"linearization",
|
|
"linuxstatic",
|
|
"localappdata",
|
|
"lockfiles",
|
|
"loglevel",
|
|
"logstream",
|
|
"longlink",
|
|
"longpaths",
|
|
"loong",
|
|
"lowlink",
|
|
"luca",
|
|
"manylinux",
|
|
"martensson",
|
|
"maxsockets",
|
|
"maxtimeout",
|
|
"mdast",
|
|
"metacharacter",
|
|
"metafile",
|
|
"millis",
|
|
"minioadmin",
|
|
"mintimeout",
|
|
"mkfifo",
|
|
"mmap",
|
|
"monorepolint",
|
|
"montudor",
|
|
"moonrepo",
|
|
"mountpoint",
|
|
"msgpack",
|
|
"msgpackr",
|
|
"msvc",
|
|
"msys",
|
|
"MSYSTEM",
|
|
"mtimes",
|
|
"musleabihf",
|
|
"mycomp",
|
|
"mycompany",
|
|
"myorg",
|
|
"mypackage",
|
|
"mytoken",
|
|
"napi",
|
|
"ndjson",
|
|
"nerfed",
|
|
"newteam",
|
|
"newversion",
|
|
"nistp",
|
|
"NOASSERTION",
|
|
"nodepath",
|
|
"nodetouch",
|
|
"noent",
|
|
"nonexec",
|
|
"noninjected",
|
|
"nonvulnerable",
|
|
"noopener",
|
|
"nopadding",
|
|
"noprofile",
|
|
"noproxy",
|
|
"norc",
|
|
"noreferrer",
|
|
"nosystem",
|
|
"nothrow",
|
|
"npath",
|
|
"npmcli",
|
|
"npmignore",
|
|
"npmjs",
|
|
"npmmirror",
|
|
"npmx",
|
|
"ntfs",
|
|
"nushell",
|
|
"ofjergrg",
|
|
"oldteam",
|
|
"onclickoutside",
|
|
"oomol",
|
|
"openharmony",
|
|
"openpgp",
|
|
"openpyxl",
|
|
"ossl",
|
|
"outfile",
|
|
"overrider",
|
|
"packlist",
|
|
"packr",
|
|
"packument",
|
|
"packuments",
|
|
"pacquet",
|
|
"paralleljs",
|
|
"parallelly",
|
|
"parseable",
|
|
"partialmatch",
|
|
"pathext",
|
|
"pathsep",
|
|
"pegjs",
|
|
"pgid",
|
|
"pids",
|
|
"pidtree",
|
|
"pify",
|
|
"pkgid",
|
|
"pkgname",
|
|
"pkgs",
|
|
"plotly",
|
|
"plugh",
|
|
"pnpmfile",
|
|
"pnpmfiles",
|
|
"pnpmjs",
|
|
"pnpmrc",
|
|
"pnpmtest",
|
|
"pnpr",
|
|
"polyfilling",
|
|
"português",
|
|
"posix",
|
|
"postbuild",
|
|
"postfoo",
|
|
"postpack",
|
|
"postprepare",
|
|
"postpublish",
|
|
"postrestart",
|
|
"postshrinkwrap",
|
|
"poststart",
|
|
"poststop",
|
|
"posttest",
|
|
"postuninstall",
|
|
"postversion",
|
|
"preact",
|
|
"prebuild",
|
|
"prefoo",
|
|
"prefs",
|
|
"preinstall",
|
|
"premajor",
|
|
"preminor",
|
|
"prepatch",
|
|
"prepublish",
|
|
"prereleases",
|
|
"prerestart",
|
|
"preshrinkwrap",
|
|
"prestart",
|
|
"prestop",
|
|
"preuninstall",
|
|
"preversion",
|
|
"prioritizer",
|
|
"promisified",
|
|
"propfind",
|
|
"proxied",
|
|
"pwsh",
|
|
"pylock",
|
|
"pypi",
|
|
"pyproject",
|
|
"pythonhosted",
|
|
"qrcode",
|
|
"quux",
|
|
"rcompare",
|
|
"redownload",
|
|
"refclone",
|
|
"refetched",
|
|
"refetches",
|
|
"reflattened",
|
|
"reflink",
|
|
"reflinked",
|
|
"reflinks",
|
|
"rehoist",
|
|
"reimagining",
|
|
"reka",
|
|
"Rekor",
|
|
"relinks",
|
|
"renderable",
|
|
"reparses",
|
|
"replit",
|
|
"reqheaders",
|
|
"rescans",
|
|
"rescopable",
|
|
"rescope",
|
|
"rescoped",
|
|
"rescopes",
|
|
"rescoping",
|
|
"resolv",
|
|
"rimrafed",
|
|
"riscv",
|
|
"rmgr",
|
|
"rpmdevtools",
|
|
"rpmlint",
|
|
"rsort",
|
|
"rstacruz",
|
|
"rushstack",
|
|
"rustc",
|
|
"rustup",
|
|
"safecrlf",
|
|
"sccache",
|
|
"scopeless",
|
|
"scriptless",
|
|
"sdiff",
|
|
"searchexclude",
|
|
"searchlimit",
|
|
"searchopts",
|
|
"searchstaleness",
|
|
"secp",
|
|
"sels",
|
|
"semistrict",
|
|
"serde",
|
|
"serp",
|
|
"serverjs",
|
|
"SETLOCAL",
|
|
"shasums",
|
|
"sheetjs",
|
|
"Sherov",
|
|
"shlex",
|
|
"sigstore",
|
|
"sindresorhus",
|
|
"sirv",
|
|
"skopeo",
|
|
"SLSA",
|
|
"soporan",
|
|
"sopts",
|
|
"spdxdocs",
|
|
"SPDXID",
|
|
"sqld",
|
|
"srcset",
|
|
"ssri",
|
|
"stackblitz",
|
|
"stacktracey",
|
|
"stdtype",
|
|
"streamsearch",
|
|
"stringifying",
|
|
"strongconnect",
|
|
"subcmd",
|
|
"subdep",
|
|
"subdependencies",
|
|
"subdependency",
|
|
"subdeps",
|
|
"subdir",
|
|
"subdirs",
|
|
"subkey",
|
|
"subkeys",
|
|
"subpkg",
|
|
"subresource",
|
|
"supercede",
|
|
"Swatinem",
|
|
"syml",
|
|
"syncer",
|
|
"syscall",
|
|
"syscalls",
|
|
"systemroot",
|
|
"szia",
|
|
"tabtab",
|
|
"taffydb",
|
|
"taiki",
|
|
"tarballtemplate",
|
|
"Tarjan",
|
|
"taskkill",
|
|
"teambit",
|
|
"tempy",
|
|
"testcase",
|
|
"thesys",
|
|
"tlog",
|
|
"TLSV",
|
|
"toctou",
|
|
"todomvc",
|
|
"toplevel",
|
|
"TOTP",
|
|
"tsgo",
|
|
"tsparticles",
|
|
"turso",
|
|
"typecheck",
|
|
"typeflag",
|
|
"TYPELESS",
|
|
"unallowed",
|
|
"unconfigured",
|
|
"undeprecate",
|
|
"underperformance",
|
|
"undispatched",
|
|
"undollar",
|
|
"unextractable",
|
|
"uninstallation",
|
|
"unmigrated",
|
|
"unnest",
|
|
"unparseable",
|
|
"unreleasable",
|
|
"unreviewed",
|
|
"unskip",
|
|
"unstar",
|
|
"untracks",
|
|
"usecase",
|
|
"userconfig",
|
|
"userprofile",
|
|
"ustar",
|
|
"uuidv",
|
|
"valign",
|
|
"venv",
|
|
"versionless",
|
|
"vuln",
|
|
"waitpid",
|
|
"wbem",
|
|
"webauth",
|
|
"webcontainer",
|
|
"webdav",
|
|
"WIFEXITED",
|
|
"windir",
|
|
"windowspowershell",
|
|
"winst",
|
|
"workleap",
|
|
"worktree",
|
|
"worktrees",
|
|
"wrappy",
|
|
"wslpath",
|
|
"WTERMSIG",
|
|
"xattr",
|
|
"xattrs",
|
|
"xmarw",
|
|
"yazl",
|
|
"zkochan",
|
|
"zoli",
|
|
"zoltan"
|
|
]
|
|
}
|