| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- import { spawnSync } from 'node:child_process'
- import { resolve } from 'node:path'
- import { fileURLToPath } from 'node:url'
- const oxlintCli = fileURLToPath(new URL('../node_modules/oxlint/bin/oxlint', import.meta.url))
- const MAX_CAPTURED_OUTPUT_BYTES = 64 * 1024 * 1024
- const FIX_FLAGS = new Set(['--fix', '--fix-dangerously', '--fix-suggestions'])
- function isFixInvocation(args: readonly string[]): boolean {
- return args.some(arg => FIX_FLAGS.has(arg))
- }
- /** Complete Oxlint child-process arguments and environment. */
- export interface OxlintInvocation {
- readonly args: readonly string[]
- readonly env: NodeJS.ProcessEnv
- }
- /**
- * Apply the repository worker bound to both Oxlint backends.
- * @param args - Oxlint CLI arguments requested by the caller.
- * @param env - Environment inherited by the Oxlint process.
- * @returns the complete CLI arguments and child environment.
- */
- export function resolveOxlintInvocation(args: readonly string[], env: NodeJS.ProcessEnv): OxlintInvocation {
- const raw = env.DSH_OXLINT_THREADS
- if (raw === undefined || raw === '') return { args: [...args], env: { ...env } }
- const parsed = Number.parseInt(raw, 10)
- if (!Number.isSafeInteger(parsed) || parsed < 1 || String(parsed) !== raw) {
- throw new Error(`run-oxlint: DSH_OXLINT_THREADS must be a positive integer, got ${JSON.stringify(raw)}.`)
- }
- if (args.some(arg => arg === '--threads' || arg.startsWith('--threads='))) {
- throw new Error('run-oxlint: use DSH_OXLINT_THREADS instead of passing --threads directly.')
- }
- return {
- args: [...args, `--threads=${raw}`],
- env: { ...env, GOMAXPROCS: raw },
- }
- }
- function completeFrom(result: { readonly signal: NodeJS.Signals | null; readonly status: number | null }): void {
- if (result.signal !== null) {
- process.kill(process.pid, result.signal)
- return
- }
- process.exitCode = result.status ?? 1
- }
- function main(): void {
- const invocation = resolveOxlintInvocation(process.argv.slice(2), process.env)
- if (!isFixInvocation(invocation.args)) {
- const result = spawnSync(process.execPath, [oxlintCli, ...invocation.args], {
- env: invocation.env,
- stdio: 'inherit',
- })
- if (result.error !== undefined) throw result.error
- completeFrom(result)
- return
- }
- const first = spawnSync(process.execPath, [oxlintCli, ...invocation.args], {
- encoding: 'utf8',
- env: invocation.env,
- maxBuffer: MAX_CAPTURED_OUTPUT_BYTES,
- })
- if (first.error !== undefined) throw first.error
- if (first.signal !== null) {
- completeFrom(first)
- return
- }
- if (first.status === 0) {
- process.stdout.write(first.stdout)
- process.stderr.write(first.stderr)
- process.exitCode = 0
- return
- }
- // Overlapping JS-plugin fixes can expose one more fixable diagnostic after the first pass.
- const second = spawnSync(process.execPath, [oxlintCli, ...invocation.args], {
- env: invocation.env,
- stdio: 'inherit',
- })
- if (second.error !== undefined) throw second.error
- completeFrom(second)
- }
- const entrypoint = process.argv[1]
- if (entrypoint !== undefined && resolve(entrypoint) === fileURLToPath(import.meta.url)) main()
|