@@ -27,6 +27,7 @@ import {
2727 updateTask ,
2828 createTaskMetrics ,
2929} from "@benchmark/db"
30+ import { inChunksOf } from "@benchmark/lib"
3031import { IpcServer , IpcClient } from "@benchmark/ipc"
3132
3233import { __dirname , extensionDevelopmentPath , exercisesPath } from "./paths.js"
@@ -90,54 +91,30 @@ const run = async (toolbox: GluegunToolbox) => {
9091 throw new Error ( "No tasks found." )
9192 }
9293
93- let currentTask = tasks [ 0 ]
94-
9594 const server = new IpcServer ( run . socketPath , ( ) => { } )
9695 server . listen ( )
9796
9897 server . on ( IpcMessageType . Connect , ( clientId ) => {
9998 server . send ( clientId , {
10099 type : IpcMessageType . TaskEvent ,
101100 origin : IpcOrigin . Server ,
102- data : { eventName : RooCodeEventName . Connect , taskId : currentTask . id } ,
101+ // TODO: Broacast the set of running tasks.
102+ data : { eventName : RooCodeEventName . Connect , taskId : - 1 } ,
103103 } )
104104 } )
105105
106- for ( const task of tasks ) {
107- currentTask = task
108-
109- await runExercise ( { run, task, server } )
110-
111- const cmd = testCommands [ task . language ]
112- const exercisePath = path . resolve ( exercisesPath , task . language , task . exercise )
113- const cwd = cmd . cwd ? path . resolve ( exercisePath , cmd . cwd ) : exercisePath
114- const commands = cmd . commands . map ( ( cs ) => parseCommandString ( cs ) )
115-
116- let passed = true
106+ const chunks = inChunksOf ( tasks , 2 )
117107
118- for ( const command of commands ) {
119- const controller = new AbortController ( )
120- const cancelSignal = controller . signal
121- const timeout = setTimeout ( ( ) => controller . abort ( ) , cmd . timeout ?? 15_000 )
108+ for ( const chunk of chunks ) {
109+ await Promise . all (
110+ chunk . map ( async ( task ) => {
111+ const runSucceeded = await runExercise ( { run, task, server } )
112+ const passed = runSucceeded ? await runUnitTest ( { task } ) : false
113+ await updateTask ( task . id , { passed } )
114+ } ) ,
115+ )
122116
123- try {
124- const result = await execa ( { cwd, shell : true , reject : false , cancelSignal } ) `${ command } `
125- // console.log('[cli#run] execa result =', { ...result, cwd, command })
126-
127- clearTimeout ( timeout )
128-
129- if ( result . failed ) {
130- passed = false
131- break
132- }
133- } catch ( error ) {
134- console . log ( "[cli#run] execa error =" , error )
135- passed = false
136- break
137- }
138- }
139-
140- await updateTask ( task . id , { passed } )
117+ break
141118 }
142119
143120 const result = await finishRun ( run . id )
@@ -155,8 +132,8 @@ const runExercise = async ({ run, task, server }: { run: Run; task: Task; server
155132 const prompt = fs . readFileSync ( path . resolve ( exercisesPath , `prompts/${ language } .md` ) , "utf-8" )
156133
157134 const dirname = path . dirname ( run . socketPath )
158- const basename = path . basename ( run . socketPath , ". sock" )
159- const taskSocketPath = path . resolve ( dirname , ` ${ dirname } / ${ basename } - ${ task . id } .sock` )
135+ const taskSocketPath = path . resolve ( dirname , ` ${ dirname } /task- ${ task . id } . sock` )
136+
160137 await execa ( {
161138 env : { ROO_CODE_IPC_SOCKET_PATH : taskSocketPath } ,
162139 } ) `code -n ${ path . resolve ( exercisesPath , language , exercise ) } `
@@ -179,7 +156,7 @@ const runExercise = async ({ run, task, server }: { run: Run; task: Task; server
179156 let isTaskFinished = false
180157
181158 client . on ( IpcMessageType . Disconnect , ( ) => {
182- console . log ( " disconnect" )
159+ console . log ( `[cli#runExercise | ${ language } / ${ exercise } ] disconnect` )
183160 isTaskFinished = true
184161 } )
185162
@@ -202,7 +179,7 @@ const runExercise = async ({ run, task, server }: { run: Run; task: Task; server
202179 } )
203180
204181 if ( ! ignoreEvents . includes ( eventName ) ) {
205- console . log ( `[cli#runExercise] taskEvent -> ${ eventName } ` )
182+ console . log ( `[cli#runExercise | ${ language } / ${ exercise } ] taskEvent -> ${ eventName } ` )
206183 }
207184
208185 // if (eventName === RooCodeEventName.Message) {
@@ -215,6 +192,7 @@ const runExercise = async ({ run, task, server }: { run: Run; task: Task; server
215192
216193 if ( eventName === RooCodeEventName . TaskStarted ) {
217194 taskStartedAt = Date . now ( )
195+ await updateTask ( task . id , { startedAt : new Date ( ) } )
218196 }
219197
220198 if ( eventName === RooCodeEventName . TaskCompleted ) {
@@ -233,7 +211,7 @@ const runExercise = async ({ run, task, server }: { run: Run; task: Task; server
233211 cacheReads : totalCacheReads ?? 0 ,
234212 } )
235213
236- await updateTask ( task . id , { taskMetricsId : taskMetrics . id } )
214+ await updateTask ( task . id , { taskMetricsId : taskMetrics . id , finishedAt : new Date ( ) } )
237215 isTaskFinished = true
238216 }
239217
@@ -242,7 +220,7 @@ const runExercise = async ({ run, task, server }: { run: Run; task: Task; server
242220 }
243221 } )
244222
245- console . log ( `[cli#runExercise] StartNewTask -> ${ language } / ${ exercise } ` )
223+ console . log ( `[cli#runExercise | ${ language } / ${ exercise } ] StartNewTask ( ${ taskSocketPath } ) ` )
246224
247225 client . sendMessage ( {
248226 type : IpcMessageType . TaskCommand ,
@@ -273,6 +251,39 @@ const runExercise = async ({ run, task, server }: { run: Run; task: Task; server
273251 }
274252}
275253
254+ const runUnitTest = async ( { task } : { task : Task } ) => {
255+ const cmd = testCommands [ task . language ]
256+ const exercisePath = path . resolve ( exercisesPath , task . language , task . exercise )
257+ const cwd = cmd . cwd ? path . resolve ( exercisePath , cmd . cwd ) : exercisePath
258+ const commands = cmd . commands . map ( ( cs ) => parseCommandString ( cs ) )
259+
260+ let passed = true
261+
262+ for ( const command of commands ) {
263+ const controller = new AbortController ( )
264+ const cancelSignal = controller . signal
265+ const timeout = setTimeout ( ( ) => controller . abort ( ) , cmd . timeout ?? 15_000 )
266+
267+ try {
268+ const result = await execa ( { cwd, shell : true , reject : false , cancelSignal } ) `${ command } `
269+ // console.log('[cli#run] execa result =', { ...result, cwd, command })
270+
271+ clearTimeout ( timeout )
272+
273+ if ( result . failed ) {
274+ passed = false
275+ break
276+ }
277+ } catch ( error ) {
278+ console . log ( "[cli#run] execa error =" , error )
279+ passed = false
280+ break
281+ }
282+ }
283+
284+ return passed
285+ }
286+
276287const askLanguage = async ( prompt : GluegunPrompt ) => {
277288 const { language } = await prompt . ask < { language : ExerciseLanguage } > ( {
278289 type : "select" ,
0 commit comments