1010import shutil
1111import subprocess
1212import sys
13+ import time
1314from pathlib import Path
1415
1516
@@ -47,6 +48,11 @@ def detect_compose_cmd():
4748 sys .exit (1 )
4849
4950
51+ def fmt_elapsed (seconds ):
52+ m , s = divmod (int (seconds ), 60 )
53+ return f"{ m } m { s } s" if m else f"{ s } s"
54+
55+
5056def run (cmd , check = True ):
5157 return subprocess .run (cmd , check = check )
5258
@@ -248,49 +254,78 @@ def main():
248254 print ("Building Docker images and running builds..." )
249255 print (f"Services to build: { services } \n " )
250256
257+ total = len (services )
258+ build_start = time .time ()
259+
251260 # Step 1: Build Docker images in parallel (output suppressed to avoid interleaving)
252- print ("Step 1: Building Docker images..." )
253- procs = [
254- subprocess .Popen (
261+ print (f"Step 1: Building { total } Docker image(s)..." )
262+ img_start = time .time ()
263+ img_pending = {}
264+ for svc in services :
265+ proc = subprocess .Popen (
255266 compose + ["-f" , COMPOSE_FILE , "build" , svc ],
256267 stdout = subprocess .DEVNULL , stderr = subprocess .DEVNULL ,
257268 )
258- for svc in services
259- ]
260- for p in procs :
261- p .wait ()
262- print ("All Docker images built!\n " )
269+ img_pending [svc ] = (proc , time .time ())
270+ done = 0
271+ while img_pending :
272+ for svc , (proc , svc_start ) in list (img_pending .items ()):
273+ if proc .poll () is not None :
274+ done += 1
275+ print (f" [{ done } /{ total } ] Image ready: { svc } ({ fmt_elapsed (time .time () - svc_start )} )" )
276+ del img_pending [svc ]
277+ if img_pending :
278+ time .sleep (2 )
279+ print (f"All Docker images built! (took { fmt_elapsed (time .time () - img_start )} )\n " )
263280
264281 # Step 2: Run builds
282+ step2_start = time .time ()
265283 print ("Step 2: Running builds..." )
266284 if args .parallel :
267285 print (">>> Running builds in PARALLEL mode..." )
268- print (">>> WARNING: This will use significant CPU and RAM!\n " )
286+ print (f">>> WARNING: This will use significant CPU and RAM!" )
287+ print (f">>> Launching { total } build(s)...\n " )
269288
270- procs = {svc : run_build (compose , svc , background = True , evomaster = args .evomaster ) for svc in services }
271- print ("Waiting for all builds to complete..." )
289+ pending = {}
290+ for svc in services :
291+ proc = run_build (compose , svc , background = True , evomaster = args .evomaster )
292+ pending [svc ] = (proc , time .time ())
293+ print (f" [launched] { svc } " )
294+ print (f"\n Waiting for all { total } builds to complete...\n " )
272295
273296 failed = 0
274- for svc , proc in procs .items ():
275- code = proc .wait ()
276- if code != 0 :
277- print (f"ERROR: { svc } failed with exit code { code } " )
278- failed += 1
297+ done = 0
298+ while pending :
299+ for svc , (proc , svc_start ) in list (pending .items ()):
300+ code = proc .poll ()
301+ if code is not None :
302+ done += 1
303+ svc_elapsed = fmt_elapsed (time .time () - svc_start )
304+ if code != 0 :
305+ print (f" [{ done } /{ total } ] FAILED: { svc } (exit code { code } , { svc_elapsed } )" )
306+ failed += 1
307+ else :
308+ print (f" [{ done } /{ total } ] OK: { svc } ({ svc_elapsed } )" )
309+ del pending [svc ]
310+ if pending :
311+ time .sleep (2 )
279312
280313 if failed :
281314 print (f"\n ERROR: { failed } build(s) failed!" )
282315 sys .exit (1 )
283316
284- print ("\n All parallel builds completed successfully!\n " )
317+ print (f "\n All parallel builds completed successfully! (took { fmt_elapsed ( time . time () - step2_start ) } ) \n " )
285318 else :
286319 print (">>> Running builds in SEQUENTIAL mode...\n " )
287- for svc in services :
288- print (f">>> Building: { svc } " )
320+ for i , svc in enumerate (services , 1 ):
321+ print (f">>> [{ i } /{ total } ] Building: { svc } " )
322+ svc_start = time .time ()
289323 result = run_build (compose , svc , evomaster = args .evomaster )
324+ svc_elapsed = fmt_elapsed (time .time () - svc_start )
290325 if result .returncode != 0 :
291- print (f"\n ERROR: { svc } build failed!" )
326+ print (f"\n ERROR: { svc } build failed! (after { svc_elapsed } ) " )
292327 sys .exit (1 )
293- print ()
328+ print (f" Completed in { svc_elapsed } \n " )
294329
295330 if args .evomaster :
296331 copy_additional_files (compose )
@@ -300,9 +335,11 @@ def main():
300335 run (compose + ["-f" , COMPOSE_FILE , "down" ])
301336
302337 # Summary
338+ total_elapsed = fmt_elapsed (time .time () - build_start )
303339 print ()
304340 print ("Build Summary" )
305341 print (f"Builds executed: { len (services )} " )
342+ print (f"Total time: { total_elapsed } " )
306343 print ("Checking dist folder contents...\n " )
307344
308345 jar_count = count_jars ()
0 commit comments