repo-tools: Add _handle stub preload for file-backed stdout
Add a --require preload that stubs process.stdout._handle when stdout is a SyncWriteStream (file-backed). Some CLI code accesses _handle.setBlocking directly and would crash without the stub. Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Made-with: Cursor
This commit is contained in:
@@ -15,10 +15,42 @@
|
||||
*/
|
||||
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import { openSync, closeSync, readFileSync, unlinkSync } from 'node:fs';
|
||||
import {
|
||||
openSync,
|
||||
closeSync,
|
||||
readFileSync,
|
||||
unlinkSync,
|
||||
writeFileSync,
|
||||
} from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
|
||||
// Preload script that stubs process.stdout._handle when stdout is backed by a
|
||||
// file (SyncWriteStream). Some CLI code accesses _handle.setBlocking directly
|
||||
// and would crash without this.
|
||||
const preloadContent = `
|
||||
if (process.stdout && !process.stdout._handle) {
|
||||
process.stdout._handle = { setBlocking() {} };
|
||||
}
|
||||
`;
|
||||
|
||||
let preloadPath: string | undefined;
|
||||
|
||||
function getPreloadPath() {
|
||||
if (!preloadPath) {
|
||||
preloadPath = join(tmpdir(), `backstage-stdout-preload-${process.pid}.cjs`);
|
||||
writeFileSync(preloadPath, preloadContent);
|
||||
process.on('exit', () => {
|
||||
try {
|
||||
unlinkSync(preloadPath!);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
});
|
||||
}
|
||||
return preloadPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect stdout to a temp file so that Node.js creates a SyncWriteStream
|
||||
* (synchronous writes) in the child instead of an async pipe stream. This
|
||||
@@ -35,11 +67,15 @@ export function createBinRunner(cwd: string, path: string) {
|
||||
const outFd = openSync(outPath, 'w');
|
||||
|
||||
try {
|
||||
const result = spawnSync('node', args, {
|
||||
cwd,
|
||||
stdio: ['ignore', outFd, 'pipe'],
|
||||
maxBuffer: 10 * 1024 * 1024,
|
||||
});
|
||||
const result = spawnSync(
|
||||
'node',
|
||||
['--require', getPreloadPath(), ...args],
|
||||
{
|
||||
cwd,
|
||||
stdio: ['ignore', outFd, 'pipe'],
|
||||
maxBuffer: 10 * 1024 * 1024,
|
||||
},
|
||||
);
|
||||
|
||||
closeSync(outFd);
|
||||
const stdout = readFileSync(outPath, 'utf8');
|
||||
|
||||
Reference in New Issue
Block a user