Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/spec/scripts/check-generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,10 @@ function runScript(script: string): { ok: boolean; output: string } {
// the build alone; every gate keeps the caller's environment.
if (script === SPEC_BUILD) delete env.OS_SKIP_DTS;
try {
const output = execSync(`pnpm -s ${script}`, { cwd: pkgRoot, env, stdio: ['ignore', 'pipe', 'pipe'] }).toString();
// `--silent`, never `-s`: a global pnpm 11+/12 `@pnpm/exe` frontend parses the
// argv before handing off to the pinned pnpm and rejects `-s` with exit 2, which
// reads here as every gate stale.
const output = execSync(`pnpm --silent ${script}`, { cwd: pkgRoot, env, stdio: ['ignore', 'pipe', 'pipe'] }).toString();
return { ok: true, output };
} catch (err: any) {
return { ok: false, output: `${err?.stdout?.toString() ?? ''}${err?.stderr?.toString() ?? ''}`.trim() };
Expand Down
11 changes: 10 additions & 1 deletion scripts/build-console.sh
Original file line number Diff line number Diff line change
Expand Up @@ -321,9 +321,18 @@ pushd "$BUILD_ROOT" > /dev/null

# objectui's root package.json may pin packages that aren't available on
# every mirror. Fall back to the public registry just for this install.
#
# The console build needs objectui's devDependencies, so production mode is
# forced OFF: an inherited `npm_config_production=true` or an .npmrc
# `production=true` would otherwise skip them (NODE_ENV=production alone does
# not, under pnpm 10). Spelled `--config.production=false`, never
# `--prod=false`: a global pnpm 11+/12 `@pnpm/exe` frontend parses the argv
# itself before handing off to the version objectui pins, rejects a value on its
# boolean `--prod` and exits 2 without installing anything. The pinned pnpm and
# that frontend both accept this spelling.
NPM_CONFIG_REGISTRY_OVERRIDE="${OBJECTUI_NPM_REGISTRY:-https://registry.npmjs.org}"
npm_config_registry="$NPM_CONFIG_REGISTRY_OVERRIDE" \
pnpm install --frozen-lockfile --prefer-offline --prod=false
pnpm install --frozen-lockfile --prefer-offline --config.production=false

# Build the console's workspace deps via turbo, then the SPA itself directly
# (see DEPS_BUILD_CMD/BUILD_CMD above for why these are split).
Expand Down
15 changes: 10 additions & 5 deletions scripts/check-regen-pending.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -859,9 +859,12 @@ export function gateCouldNotRun(output, exitCode, fromDir, gate = null) {
return null;
}

// `--silent`, never `-s`: a global pnpm 11+/12 `@pnpm/exe` frontend parses the argv
// before handing off to the pinned pnpm and rejects `-s` with exit 2 — every artifact
// would read as stale and every commit would be refused.
function runCheck(script, cwd) {
try {
execSync(`pnpm -s ${script}`, { cwd, stdio: ['ignore', 'pipe', 'pipe'] });
execSync(`pnpm --silent ${script}`, { cwd, stdio: ['ignore', 'pipe', 'pipe'] });
return { ok: true, output: '', code: 0 };
} catch (err) {
return {
Expand Down Expand Up @@ -1396,7 +1399,7 @@ function fixtureSelfTest() {
/**
* The pnpm the fixture's stub gate runs under, pinned to the repository's own.
*
* `runCheck` spawns every gate with `pnpm -s`, and CI reaches pnpm through
* `runCheck` spawns every gate with `pnpm --silent`, and CI reaches pnpm through
* Corepack (`.github/actions/setup-pnpm`). Corepack resolves the version from
* the project it is invoked IN, so a fixture carrying no `packageManager` field
* does not inherit this repo's pin and does not get "whatever the machine has"
Expand All @@ -1405,8 +1408,10 @@ function fixtureSelfTest() {
* published that morning: the day `latest` moved to a major whose CLI rejects
* `-s`, the "clean" stub exited 2 without ever running, and every case that
* reads the stub's own exit code went red on a tree nobody had touched. It is
* the FIXTURE that was unpinned, never production — the real hook runs `pnpm -s`
* in this repository, which is pinned.
* the FIXTURE that was unpinned, never production — the real hook runs in this
* repository, which is pinned. A pin does not reach the argv parser of a global
* pnpm 11+ `@pnpm/exe` frontend, though, which is why the spawn is spelled
* `--silent` rather than `-s`.
*
* Read off the ROOT manifest rather than written as a literal, so the fixture
* cannot drift from the pnpm this repo pins. The case below asserts both halves,
Expand Down Expand Up @@ -1508,7 +1513,7 @@ function fixtureSelfTest() {
const merge = runHook('stale');

// The fixture's OWN prerequisite, asserted before any verdict is read out of a
// gate's exit code: every case below spawns `pnpm -s` inside this directory, so
// gate's exit code: every case below spawns `pnpm --silent` inside this directory, so
// an unpinned fixture grades the registry's `latest` pnpm instead of the one
// this repository pins, and the failure lands on cases that have nothing to do
// with pnpm. ⛔ Not `=== rootPackageManager` on its own: were the root manifest
Expand Down
4 changes: 2 additions & 2 deletions scripts/git-merge-regen.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1194,7 +1194,7 @@ function reconcileOwnership() {
'a package command filters to its owner',
ownerRunCommand(DEFAULT_OWNER, 'gen:x') === `pnpm --filter ${DEFAULT_OWNER} gen:x`,
],
['a spawn asks for silence', ownerRunCommand(ROOT_OWNER, 'check:x', { silent: true }) === 'pnpm -s check:x'],
['a spawn asks for silence', ownerRunCommand(ROOT_OWNER, 'check:x', { silent: true }) === 'pnpm --silent check:x'],
];

const failures = cases.filter(([, ok]) => !ok).map(([name]) => name);
Expand Down Expand Up @@ -1715,7 +1715,7 @@ function endToEndWorktreeRefusal() {
const target = REGEN_ARTIFACTS[0].path;
const gateScript = REGEN_ARTIFACTS[0].check;

/* The stub gate, and the pin that keeps it honest. `pnpm -s` resolves its own
/* The stub gate, and the pin that keeps it honest. `pnpm --silent` resolves its own
* version from the manifest of the directory it runs in, so a fixture with no
* `packageManager` grades whatever Corepack resolves as `latest` instead of the
* pnpm this repository pins — the same trap `check-regen-pending.mjs`'s fixture
Expand Down
2 changes: 1 addition & 1 deletion scripts/pm/dispatch-gates.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9316,7 +9316,7 @@ export function governedReadCensus({ files = null, read = null } = {}) {
* quoted literal that `resolvePathExpression` refuses by construction, so
* admitting them would add a scan that cannot return a target: dead code that
* reads as coverage. Live specimens of the refused class in this tree, both
* shell-quoted: `pnpm -s ${script}` and `git rev-parse --show-toplevel`.
* shell-quoted: `pnpm --silent ${script}` and `git rev-parse --show-toplevel`.
*
* THE PROGRAM POSITION ONLY — argument 0, plus the elements of an argv ARRAY
* LITERAL in argument 1. That is where a program path is; an options object is
Expand Down
2 changes: 1 addition & 1 deletion scripts/pm/dispatch-gates.self-test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8728,7 +8728,7 @@ export function selfTest({ tier = 'full' } = {}) {
"const r1 = spawnSync(process.execPath, [join(ROOT, TOOL), '--self-test'], { stdio: 'inherit' });", // followed: argv array, component NAMED
"const r2 = execFileSync('node', [join(ROOT, 'scripts/invoked-as.mjs')]);", // followed: component written out
"const r3 = spawnSync('git', ['ls-files'], { cwd: ROOT });", // a program that is not in this tree
'const r4 = execSync(`pnpm -s ${script}`);', // shell form: a command STRING, never scanned
'const r4 = execSync(`pnpm --silent ${script}`);', // shell form: a command STRING, never scanned
"const r5 = spawnSync(process.execPath, [join(ROOT, 'package.json')]);", // tracked, but not program text
"const r6 = spawnSync(process.execPath, [join(ROOT, 'scripts/does-not-exist.mjs')]);", // resolves, untracked
"const r7 = spawnSync(process.execPath, [join(ROOT, 'scripts/fixture.mjs')]);", // itself: the identity key owns it
Expand Down
6 changes: 4 additions & 2 deletions scripts/regen-artifacts.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -957,11 +957,13 @@ export function ownerDir(owner, workspacePkgs) {
*
* @param {string} owner
* @param {string} script
* @param {{ silent?: boolean }} [options] `silent` adds `-s`, for a spawn rather than advice
* @param {{ silent?: boolean }} [options] `silent` adds `--silent`, for a spawn rather than
* advice — never `-s`, which a global pnpm 11+ `@pnpm/exe` frontend rejects before the
* pinned pnpm ever runs
* @returns {string}
*/
export function ownerRunCommand(owner, script, { silent = false } = {}) {
const s = silent ? ' -s' : '';
const s = silent ? ' --silent' : '';
return owner === ROOT_OWNER ? `pnpm${s} ${script}` : `pnpm${s} --filter ${owner} ${script}`;
}

Expand Down
Loading