@@ -195,19 +195,20 @@ def install_arduino_library_dependencies(library_names, on_behalf_of, already_in
195195 installed
196196end
197197
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 )
201201 # with all platform info, we can extract unique packages and their urls
202202 # 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 } "
204205
205206 # 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 ) } }
207208
208209 # set up all the board manager URLs.
209210 # 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
211212 unless all_urls . empty?
212213 assure_multiline ( "Setting board manager URLs" ) do
213214 @backend . board_manager_urls = all_urls
@@ -248,17 +249,25 @@ def handle_expectation_of_files(expectation_envvar, operation, filegroup_name, d
248249 end
249250
250251 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 )
251260 inform ( "Environment variable #{ expectation_envvar } is" ) { "(#{ ENV [ expectation_envvar ] . class } ) #{ ENV [ expectation_envvar ] } " }
252261 if ENV [ expectation_envvar ] . nil?
253262 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 ( )
256265 puts " To force an error in this case, set the environment variable #{ expectation_envvar } "
257266 true
258267 end
259268 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 ( )
262271 false
263272 end
264273 end
@@ -305,6 +314,49 @@ def perform_custom_initialization(_config)
305314 end
306315end
307316
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+ platform_architecture = Hash [ config . platform_info . map { |k , v | [ k , v [ :board ] . split ( ":" ) [ 1 ] ] } ]
339+ supported_platforms = platform_architecture . select { |_ , a | library_properties . architectures . include? ( a ) }
340+
341+ if config . is_default
342+ # completely ignore default config, opting for brute-force library matches
343+ # OTOH, we don't need to assure platforms because we defined them
344+ return inform_multiline ( "Default config, platforms matching architectures in library.properties" ) do
345+ supported_platforms . keys . each do |p |
346+ puts " #{ p } "
347+ end # this returns supported_platforms
348+ end
349+ end
350+
351+ desired_supported_platforms = supported_platforms . select { |p , _ | desired_platforms . include? ( p ) } . keys
352+ desired_supported_platforms . each { |p | assured_platform ( reason , p , config ) }
353+ inform_multiline ( "Configured platforms that match architectures in library.properties" ) do
354+ desired_supported_platforms . each do |p |
355+ puts " #{ p } "
356+ end # this returns supported_platforms
357+ end
358+ end
359+
308360# Unit test procedure
309361def perform_unit_tests ( cpp_library , file_config )
310362 if @cli_options [ :skip_unittests ]
@@ -314,7 +366,6 @@ def perform_unit_tests(cpp_library, file_config)
314366
315367 config = file_config . with_override_config ( @cli_options [ :ci_config ] )
316368 compilers = get_annotated_compilers ( config , cpp_library )
317- config . platforms_to_unittest . each_with_object ( { } ) { |p , acc | acc [ p ] = assured_platform ( "unittest" , p , config ) }
318369
319370 inform ( "Library conforms to Arduino library specification" ) { cpp_library . one_point_five? ? "1.5" : "1.0" }
320371
@@ -324,15 +375,20 @@ def perform_unit_tests(cpp_library, file_config)
324375 return
325376 end
326377
327- # Handle lack of platforms
328- if config . platforms_to_unittest . empty?
329- inform ( "Skipping unit tests" ) { "no platforms were requested" }
330- return
378+ # Get platforms, handle lack of them
379+ platforms = choose_platform_set ( config , "unittest" , config . platforms_to_unittest , cpp_library . library_properties )
380+ if platforms . empty?
381+ explain_and_exercise_envvar ( VAR_EXPECT_UNITTESTS , "unit tests" , "platforms and architectures" ) do
382+ puts " Configured platforms: #{ config . platforms_to_unittest } "
383+ puts " Configuration is default: #{ config . is_default } "
384+ arches = cpp_library . library_properties . nil? ? nil : cpp_library . library_properties . architectures
385+ puts " Architectures in library.properties: #{ arches } "
386+ end
331387 end
332388
333389 install_arduino_library_dependencies ( config . aux_libraries_for_unittest , "<unittest/libraries>" )
334390
335- config . platforms_to_unittest . each do |p |
391+ platforms . each do |p |
336392 config . allowable_unittest_files ( cpp_library . test_files ) . each do |unittest_path |
337393 unittest_name = unittest_path . basename . to_s
338394 compilers . each do |gcc_binary |
@@ -371,39 +427,34 @@ def perform_example_compilation_tests(cpp_library, config)
371427 aux_libraries = Set . new ( config . aux_libraries_for_build )
372428 # while collecting the platforms, ensure they're defined
373429
430+ # collect all aux libraries for installation at the same time
374431 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-
391- install_all_packages ( example_platform_info , board_package_url )
392- install_arduino_library_dependencies ( aux_libraries , "<compile/libraries>" )
393432
394- if config . platforms_to_build . empty?
395- inform ( "Skipping builds" ) { "no platforms were requested" }
396- return
397- elsif library_examples . empty?
433+ if library_examples . empty?
398434 handle_expectation_of_files ( VAR_EXPECT_EXAMPLES , "builds" , "examples" , "the examples directory" , cpp_library . examples_dir )
399435 return
400436 end
401437
402438 library_examples . each do |example_path |
439+ example_name = File . basename ( example_path )
403440 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 )
441+ platforms = choose_platform_set ( ovr_config , "library example" , ovr_config . platforms_to_build , cpp_library . library_properties )
442+
443+ if platforms . empty?
444+ explain_and_exercise_envvar ( VAR_EXPECT_EXAMPLES , "examples compilation" , "platforms and architectures" ) do
445+ puts " Configured platforms: #{ config . platforms_to_build } "
446+ puts " Configuration is default: #{ config . is_default } "
447+ arches = cpp_library . library_properties . nil? ? nil : cpp_library . library_properties . architectures
448+ puts " Architectures in library.properties: #{ arches } "
449+ end
450+ end
451+
452+ install_all_packages ( platforms , ovr_config )
453+
454+ platforms . each do |p |
455+ install_arduino_library_dependencies ( ovr_config . aux_libraries_for_build , "<compile/libraries>" )
456+
457+ board = ovr_config . platform_info [ p ] [ :board ]
407458 attempt ( "Compiling #{ example_name } for #{ board } " ) do
408459 ret = @backend . compile_sketch ( example_path , board )
409460 unless ret
0 commit comments