mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-09 01:16:15 -08:00
pnpm skips Electron's postinstall (electron is deliberately not in
onlyBuiltDependencies), so the binary is downloaded lazily on the first
require('electron'). Since Tier A projects run concurrently (#1701),
several electron-backend and database specs resolve and exec it at the
same time; one process execs it while another is still extracting it
and fails with `spawnSync .../electron ETXTBSY`.
tools/testing/ensure-electron-binary.mjs downloads the binary once and
fails unless it runs under ELECTRON_RUN_AS_NODE and reports the pinned
version. The unit job runs it right after pnpm install, coverage:unit:ci
runs it first for local runs, and the performance journeys job runs it
before its ldd check, which passed vacuously while no binary existed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
63 lines
2.1 KiB
JavaScript
63 lines
2.1 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
// Downloads the Electron binary once and proves it runs, before anything
|
|
// spawns it concurrently.
|
|
//
|
|
// pnpm does not run Electron's postinstall (it is not in
|
|
// `onlyBuiltDependencies`), so `pnpm install` leaves no binary behind and
|
|
// `require('electron')` downloads and extracts it on first use. Unit specs
|
|
// that execute SQLite code under `ELECTRON_RUN_AS_NODE` resolve it that way,
|
|
// and Tier A projects and Jest workers run in parallel: one process can exec
|
|
// the binary while another is still extracting it (ETXTBSY on Linux, clobbered
|
|
// framework symlinks on macOS). Running this first leaves nothing to download.
|
|
//
|
|
// Usage: node tools/testing/ensure-electron-binary.mjs
|
|
|
|
import { execFileSync } from 'node:child_process';
|
|
import { createRequire } from 'node:module';
|
|
import process from 'node:process';
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const { version } = require('electron/package.json');
|
|
|
|
let electronPath;
|
|
try {
|
|
electronPath = require('electron');
|
|
} catch (error) {
|
|
console.error(
|
|
`Electron ${version} binary download failed: ${error.message}`
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
let reported;
|
|
try {
|
|
reported = execFileSync(
|
|
electronPath,
|
|
['-e', 'process.stdout.write(process.versions.electron)'],
|
|
{
|
|
encoding: 'utf8',
|
|
// The child's stderr (e.g. a dyld or loader error) goes straight
|
|
// to the log instead of being repeated in the message below.
|
|
stdio: ['ignore', 'pipe', 'inherit'],
|
|
env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' },
|
|
timeout: 60_000,
|
|
}
|
|
).trim();
|
|
} catch (error) {
|
|
console.error(
|
|
`Electron binary at ${electronPath} does not run (${error.code ?? `exit ${error.status}`}). ` +
|
|
'If an interrupted download left a partial copy, delete node_modules/electron/dist and path.txt, then rerun.'
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
if (reported !== version) {
|
|
console.error(
|
|
`Electron binary at ${electronPath} reports ${reported || 'no version'}, expected ${version}.`
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log(`Electron ${version} binary ready at ${electronPath}`);
|