3
3
import time
4
4
import os
5
5
import shutil
6
- from distutils .dir_util import copy_tree
7
6
import subprocess
8
7
import collections
8
+ from contextlib import contextmanager
9
9
10
10
# optional wall option cause build failed if has warnings
11
11
BUILD_WALL = False
@@ -248,6 +248,12 @@ def run_or_die(cmd, error):
248
248
249
249
################################ UF2 Utils.
250
250
251
+ def glob01 (pattern ):
252
+ result = glob .glob (pattern )
253
+ if len (result ) > 1 :
254
+ raise RuntimeError (f"Required pattern { pattern } to match at most 1 file, got { result } " )
255
+ return result [0 ] if result else None
256
+
251
257
def glob1 (pattern ):
252
258
result = glob .glob (pattern )
253
259
if len (result ) != 1 :
@@ -276,11 +282,23 @@ def generate_uf2(example_path):
276
282
"""
277
283
if not download_uf2_utils ():
278
284
return None
279
- cli_build_path = "build/*.*." + fqbn .split (':' )[2 ] + "/*.hex"
280
- input_file = glob1 (os .path .join (example_path , cli_build_path ))
281
- output_file = os .path .splitext (input_file )[0 ] + ".uf2"
285
+
286
+ cli_build_uf2_path = "build/*.*." + fqbn .split (':' )[2 ] + "/*.uf2"
287
+ uf2_input_file = glob01 (os .path .join (example_path , cli_build_uf2_path ))
288
+
289
+ # Some platforms, like rp2040, directly generate a uf2 file, so no need to do it ourselves
290
+ if uf2_input_file is not None :
291
+ output_file = os .path .splitext (uf2_input_file )[0 ] + ".uf2"
292
+ ColorPrint .print_pass (CHECK )
293
+ ColorPrint .print_info ("Used uf2 generated by arduino-cli" )
294
+ return output_file
295
+
296
+ # For other uf2-supporting platforms, we can generate it from a hex file
297
+ cli_build_hex_path = "build/*.*." + fqbn .split (':' )[2 ] + "/*.hex"
298
+ hex_input_file = glob1 (os .path .join (example_path , cli_build_hex_path ))
299
+ output_file = os .path .splitext (hex_input_file )[0 ] + ".uf2"
282
300
family_id = ALL_PLATFORMS [platform ][1 ]
283
- cmd = ['python3' , 'uf2conv.py' , input_file , '-c' , '-f' , family_id , '-o' , output_file ]
301
+ cmd = ['python3' , 'uf2conv.py' , hex_input_file , '-c' , '-f' , family_id , '-o' , output_file ]
284
302
proc = subprocess .Popen (cmd , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
285
303
r = proc .wait (timeout = 60 )
286
304
out = proc .stdout .read ()
@@ -311,6 +329,20 @@ def generate_uf2(example_path):
311
329
print ("Unknown platform: " , arg )
312
330
exit (- 1 )
313
331
332
+ @contextmanager
333
+ def group_output (title ):
334
+ sys .stdout .flush ()
335
+ sys .stderr .flush ()
336
+ print (f"::group::{ title } " )
337
+ try :
338
+ yield
339
+ finally :
340
+ sys .stdout .flush ()
341
+ sys .stderr .flush ()
342
+ print (f"::endgroup::" )
343
+ sys .stdout .flush ()
344
+
345
+
314
346
def test_examples_in_folder (folderpath ):
315
347
global success
316
348
for example in sorted (os .listdir (folderpath )):
@@ -366,7 +398,8 @@ def test_examples_in_folder(folderpath):
366
398
ColorPrint .print_pass (CHECK )
367
399
if err :
368
400
# also print out warning message
369
- ColorPrint .print_fail (err .decode ("utf-8" ))
401
+ with group_output (f"{ example } { fqbn } build output" ):
402
+ ColorPrint .print_fail (err .decode ("utf-8" ))
370
403
if os .path .exists (gen_file_name ):
371
404
if ALL_PLATFORMS [platform ][1 ] == None :
372
405
ColorPrint .print_info ("Platform does not support UF2 files, skipping..." )
@@ -383,8 +416,9 @@ def test_examples_in_folder(folderpath):
383
416
os .system ("ls -lR " + BUILD_DIR + "/build" )
384
417
else :
385
418
ColorPrint .print_fail (CROSS )
386
- ColorPrint .print_fail (out .decode ("utf-8" ))
387
- ColorPrint .print_fail (err .decode ("utf-8" ))
419
+ with group_output (f"{ example } { fqbn } built output" ):
420
+ ColorPrint .print_fail (out .decode ("utf-8" ))
421
+ ColorPrint .print_fail (err .decode ("utf-8" ))
388
422
success = 1
389
423
390
424
def test_examples_in_learningrepo (folderpath ):
0 commit comments