mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 17:17:38 +00:00
lint:ast-grep and check-flaky-test-pattern-ratchet each parsed the whole tree. ast-grep-gates.mjs scans once; the lint gate re-runs ast-grep only on files with warning-or-error findings (ast-grep's own report and exit code), and the flaky ratchet counts test-* matches from the shared scan. Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
63 lines
2.4 KiB
JavaScript
63 lines
2.4 KiB
JavaScript
import { spawn } from 'node:child_process'
|
|
import { readdirSync } from 'node:fs'
|
|
import { availableParallelism } from 'node:os'
|
|
import path from 'node:path'
|
|
import process from 'node:process'
|
|
import { pathToFileURL } from 'node:url'
|
|
|
|
// Discover CI ratchets by filename; local lint keeps its separate explicit check list.
|
|
const RATCHET_SCRIPT = /^check-.+-ratchets?\.mjs$/
|
|
const RUN_ELSEWHERE = new Set([
|
|
// Needs the PR diff base; the cross-version-wire job runs it.
|
|
'check-runtime-launcher-protocol-ratchet.mjs',
|
|
// Its own background preflight step, so it overlaps lint and typecheck.
|
|
'check-main-sync-spawn-ratchet.mjs',
|
|
// ast-grep-gates.mjs checks it from the ast-grep lint scan instead of scanning again.
|
|
'check-flaky-test-pattern-ratchet.mjs'
|
|
])
|
|
|
|
export function listRatchetScripts(scriptsDir) {
|
|
return readdirSync(scriptsDir)
|
|
.filter((name) => RATCHET_SCRIPT.test(name) && !RUN_ELSEWHERE.has(name))
|
|
.sort()
|
|
}
|
|
|
|
function runRatchet(scriptsDir, name, root) {
|
|
return new Promise((resolve) => {
|
|
let output = ''
|
|
const child = spawn(process.execPath, [path.join(scriptsDir, name)], { cwd: root })
|
|
child.stdout.on('data', (chunk) => (output += chunk))
|
|
child.stderr.on('data', (chunk) => (output += chunk))
|
|
child.on('error', (error) => resolve({ name, ok: false, output: `${output}${error.message}` }))
|
|
child.on('close', (code) => resolve({ name, ok: code === 0, output }))
|
|
})
|
|
}
|
|
|
|
// Each ratchet is a single-threaded scan; half the cores leaves room for the overlapping typecheck.
|
|
async function main(root) {
|
|
const scriptsDir = path.join(root, 'config', 'scripts')
|
|
const pending = listRatchetScripts(scriptsDir)
|
|
const failed = []
|
|
await Promise.all(
|
|
Array.from({ length: Math.max(2, Math.floor(availableParallelism() / 2)) }, async () => {
|
|
while (pending.length > 0) {
|
|
const result = await runRatchet(scriptsDir, pending.shift(), root)
|
|
// Whole per-script blocks, so concurrent ratchets never interleave their lines.
|
|
process.stdout.write(`\n▶ ${result.name}\n${result.output}`)
|
|
if (!result.ok) {
|
|
failed.push(result.name)
|
|
}
|
|
}
|
|
})
|
|
)
|
|
if (failed.length > 0) {
|
|
console.error(`\nFailed ratchets: ${failed.sort().join(', ')}`)
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
process.exitCode = await main(process.cwd())
|
|
}
|