@@ -195,19 +195,20 @@ def install_arduino_library_dependencies(library_names, on_behalf_of, already_in
195
195
installed
196
196
end
197
197
198
- # @param example_platform_info [Hash] mapping of platform name to package information
199
- # @param board_package_url [Hash] mapping of package name to URL
200
- def install_all_packages ( example_platform_info , board_package_url )
198
+ # @param platforms [Array<String>] list of platforms to consider
199
+ # @param specific_config [CIConfig] configuration to use
200
+ def install_all_packages ( platforms , specific_config )
201
201
# with all platform info, we can extract unique packages and their urls
202
202
# do that, set the URLs, and download the packages
203
- all_packages = example_platform_info . values . map { |v | v [ :package ] } . uniq . reject ( &:nil? )
203
+ all_packages = specific_config . platform_info . select { |p , _ | platforms . include? ( p ) } . values . map { |v | v [ :package ] } . compact . uniq
204
+ puts "all_packages: #{ all_packages } "
204
205
205
206
# make sure any non-builtin package has a URL defined
206
- all_packages . each { |p | assure ( "Board package #{ p } has a defined URL" ) { board_package_url [ p ] } }
207
+ all_packages . each { |p | assure ( "Board package #{ p } has a defined URL" ) { specific_config . package_url ( p ) } }
207
208
208
209
# set up all the board manager URLs.
209
210
# we can safely reject nils now, they would be for the builtins
210
- all_urls = all_packages . map { |p | board_package_url [ p ] } . uniq . reject ( & :nil? )
211
+ all_urls = all_packages . map { |p | specific_config . package_url ( p ) } . compact . uniq
211
212
unless all_urls . empty?
212
213
assure_multiline ( "Setting board manager URLs" ) do
213
214
@backend . board_manager_urls = all_urls
@@ -248,17 +249,25 @@ def handle_expectation_of_files(expectation_envvar, operation, filegroup_name, d
248
249
end
249
250
250
251
inform ( problem ) { dir_path }
252
+ explain_and_exercise_envvar ( expectation_envvar , operation , "contents of #{ dir_desc } " ) { display_files ( dir ) }
253
+ end
254
+
255
+ # @param expectation_envvar [String] the name of the env var to check
256
+ # @param operation [String] a description of what operation we might be skipping
257
+ # @param block_desc [String] a description of what information will be dumped to assist the user
258
+ # @param block [Proc] a function that dumps information
259
+ def explain_and_exercise_envvar ( expectation_envvar , operation , block_desc , &block )
251
260
inform ( "Environment variable #{ expectation_envvar } is" ) { "(#{ ENV [ expectation_envvar ] . class } ) #{ ENV [ expectation_envvar ] } " }
252
261
if ENV [ expectation_envvar ] . nil?
253
262
inform_multiline ( "Skipping #{ operation } " ) do
254
- puts " In case that's an error, this is what was found in the #{ dir_desc } :"
255
- display_files ( dir )
263
+ puts " In case that's an error, displaying #{ block_desc } :"
264
+ block . call
256
265
puts " To force an error in this case, set the environment variable #{ expectation_envvar } "
257
266
true
258
267
end
259
268
else
260
- assure_multiline ( "Dumping project's #{ dir_desc } before exit" ) do
261
- display_files ( dir )
269
+ assure_multiline ( "Displaying #{ block_desc } before exit" ) do
270
+ block . call
262
271
false
263
272
end
264
273
end
@@ -305,6 +314,55 @@ def perform_custom_initialization(_config)
305
314
end
306
315
end
307
316
317
+ # Auto-select some platforms to test based on the information available
318
+ #
319
+ # Top choice is always library.properties -- otherwise use the default.
320
+ # But filter that through any non-default config
321
+ #
322
+ # @param config [CIConfig] the overridden config object
323
+ # @param reason [String] description of why we might use this platform (i.e. unittest or compilation)
324
+ # @param desired_platforms [Array<String>] the platform names specified
325
+ # @param library_properties [Hash] the library properties defined by the library
326
+ # @return [Array<String>] platforms to use
327
+ def choose_platform_set ( config , reason , desired_platforms , library_properties )
328
+
329
+ # if there are no properties or no architectures, defer entirely to desired platforms
330
+ if library_properties . nil? || library_properties . architectures . nil? || library_properties . architectures . empty?
331
+ # verify that all platforms exist
332
+ desired_platforms . each { |p | assured_platform ( reason , p , config ) }
333
+ return inform_multiline ( "No architectures listed in library.properties, using configured platforms" ) do
334
+ desired_platforms . each { |p | puts " #{ p } " } # this returns desired_platforms
335
+ end
336
+ end
337
+
338
+ if library_properties . architectures . include? ( "*" )
339
+ return inform_multiline ( "Wildcard architecture in library.properties, using configured platforms" ) do
340
+ desired_platforms . each { |p | puts " #{ p } " } # this returns desired_platforms
341
+ end
342
+ end
343
+
344
+ platform_architecture = config . platform_info . transform_values { |v | v [ :board ] . split ( ":" ) [ 1 ] }
345
+ supported_platforms = platform_architecture . select { |_ , a | library_properties . architectures . include? ( a ) }
346
+
347
+ if config . is_default
348
+ # completely ignore default config, opting for brute-force library matches
349
+ # OTOH, we don't need to assure platforms because we defined them
350
+ return inform_multiline ( "Default config, platforms matching architectures in library.properties" ) do
351
+ supported_platforms . each_key do |p |
352
+ puts " #{ p } "
353
+ end # this returns supported_platforms
354
+ end
355
+ end
356
+
357
+ desired_supported_platforms = supported_platforms . select { |p , _ | desired_platforms . include? ( p ) } . keys
358
+ desired_supported_platforms . each { |p | assured_platform ( reason , p , config ) }
359
+ inform_multiline ( "Configured platforms that match architectures in library.properties" ) do
360
+ desired_supported_platforms . each do |p |
361
+ puts " #{ p } "
362
+ end # this returns supported_platforms
363
+ end
364
+ end
365
+
308
366
# Unit test procedure
309
367
def perform_unit_tests ( cpp_library , file_config )
310
368
if @cli_options [ :skip_unittests ]
@@ -314,7 +372,6 @@ def perform_unit_tests(cpp_library, file_config)
314
372
315
373
config = file_config . with_override_config ( @cli_options [ :ci_config ] )
316
374
compilers = get_annotated_compilers ( config , cpp_library )
317
- config . platforms_to_unittest . each_with_object ( { } ) { |p , acc | acc [ p ] = assured_platform ( "unittest" , p , config ) }
318
375
319
376
inform ( "Library conforms to Arduino library specification" ) { cpp_library . one_point_five? ? "1.5" : "1.0" }
320
377
@@ -324,15 +381,20 @@ def perform_unit_tests(cpp_library, file_config)
324
381
return
325
382
end
326
383
327
- # Handle lack of platforms
328
- if config . platforms_to_unittest . empty?
329
- inform ( "Skipping unit tests" ) { "no platforms were requested" }
330
- return
384
+ # Get platforms, handle lack of them
385
+ platforms = choose_platform_set ( config , "unittest" , config . platforms_to_unittest , cpp_library . library_properties )
386
+ if platforms . empty?
387
+ explain_and_exercise_envvar ( VAR_EXPECT_UNITTESTS , "unit tests" , "platforms and architectures" ) do
388
+ puts " Configured platforms: #{ config . platforms_to_unittest } "
389
+ puts " Configuration is default: #{ config . is_default } "
390
+ arches = cpp_library . library_properties . nil? ? nil : cpp_library . library_properties . architectures
391
+ puts " Architectures in library.properties: #{ arches } "
392
+ end
331
393
end
332
394
333
395
install_arduino_library_dependencies ( config . aux_libraries_for_unittest , "<unittest/libraries>" )
334
396
335
- config . platforms_to_unittest . each do |p |
397
+ platforms . each do |p |
336
398
config . allowable_unittest_files ( cpp_library . test_files ) . each do |unittest_path |
337
399
unittest_name = unittest_path . basename . to_s
338
400
compilers . each do |gcc_binary |
@@ -363,47 +425,33 @@ def perform_example_compilation_tests(cpp_library, config)
363
425
return
364
426
end
365
427
366
- # gather up all required boards for compilation so we can install them up front.
367
- # start with the "platforms to unittest" and add the examples
368
- # while we're doing that, get the aux libraries as well
369
- example_platform_info = { }
370
- board_package_url = { }
371
- aux_libraries = Set . new ( config . aux_libraries_for_build )
372
- # while collecting the platforms, ensure they're defined
373
-
374
428
library_examples = cpp_library . example_sketches
375
- library_examples . each do |path |
376
- ovr_config = config . from_example ( path )
377
- ovr_config . platforms_to_build . each do |platform |
378
- # assure the platform if we haven't already
379
- next if example_platform_info . key? ( platform )
380
-
381
- platform_info = assured_platform ( "library example" , platform , config )
382
- next if platform_info . nil?
383
-
384
- example_platform_info [ platform ] = platform_info
385
- package = platform_info [ :package ]
386
- board_package_url [ package ] = ovr_config . package_url ( package )
387
- end
388
- aux_libraries . merge ( ovr_config . aux_libraries_for_build )
389
- end
390
429
391
- install_all_packages ( example_platform_info , board_package_url )
392
- install_arduino_library_dependencies ( aux_libraries , "<compile/libraries>" )
393
-
394
- if config . platforms_to_build . empty?
395
- inform ( "Skipping builds" ) { "no platforms were requested" }
396
- return
397
- elsif library_examples . empty?
430
+ if library_examples . empty?
398
431
handle_expectation_of_files ( VAR_EXPECT_EXAMPLES , "builds" , "examples" , "the examples directory" , cpp_library . examples_dir )
399
432
return
400
433
end
401
434
402
435
library_examples . each do |example_path |
436
+ example_name = File . basename ( example_path )
403
437
ovr_config = config . from_example ( example_path )
404
- ovr_config . platforms_to_build . each do |p |
405
- board = example_platform_info [ p ] [ :board ]
406
- example_name = File . basename ( example_path )
438
+ platforms = choose_platform_set ( ovr_config , "library example" , ovr_config . platforms_to_build , cpp_library . library_properties )
439
+
440
+ if platforms . empty?
441
+ explain_and_exercise_envvar ( VAR_EXPECT_EXAMPLES , "examples compilation" , "platforms and architectures" ) do
442
+ puts " Configured platforms: #{ config . platforms_to_build } "
443
+ puts " Configuration is default: #{ config . is_default } "
444
+ arches = cpp_library . library_properties . nil? ? nil : cpp_library . library_properties . architectures
445
+ puts " Architectures in library.properties: #{ arches } "
446
+ end
447
+ end
448
+
449
+ install_all_packages ( platforms , ovr_config )
450
+
451
+ platforms . each do |p |
452
+ install_arduino_library_dependencies ( ovr_config . aux_libraries_for_build , "<compile/libraries>" )
453
+
454
+ board = ovr_config . platform_info [ p ] [ :board ]
407
455
attempt ( "Compiling #{ example_name } for #{ board } " ) do
408
456
ret = @backend . compile_sketch ( example_path , board )
409
457
unless ret
0 commit comments