Skip to content

Commit 9a62f7e

Browse files
committed
Consider library.properties when doing default iteration
1 parent d6fb3a1 commit 9a62f7e

File tree

2 files changed

+93
-41
lines changed

2 files changed

+93
-41
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2323
- `assertEqual()` and `assertNotEqual()` use actual `==` and `!=` -- they no longer require a type to be totally ordered just to do equality tests
2424
- Evaluative assertions (is true/false/null/etc) now produce simpler error messages instead of masquerading as an operation (e.g. "== true")
2525
- `LibraryProperties.to_h` now properly uses formatters and symbolic keys, in order to support a `.to_s`
26+
- Architectures from `library.properties` are considered when iterating over unit test or examples compilation, as well as the configured platforms
2627

2728
### Deprecated
2829

exe/arduino_ci.rb

+92-41
Original file line numberDiff line numberDiff line change
@@ -195,19 +195,20 @@ def install_arduino_library_dependencies(library_names, on_behalf_of, already_in
195195
installed
196196
end
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
306315
end
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
309361
def 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

Comments
 (0)