Skip to content

Commit f1063ec

Browse files
committed
Scan library.properties as part of CI - depends and includes
1 parent 5550e43 commit f1063ec

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1919
- `CIConfig.is_default` to detect when the default configuration is used
2020
- `ArduinoBackend.boards_installed?` to detect whether a board family (or package, like `arduino:avr`) is installed
2121
- `ArduinoBackend.library_available?` to detect whether the library manager knows of a library
22+
- Sanity checks for `library.properties` `includes=` and `depends=` entries
2223

2324
### Changed
2425
- Rubocop expected syntax downgraded from ruby 2.6 to 2.5

REFERENCE.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ This completely skips the compilation tests (of library examples) portion of the
2929
This completely skips the compilation tests (of library examples) portion of the CI script. It does not skip the compilation of unit tests.
3030

3131

32+
### `--skip-library-properties` option
33+
34+
This completely skips validation of entries in `library.properties`.
35+
36+
3237
### `--testfile-select` option
3338

3439
This allows a file (or glob) pattern to be executed in your tests directory, creating a whitelist of files to test. E.g. `--testfile-select=test_animal_*.cpp` would match `test_animal_cat.cpp` and `test_animal_dog.cpp` (testing only those) and not `test_plant_rose.cpp`.
@@ -59,6 +64,11 @@ If set, testing will fail if no unit test files are detected (or if the director
5964
If set, testing will fail if no example sketches are detected. This is to avoid communicating a passing status in cases where a commit may have accidentally moved or deleted the examples.
6065

6166

67+
### `SKIP_LIBRARY_PROPERTIES` environment variable
68+
69+
If set, testing will skip validating `library.properties` entries. This is to work around any possible bugs in `arduino_ci`'s interpretation of what is "correct".
70+
71+
6272
## Indirectly Overriding Build Behavior (medium term use), and Advanced Options
6373

6474
For build behavior that you'd like to persist across commits (e.g. defining the set of platforms to test against, disabling a test that you expect to re-enable at some future point), a special configuration file called `.arduino-ci.yml` can be used. There are 3 places you can put them:

exe/arduino_ci.rb

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
VAR_USE_SUBDIR = "USE_SUBDIR".freeze
1010
VAR_EXPECT_EXAMPLES = "EXPECT_EXAMPLES".freeze
1111
VAR_EXPECT_UNITTESTS = "EXPECT_UNITTESTS".freeze
12+
VAR_SKIP_LIBPROPS = "SKIP_LIBRARY_PROPERTIES".freeze
1213

1314
@failure_count = 0
1415
@passfail = proc { |result| result ? "✓" : "✗" }
@@ -21,6 +22,7 @@ def self.parse(options)
2122
output_options = {
2223
skip_unittests: false,
2324
skip_compilation: false,
25+
skip_library_properties: false,
2426
ci_config: {
2527
"unittest" => unit_config
2628
},
@@ -37,6 +39,10 @@ def self.parse(options)
3739
output_options[:skip_compilation] = p
3840
end
3941

42+
opts.on("--skip-library-properties", "Don't validate library.properties entries") do |p|
43+
output_options[:skip_compilation] = p
44+
end
45+
4046
opts.on("--testfile-select=GLOB", "Unit test file (or glob) to select") do |p|
4147
unit_config["testfiles"] ||= {}
4248
unit_config["testfiles"]["select"] ||= []
@@ -58,6 +64,7 @@ def self.parse(options)
5864
puts " - #{VAR_USE_SUBDIR} - if set, the script will install the library from this subdirectory of the cwd"
5965
puts " - #{VAR_EXPECT_EXAMPLES} - if set, testing will fail if no example sketches are present"
6066
puts " - #{VAR_EXPECT_UNITTESTS} - if set, testing will fail if no unit tests are present"
67+
puts " - #{VAR_SKIP_LIBPROPS} - if set, testing will skip [experimental] library.properties validation"
6168
exit
6269
end
6370
end
@@ -146,6 +153,10 @@ def inform_multiline(message, &block)
146153
perform_action(message, true, nil, nil, false, false, &block)
147154
end
148155

156+
def warn(message)
157+
inform("WARNING") { message }
158+
end
159+
149160
# Assure that a platform exists and return its definition
150161
def assured_platform(purpose, name, config)
151162
platform_definition = config.platform_definition(name)
@@ -354,6 +365,32 @@ def choose_platform_set(config, reason, desired_platforms, library_properties)
354365
end
355366
end
356367

368+
# tests of sane library.properties values
369+
def perform_property_tests(cpp_library)
370+
return inform("Skipping library.properties tests") { "as requested via command line" } if @cli_options[:skip_library_properties]
371+
return inform("Skipping library.properties tests") { "as requested via #{VAR_SKIP_LIBPROPS}" } unless ENV[VAR_SKIP_LIBPROPS].nil?
372+
return inform("Skipping library.properties tests") { "file not found" } unless cpp_library.library_properties?
373+
374+
props = cpp_library.library_properties
375+
376+
props.depends&.each do |l|
377+
assure("library.properties 'depends=' entry '#{l}' is available via the library manager") { @backend.library_available?(l) }
378+
end
379+
380+
# the IDE would add these entries to a sketch (as "#include <...>" lines), they are nothing to do with the compioler
381+
props.includes&.map(&:strip)&.map(&Pathname::method(:new))&.each do |f|
382+
if (cpp_library.path + f).exist?
383+
inform("library.properties 'includes=' entry found") { f }
384+
elsif (cpp_library.path + "src" + f).exist?
385+
inform("library.properties 'includes=' entry found") { Pathname.new("src") + f }
386+
else
387+
# this is if they want to "#include <math>" or something -- may or may not be valid! so just warn.
388+
warn("library.properties 'includes=' entry '#{f}' does not refer to a file in the library")
389+
end
390+
end
391+
392+
end
393+
357394
# Unit test procedure
358395
def perform_unit_tests(cpp_library, file_config)
359396
if @cli_options[:skip_unittests]
@@ -475,7 +512,7 @@ def perform_example_compilation_tests(cpp_library, config)
475512
assumed_name = @backend.name_of_library(cpp_library_path)
476513
ondisk_name = cpp_library_path.realpath.basename.to_s
477514
if assumed_name != ondisk_name
478-
inform("WARNING") { "Installed library named '#{assumed_name}' has directory name '#{ondisk_name}'" }
515+
warn("Installed library named '#{assumed_name}' has directory name '#{ondisk_name}'")
479516
end
480517

481518
if !cpp_library.nil?
@@ -488,6 +525,8 @@ def perform_example_compilation_tests(cpp_library, config)
488525
end
489526
end
490527

528+
perform_property_tests(cpp_library)
529+
491530
install_arduino_library_dependencies(
492531
cpp_library.arduino_library_dependencies,
493532
"<#{ArduinoCI::CppLibrary::LIBRARY_PROPERTIES_FILE}>"

0 commit comments

Comments
 (0)