1- import { execFileSync , spawn } from 'node:child_process'
1+ import { execFileSync } from 'node:child_process'
22import { createHash } from 'node:crypto'
33import { existsSync , mkdirSync , readFileSync , writeFileSync } from 'node:fs'
44import path from 'node:path'
55import { parseArgs } from 'node:util'
6+ import { runProcess } from '#design-diff/process'
67import type { Report } from '#design-diff/types'
78
89interface Comparison {
@@ -150,10 +151,11 @@ export async function benchmark(args = process.argv.slice(2)): Promise<void> {
150151 const started = performance . now ( )
151152 const env = { ...process . env }
152153 for ( const key of [ 'DESIGN_DIFF_PR' , 'DESIGN_DIFF_ENGINE_SHA' , 'HEAD_SHA' ] ) delete env [ key ]
153- const timeArgs = process . platform === 'darwin' ? [ '-l' ] : [ '-v' ]
154- const proc = spawn (
155- '/usr/bin/time' ,
154+ const metricsFile = ` ${ stem } .time.txt`
155+ const timeArgs = process . platform === 'darwin' ? [ '-l' ] : [ '-v' , '-o' , metricsFile ]
156+ const execution = await runProcess (
156157 [
158+ '/usr/bin/time' ,
157159 ...timeArgs ,
158160 process . execPath ,
159161 '--no-env-file' ,
@@ -165,22 +167,20 @@ export async function benchmark(args = process.argv.slice(2)): Promise<void> {
165167 '--output' ,
166168 reportFile ,
167169 ] ,
168- { cwd : engine , env, stdio : [ 'ignore' , 'ignore' , 'pipe' ] , detached : true }
170+ engine ,
171+ env
169172 )
170- let metrics = ''
171- proc . stderr . on ( 'data' , ( chunk : Buffer ) => {
172- if ( metrics . length < 65536 ) metrics += chunk . toString ( )
173- } )
174- const timeout = setTimeout (
175- ( ) => {
176- if ( proc . pid ) process . kill ( - proc . pid , 'SIGKILL' )
177- } ,
178- 15 * 60 * 1000
179- )
180- result . exitCode = await new Promise < number | null > ( ( resolve , reject ) => {
181- proc . on ( 'error' , reject )
182- proc . on ( 'close' , resolve )
183- } ) . finally ( ( ) => clearTimeout ( timeout ) )
173+ result . exitCode = execution . exitCode
174+ const metrics =
175+ process . platform === 'linux' && existsSync ( metricsFile )
176+ ? readFileSync ( metricsFile , 'utf8' )
177+ : execution . stderr
178+ if ( execution . exitCode !== 0 || execution . timedOut )
179+ writeFileSync (
180+ `${ stem } .stderr.txt` ,
181+ execution . stderr + ( execution . truncated ? '\n[stderr truncated at 65536 bytes]\n' : '' ) ,
182+ { mode : 0o600 }
183+ )
184184 result . seconds = Math . round ( ( performance . now ( ) - started ) / 10 ) / 100
185185 const rss =
186186 process . platform === 'darwin'
@@ -189,6 +189,7 @@ export async function benchmark(args = process.argv.slice(2)): Promise<void> {
189189 result . peakMemoryBytes = rss
190190 ? Number ( rss [ 1 ] ) * ( process . platform === 'darwin' ? 1 : 1024 )
191191 : null
192+ if ( execution . timedOut ) throw new Error ( 'Analysis deadline exceeded' )
192193 if ( ! existsSync ( reportFile ) ) throw new Error ( 'Engine did not produce a report' )
193194 const bytes = readFileSync ( reportFile )
194195 const report = JSON . parse ( bytes . toString ( ) ) as Report
0 commit comments