mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 17:37:40 +00:00
* refactor(startup): organize remaining lifecycle and service owners * fix(tests): bind quit mocks to concrete shutdown owners
88 lines
2.3 KiB
JavaScript
88 lines
2.3 KiB
JavaScript
import { spawn } from 'node:child_process'
|
|
import { writeFileSync } from 'node:fs'
|
|
import path from 'node:path'
|
|
|
|
const __dirname = import.meta.dirname
|
|
const grandchildPath = path.join(__dirname, 'electron-vite-dev-grandchild.mjs')
|
|
const pidFile = process.env.ORCA_DEV_WRAPPER_TEST_PID_FILE
|
|
const envFile = process.env.ORCA_DEV_WRAPPER_TEST_ENV_FILE
|
|
|
|
const grandchild = spawn(process.execPath, [grandchildPath], {
|
|
stdio: 'ignore'
|
|
})
|
|
|
|
let exiting = false
|
|
|
|
function killGrandchild(signal) {
|
|
if (!grandchild.pid) {
|
|
return
|
|
}
|
|
try {
|
|
process.kill(grandchild.pid, signal)
|
|
} catch (error) {
|
|
const code = error && typeof error === 'object' && 'code' in error ? error.code : null
|
|
if (code !== 'ESRCH') {
|
|
throw error
|
|
}
|
|
}
|
|
}
|
|
|
|
function exitAfterGrandchild(signal, code) {
|
|
if (exiting) {
|
|
return
|
|
}
|
|
exiting = true
|
|
killGrandchild(signal)
|
|
const forceTimer = setTimeout(() => {
|
|
killGrandchild('SIGKILL')
|
|
process.exit(code)
|
|
}, 1000)
|
|
grandchild.once('exit', () => {
|
|
clearTimeout(forceTimer)
|
|
process.exit(code)
|
|
})
|
|
}
|
|
|
|
process.once('SIGINT', () => {
|
|
exitAfterGrandchild('SIGINT', 130)
|
|
})
|
|
|
|
process.once('SIGTERM', () => {
|
|
exitAfterGrandchild('SIGTERM', 143)
|
|
})
|
|
|
|
if (!pidFile) {
|
|
throw new Error('ORCA_DEV_WRAPPER_TEST_PID_FILE is required')
|
|
}
|
|
|
|
// Record both PIDs so assertion failures before SIGINT cannot leak the wrapper or its child.
|
|
writeFileSync(pidFile, `${process.pid}\n${grandchild.pid ?? ''}\n`, 'utf8')
|
|
if (envFile) {
|
|
writeFileSync(
|
|
envFile,
|
|
JSON.stringify(
|
|
{
|
|
args: process.argv.slice(2),
|
|
label: process.env.ORCA_DEV_INSTANCE_LABEL ?? null,
|
|
branch: process.env.ORCA_DEV_BRANCH ?? null,
|
|
worktreeName: process.env.ORCA_DEV_WORKTREE_NAME ?? null,
|
|
repoRoot: process.env.ORCA_DEV_REPO_ROOT ?? null,
|
|
badgeLabel: process.env.ORCA_DEV_DOCK_BADGE_LABEL ?? null,
|
|
dockTitle: process.env.ORCA_DEV_DOCK_TITLE ?? null,
|
|
stableName: process.env.ORCA_DEV_STABLE_NAME ?? null,
|
|
electronExecPath: process.env.ELECTRON_EXEC_PATH ?? null
|
|
},
|
|
null,
|
|
2
|
|
),
|
|
'utf8'
|
|
)
|
|
}
|
|
// The wrapper detaches this process group; exit with it so a killed test run cannot orphan us.
|
|
const parentPid = process.ppid
|
|
setInterval(() => {
|
|
if (process.ppid !== parentPid) {
|
|
exitAfterGrandchild('SIGTERM', 143)
|
|
}
|
|
}, 1000)
|