arduino_ci 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +1 -1
- data/REFERENCE.md +12 -1
- data/exe/arduino_ci.rb +127 -100
- data/exe/arduino_ci_remote.rb +1 -1
- data/exe/ensure_arduino_installation.rb +7 -1
- data/lib/arduino_ci/arduino_backend.rb +7 -3
- data/lib/arduino_ci/arduino_downloader.rb +1 -1
- data/lib/arduino_ci/ci_config.rb +3 -2
- data/lib/arduino_ci/cpp_library.rb +7 -3
- data/lib/arduino_ci/host.rb +2 -2
- data/lib/arduino_ci/version.rb +1 -1
- metadata +6 -7
checksums.yaml CHANGED
| @@ -1,7 +1,7 @@ | |
| 1 1 | --- |
| 2 | - |
| 3 | - metadata.gz: |
| 4 | - data.tar.gz: |
| 2 | + SHA256: |
| 3 | + metadata.gz: 6dab88af65d6e71fd9cd3e2f389340b184fb1fbb063ccb7a6743f893c47f690d |
| 4 | + data.tar.gz: 267b58186eea10a1f52ff4c16838270437a7d52d8fd0a3681f84e770845efa0d |
| 5 5 | SHA512: |
| 6 | - metadata.gz: |
| 7 | - data.tar.gz: |
| 6 | + metadata.gz: 8765d7d3c01fb5a4f9737604ee9ee33a020629e3e5d404403069ac346caad36f69a94893ca2db49cdc14bb50a1d5557d29cccd9b58022fb3d1a00cd9de348323 |
| 7 | + data.tar.gz: e537d36bd505b31630aae9e7359a71f82dbb07977bac93dbc4194d6da4112ca005e22b2e9051970d0d67afd4e5dcdabcd9a6dddda1ee399c0a7cfc01aecb631c |
data/README.md CHANGED
| @@ -1,7 +1,7 @@ | |
| 1 1 | |
| 2 2 | # ArduinoCI Ruby gem (`arduino_ci`) |
| 3 3 | [](https://rubygems.org/gems/arduino_ci) |
| 4 | - [](http://www.rubydoc.info/gems/arduino_ci/1. |
| 4 | + [](http://www.rubydoc.info/gems/arduino_ci/1.1.0) |
| 5 5 | [](https://gitter.im/Arduino-CI/arduino_ci?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) |
| 6 6 | |
| 7 7 | You want to run tests on your Arduino library (bonus: without hardware present), but the IDE doesn't support that. Arduino CI provides that ability. |
data/REFERENCE.md CHANGED
| @@ -33,11 +33,22 @@ This completely skips the compilation tests (of library examples) portion of the | |
| 33 33 | |
| 34 34 | 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`. |
| 35 35 | |
| 36 | + |
| 36 37 | ### `--testfile-reject` option |
| 37 38 | |
| 38 39 | This allows a file (or glob) pattern to be executed in your tests directory, creating a blacklist of files to skip. E.g. `--testfile-reject=test_animal_*.cpp` would match `test_animal_cat.cpp` and `test_animal_dog.cpp` (skipping those) and test only `test_plant_rose.cpp`, `test_plant_daisy.cpp`, etc. |
| 39 40 | |
| 40 41 | |
| 42 | + ### `EXPECT_UNITTESTS` environment variable |
| 43 | + |
| 44 | + If set, testing will fail if no unit test files are detected (or if the directory does not exist). This is to avoid communicating a passing status in cases where a commit may have accidentally moved or deleted the test files. |
| 45 | + |
| 46 | + |
| 47 | + ### `EXPECT_EXAMPLES` environment variable |
| 48 | + |
| 49 | + 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. |
| 50 | + |
| 51 | + |
| 41 52 | ## Indirectly Overriding Build Behavior (medium term use), and Advanced Options |
| 42 53 | |
| 43 54 | 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: |
| @@ -53,7 +64,7 @@ For build behavior that you'd like to persist across commits (e.g. defining the | |
| 53 64 | |
| 54 65 | Arduino boards are typically named in the form `manufacturer:family:model`. These definitions are not arbitrary -- they are defined in an Arduino _package_. For all but the built-in packages, you will need a package URL. Here is Adafruit's: https://adafruit.github.io/arduino-board-index/package_adafruit_index.json |
| 55 66 | |
| 56 | - Here is how you would declare a package that includes the `potato:salad` |
| 67 | + Here is how you would declare a package that includes the `potato:salad` set of platforms (aka "board family") in your `.arduino-ci.yml`: |
| 57 68 | |
| 58 69 | ```yaml |
| 59 70 | packages: |
data/exe/arduino_ci.rb CHANGED
| @@ -5,7 +5,8 @@ require 'pathname' | |
| 5 5 | require 'optparse' |
| 6 6 | |
| 7 7 | WIDTH = 80 |
| 8 | - |
| 8 | + VAR_EXPECT_EXAMPLES = "EXPECT_EXAMPLES".freeze |
| 9 | + VAR_EXPECT_UNITTESTS = "EXPECT_UNITTESTS".freeze |
| 9 10 | |
| 10 11 | @failure_count = 0 |
| 11 12 | @passfail = proc { |result| result ? "✓" : "✗" } |
| @@ -48,6 +49,10 @@ class Parser | |
| 48 49 | |
| 49 50 | opts.on("-h", "--help", "Prints this help") do |
| 50 51 | puts opts |
| 52 | + puts |
| 53 | + puts "Additionally, the following environment variables control the script:" |
| 54 | + puts " - #{VAR_EXPECT_EXAMPLES} - if set, testing will fail if no example sketches are present" |
| 55 | + puts " - #{VAR_EXPECT_UNITTESTS} - if set, testing will fail if no unit tests are present" |
| 51 56 | exit |
| 52 57 | end |
| 53 58 | end |
| @@ -93,7 +98,7 @@ def perform_action(message, multiline, mark_fn, on_fail_msg, tally_on_fail, abor | |
| 93 98 | else |
| 94 99 | print line |
| 95 100 | end |
| 96 | - |
| 101 | + $stdout.flush |
| 97 102 | result = yield |
| 98 103 | mark = mark_fn.nil? ? "" : mark_fn.call(result) |
| 99 104 | # if multline, put checkmark at full width |
| @@ -119,7 +124,7 @@ def attempt_multiline(message, &block) | |
| 119 124 | end |
| 120 125 | |
| 121 126 | # Make a nice status for something that kills the script immediately on failure |
| 122 | - FAILED_ASSURANCE_MESSAGE = "This may indicate a problem with |
| 127 | + FAILED_ASSURANCE_MESSAGE = "This may indicate a problem with your configuration; halting here".freeze |
| 123 128 | def assure(message, &block) |
| 124 129 | perform_action(message, false, @passfail, FAILED_ASSURANCE_MESSAGE, true, true, &block) |
| 125 130 | end |
| @@ -139,9 +144,7 @@ end | |
| 139 144 | # Assure that a platform exists and return its definition |
| 140 145 | def assured_platform(purpose, name, config) |
| 141 146 | platform_definition = config.platform_definition(name) |
| 142 | - assure("Requested #{purpose} platform '#{name}' is defined in 'platforms' YML") |
| 143 | - !platform_definition.nil? |
| 144 | - end |
| 147 | + assure("Requested #{purpose} platform '#{name}' is defined in 'platforms' YML") { !platform_definition.nil? } |
| 145 148 | platform_definition |
| 146 149 | end |
| 147 150 | |
| @@ -157,24 +160,22 @@ end | |
| 157 160 | # print out some files |
| 158 161 | def display_files(pathname) |
| 159 162 | # `find` doesn't follow symlinks, so we should instead |
| 160 | - realpath = Host.symlink?(pathname) ? Host.readlink(pathname) : pathname |
| 163 | + realpath = ArduinoCI::Host.symlink?(pathname) ? ArduinoCI::Host.readlink(pathname) : pathname |
| 161 164 | |
| 162 165 | # suppress directories and dotfile-based things |
| 163 166 | all_files = realpath.find.select(&:file?) |
| 164 167 | non_hidden = all_files.reject { |path| file_is_hidden_somewhere?(path) } |
| 165 168 | |
| 166 169 | # print files with an indent |
| 167 | - |
| 168 | - non_hidden.each { |p| puts "#{ |
| 170 | + puts " Files (excluding hidden files): #{non_hidden.size}" |
| 171 | + non_hidden.each { |p| puts " #{p}" } |
| 169 172 | end |
| 170 173 | |
| 171 174 | # @return [Array<String>] The list of installed libraries |
| 172 175 | def install_arduino_library_dependencies(library_names, on_behalf_of, already_installed = []) |
| 173 176 | installed = already_installed.clone |
| 174 | - library_names.map { |n| @backend.library_of_name(n) }.each do |l| |
| 175 | - if installed |
| 176 | - # do nothing |
| 177 | - elsif l.installed? |
| 177 | + (library_names.map { |n| @backend.library_of_name(n) } - installed).each do |l| |
| 178 | + if l.installed? |
| 178 179 | inform("Using pre-existing dependency of #{on_behalf_of}") { l.name } |
| 179 180 | else |
| 180 181 | assure("Installing dependency of #{on_behalf_of}: '#{l.name}'") do |
| @@ -189,13 +190,77 @@ def install_arduino_library_dependencies(library_names, on_behalf_of, already_in | |
| 189 190 | installed |
| 190 191 | end |
| 191 192 | |
| 192 | - |
| 193 | - |
| 194 | - |
| 195 | - |
| 193 | + # @param example_platform_info [Hash] mapping of platform name to package information |
| 194 | + # @param board_package_url [Hash] mapping of package name to URL |
| 195 | + def install_all_packages(example_platform_info, board_package_url) |
| 196 | + # with all platform info, we can extract unique packages and their urls |
| 197 | + # do that, set the URLs, and download the packages |
| 198 | + all_packages = example_platform_info.values.map { |v| v[:package] }.uniq.reject(&:nil?) |
| 199 | + |
| 200 | + # make sure any non-builtin package has a URL defined |
| 201 | + all_packages.each { |p| assure("Board package #{p} has a defined URL") { board_package_url[p] } } |
| 202 | + |
| 203 | + # set up all the board manager URLs. |
| 204 | + # we can safely reject nils now, they would be for the builtins |
| 205 | + all_urls = all_packages.map { |p| board_package_url[p] }.uniq.reject(&:nil?) |
| 206 | + unless all_urls.empty? |
| 207 | + assure_multiline("Setting board manager URLs") do |
| 208 | + @backend.board_manager_urls = all_urls |
| 209 | + result = @backend.board_manager_urls |
| 210 | + result.each { |u| puts " #{u}" } |
| 211 | + (all_urls - result).empty? # check that all_urls is completely contained in the result |
| 212 | + end |
| 196 213 | end |
| 197 | - |
| 214 | + all_packages.each { |p| assure("Installing board package #{p}") { @backend.install_boards(p) } } |
| 215 | + end |
| 198 216 | |
| 217 | + # @param expectation_envvar [String] the name of the env var to check |
| 218 | + # @param operation [String] a description of what operation we might be skipping |
| 219 | + # @param filegroup_name [String] a description of the set of files without which we effectively skip the operation |
| 220 | + # @param dir_description [String] a description of the directory where we looked for the files |
| 221 | + # @param dir [Pathname] the directory where we looked for the files |
| 222 | + def handle_expectation_of_files(expectation_envvar, operation, filegroup_name, dir_description, dir_path) |
| 223 | + # alert future me about running the script from the wrong directory, instead of doing the huge file dump |
| 224 | + # otherwise, assume that the user might be running the script on a library with no actual unit tests |
| 225 | + if Pathname.new(__dir__).parent == Pathname.new(Dir.pwd) |
| 226 | + inform_multiline("arduino_ci seems to be trying to test itself") do |
| 227 | + [ |
| 228 | + "arduino_ci (the ruby gem) isn't an arduino project itself, so running the CI test script against", |
| 229 | + "the core library isn't really a valid thing to do... but it's easy for a developer (including the", |
| 230 | + "owner) to mistakenly do just that. Hello future me, you probably meant to run this against one of", |
| 231 | + "the sample projects in SampleProjects/ ... if not, please submit a bug report; what a wild case!" |
| 232 | + ].each { |l| puts " #{l}" } |
| 233 | + false |
| 234 | + end |
| 235 | + exit(1) |
| 236 | + end |
| 237 | + |
| 238 | + # either the directory is empty, or it doesn't exist at all. message accordingly. |
| 239 | + (problem, dir_desc, dir) = if dir_path.exist? |
| 240 | + ["No #{filegroup_name} were found in", dir_description, dir_path] |
| 241 | + else |
| 242 | + ["No #{dir_description} at", "base directory", dir_path.parent] |
| 243 | + end |
| 244 | + |
| 245 | + inform(problem) { dir_path } |
| 246 | + inform("Environment variable #{expectation_envvar} is") { "(#{ENV[expectation_envvar].class}) #{ENV[expectation_envvar]}" } |
| 247 | + if ENV[expectation_envvar].nil? |
| 248 | + inform_multiline("Skipping #{operation}") do |
| 249 | + puts " In case that's an error, this is what was found in the #{dir_desc}:" |
| 250 | + display_files(dir) |
| 251 | + puts " To force an error in this case, set the environment variable #{expectation_envvar}" |
| 252 | + true |
| 253 | + end |
| 254 | + else |
| 255 | + assure_multiline("Dumping project's #{dir_desc} before exit") do |
| 256 | + display_files(dir) |
| 257 | + false |
| 258 | + end |
| 259 | + end |
| 260 | + end |
| 261 | + |
| 262 | + # report and return the set of compilers |
| 263 | + def get_annotated_compilers(config, cpp_library) |
| 199 264 | # check GCC |
| 200 265 | compilers = config.compilers_to_use |
| 201 266 | assure("The set of compilers (#{compilers.length}) isn't empty") { !compilers.empty? } |
| @@ -209,66 +274,54 @@ def perform_unit_tests(cpp_library, file_config) | |
| 209 274 | end |
| 210 275 | inform("libasan availability for #{gcc_binary}") { cpp_library.libasan?(gcc_binary) } |
| 211 276 | end |
| 277 | + compilers |
| 278 | + end |
| 279 | + |
| 280 | + def perform_unit_tests(cpp_library, file_config) |
| 281 | + if @cli_options[:skip_unittests] |
| 282 | + inform("Skipping unit tests") { "as requested via command line" } |
| 283 | + return |
| 284 | + end |
| 212 285 | |
| 213 | - |
| 214 | - |
| 215 | - config.platforms_to_unittest. |
| 286 | + config = file_config.with_override_config(@cli_options[:ci_config]) |
| 287 | + compilers = get_annotated_compilers(config, cpp_library) |
| 288 | + config.platforms_to_unittest.each_with_object({}) { |p, acc| acc[p] = assured_platform("unittest", p, config) } |
| 216 289 | |
| 217 290 | inform("Library conforms to Arduino library specification") { cpp_library.one_point_five? ? "1.5" : "1.0" } |
| 218 291 | |
| 219 | - # |
| 220 | - if |
| 221 | - |
| 222 | - |
| 223 | - |
| 224 | - |
| 225 | - |
| 226 | - |
| 227 | - "the core library isn't really a valid thing to do... but it's easy for a developer (including the", |
| 228 | - "owner) to mistakenly do just that. Hello future me, you probably meant to run this against one of", |
| 229 | - "the sample projects in SampleProjects/ ... if not, please submit a bug report; what a wild case!" |
| 230 | - ].each { |l| puts " #{l}" } |
| 231 | - false |
| 232 | - end |
| 233 | - exit(1) |
| 234 | - else |
| 235 | - inform_multiline("Skipping unit tests; no tests dir at #{cpp_library.tests_dir}") do |
| 236 | - puts " In case that's an error, this is what was found in the library:" |
| 237 | - display_files(cpp_library.tests_dir.parent) |
| 238 | - true |
| 239 | - end |
| 240 | - end |
| 241 | - elsif cpp_library.test_files.empty? |
| 242 | - inform_multiline("Skipping unit tests; no test files were found in #{cpp_library.tests_dir}") do |
| 243 | - puts " In case that's an error, this is what was found in the tests directory:" |
| 244 | - display_files(cpp_library.tests_dir) |
| 245 | - true |
| 246 | - end |
| 247 | - elsif config.platforms_to_unittest.empty? |
| 292 | + # Handle lack of test files |
| 293 | + if cpp_library.test_files.empty? |
| 294 | + handle_expectation_of_files(VAR_EXPECT_UNITTESTS, "unit tests", "test files", "tests directory", cpp_library.tests_dir) |
| 295 | + return |
| 296 | + end |
| 297 | + |
| 298 | + # Handle lack of platforms |
| 299 | + if config.platforms_to_unittest.empty? |
| 248 300 | inform("Skipping unit tests") { "no platforms were requested" } |
| 249 | - |
| 250 | - |
| 251 | - |
| 252 | - |
| 253 | - |
| 254 | - |
| 255 | - |
| 256 | - |
| 257 | - |
| 258 | - |
| 259 | - |
| 260 | - |
| 261 | - |
| 262 | - |
| 263 | - |
| 264 | - |
| 265 | - |
| 266 | - |
| 267 | - |
| 268 | - |
| 269 | - |
| 270 | - |
| 301 | + return |
| 302 | + end |
| 303 | + |
| 304 | + install_arduino_library_dependencies(config.aux_libraries_for_unittest, "<unittest/libraries>") |
| 305 | + |
| 306 | + config.platforms_to_unittest.each do |p| |
| 307 | + config.allowable_unittest_files(cpp_library.test_files).each do |unittest_path| |
| 308 | + unittest_name = unittest_path.basename.to_s |
| 309 | + compilers.each do |gcc_binary| |
| 310 | + attempt_multiline("Unit testing #{unittest_name} with #{gcc_binary} for #{p}") do |
| 311 | + exe = cpp_library.build_for_test_with_configuration( |
| 312 | + unittest_path, |
| 313 | + config.aux_libraries_for_unittest, |
| 314 | + gcc_binary, |
| 315 | + config.gcc_config(p) |
| 316 | + ) |
| 317 | + puts |
| 318 | + unless exe |
| 319 | + puts "Last command: #{cpp_library.last_cmd}" |
| 320 | + puts cpp_library.last_out |
| 321 | + puts cpp_library.last_err |
| 322 | + next false |
| 271 323 | end |
| 324 | + cpp_library.run_test_file(exe) |
| 272 325 | end |
| 273 326 | end |
| 274 327 | end |
| @@ -306,40 +359,14 @@ def perform_example_compilation_tests(cpp_library, config) | |
| 306 359 | aux_libraries.merge(ovr_config.aux_libraries_for_build) |
| 307 360 | end |
| 308 361 | |
| 309 | - |
| 310 | - # do that, set the URLs, and download the packages |
| 311 | - all_packages = example_platform_info.values.map { |v| v[:package] }.uniq.reject(&:nil?) |
| 312 | - |
| 313 | - # make sure any non-builtin package has a URL defined |
| 314 | - all_packages.each do |p| |
| 315 | - assure("Board package #{p} has a defined URL") { board_package_url[p] } |
| 316 | - end |
| 317 | - |
| 318 | - # set up all the board manager URLs. |
| 319 | - # we can safely reject nils now, they would be for the builtins |
| 320 | - all_urls = all_packages.map { |p| board_package_url[p] }.uniq.reject(&:nil?) |
| 321 | - |
| 322 | - unless all_urls.empty? |
| 323 | - assure("Setting board manager URLs") do |
| 324 | - @backend.board_manager_urls = all_urls |
| 325 | - end |
| 326 | - end |
| 327 | - |
| 328 | - all_packages.each do |p| |
| 329 | - assure("Installing board package #{p}") do |
| 330 | - @backend.install_boards(p) |
| 331 | - end |
| 332 | - end |
| 333 | - |
| 362 | + install_all_packages(example_platform_info, board_package_url) |
| 334 363 | install_arduino_library_dependencies(aux_libraries, "<compile/libraries>") |
| 335 364 | |
| 336 365 | if config.platforms_to_build.empty? |
| 337 366 | inform("Skipping builds") { "no platforms were requested" } |
| 338 367 | return |
| 339 368 | elsif library_examples.empty? |
| 340 | - |
| 341 | - display_files(installed_library_path) |
| 342 | - end |
| 369 | + handle_expectation_of_files(VAR_EXPECT_EXAMPLES, "builds", "examples", "the examples directory", cpp_library.examples_dir) |
| 343 370 | return |
| 344 371 | end |
| 345 372 | |
data/exe/arduino_ci_remote.rb CHANGED
| @@ -2,4 +2,10 @@ | |
| 2 2 | require 'arduino_ci' |
| 3 3 | |
| 4 4 | # this will exit after Arduino is located and/or forcibly installed |
| 5 | - ArduinoCI::ArduinoInstallation.autolocate! |
| 5 | + backend = ArduinoCI::ArduinoInstallation.autolocate! |
| 6 | + lib_dir = backend.lib_dir |
| 7 | + |
| 8 | + unless lib_dir.exist? |
| 9 | + puts "Creating libraries directory #{lib_dir}" |
| 10 | + lib_dir.mkpath |
| 11 | + end |
| @@ -50,9 +50,9 @@ module ArduinoCI | |
| 50 50 | |
| 51 51 | def _wrap_run(work_fn, *args, **kwargs) |
| 52 52 | # do some work to extract & merge environment variables if they exist |
| 53 | - has_env = !args.empty? && args[0]. |
| 53 | + has_env = !args.empty? && args[0].instance_of?(Hash) |
| 54 54 | env_vars = has_env ? args[0] : {} |
| 55 | - actual_args = has_env ? args[1 |
| 55 | + actual_args = has_env ? args[1..] : args # need to shift over if we extracted args |
| 56 56 | custom_config = @config_dir.nil? ? [] : ["--config-file", @config_dir.to_s] |
| 57 57 | full_args = [binary_path.to_s, "--format", "json"] + custom_config + actual_args |
| 58 58 | full_cmd = env_vars.empty? ? full_args : [env_vars] + full_args |
| @@ -121,7 +121,11 @@ module ArduinoCI | |
| 121 121 | # @param name [String] the board name |
| 122 122 | # @return [bool] whether the command succeeded |
| 123 123 | def install_boards(boardfamily) |
| 124 | - result = |
| 124 | + result = if @additional_urls.empty? |
| 125 | + run_and_capture("core", "install", boardfamily) |
| 126 | + else |
| 127 | + run_and_capture("core", "install", boardfamily, "--additional-urls", @additional_urls.join(",")) |
| 128 | + end |
| 125 129 | result[:success] |
| 126 130 | end |
| 127 131 | |
| @@ -104,7 +104,7 @@ module ArduinoCI | |
| 104 104 | total_size += size |
| 105 105 | needed_dots = (total_size / chunk_size).to_i |
| 106 106 | unprinted_dots = needed_dots - dots |
| 107 | - @output.print("." * unprinted_dots) if unprinted_dots |
| 107 | + @output.print("." * unprinted_dots) if unprinted_dots.positive? |
| 108 108 | dots = needed_dots |
| 109 109 | end |
| 110 110 | |
data/lib/arduino_ci/ci_config.rb CHANGED
| @@ -66,6 +66,7 @@ module ArduinoCI | |
| 66 66 | attr_accessor :platform_info |
| 67 67 | attr_accessor :compile_info |
| 68 68 | attr_accessor :unittest_info |
| 69 | + |
| 69 70 | def initialize |
| 70 71 | @package_info = {} |
| 71 72 | @platform_info = {} |
| @@ -107,7 +108,7 @@ module ArduinoCI | |
| 107 108 | good_data = {} |
| 108 109 | source.each do |key, value| |
| 109 110 | ksym = key.to_sym |
| 110 | - expected_type = schema[ksym]. |
| 111 | + expected_type = schema[ksym].instance_of?(Class) ? schema[ksym] : Hash |
| 111 112 | if !schema.include?(ksym) |
| 112 113 | puts "Warning: unknown field '#{ksym}' under definition for #{rootname}" |
| 113 114 | elsif value.nil? |
| @@ -115,7 +116,7 @@ module ArduinoCI | |
| 115 116 | elsif value.class != expected_type |
| 116 117 | puts "Warning: expected field '#{ksym}' of #{rootname} to be '#{expected_type}', got '#{value.class}'" |
| 117 118 | else |
| 118 | - good_data[ksym] = value. |
| 119 | + good_data[ksym] = value.instance_of?(Hash) ? validate_data(key, value, schema[ksym]) : value |
| 119 120 | end |
| 120 121 | end |
| 121 122 | good_data |
| @@ -82,6 +82,11 @@ module ArduinoCI | |
| 82 82 | @backend.lib_dir + name_on_disk |
| 83 83 | end |
| 84 84 | |
| 85 | + # @return [String] The parent directory of all examples |
| 86 | + def examples_dir |
| 87 | + path + "examples" |
| 88 | + end |
| 89 | + |
| 85 90 | # Determine whether a library is present in the lib dir |
| 86 91 | # |
| 87 92 | # Note that `true` doesn't guarantee that the library is valid/installed |
| @@ -402,8 +407,7 @@ module ArduinoCI | |
| 402 407 | other_lib.install unless other_lib.installed? |
| 403 408 | other_lib.all_arduino_library_dependencies! |
| 404 409 | end.flatten |
| 405 | - |
| 406 | - ret |
| 410 | + (additional_libraries + recursive).uniq |
| 407 411 | end |
| 408 412 | |
| 409 413 | # Arduino library directories containing sources -- only those of the dependencies |
| @@ -517,7 +521,7 @@ module ArduinoCI | |
| 517 521 | # @param executable [Pathname] the path to the test file |
| 518 522 | def print_stack_dump(executable) |
| 519 523 | possible_dumpfiles = [ |
| 520 | - executable.sub_ext(executable.extname |
| 524 | + executable.sub_ext("#{executable.extname}.stackdump") |
| 521 525 | ] |
| 522 526 | possible_dumpfiles.select(&:exist?).each do |dump| |
| 523 527 | puts "========== Stack dump from #{dump}:" |
data/lib/arduino_ci/host.rb CHANGED
| @@ -8,10 +8,10 @@ module ArduinoCI | |
| 8 8 | class Host |
| 9 9 | # TODO: this came from https://stackoverflow.com/a/22716582/2063546 |
| 10 10 | # and I'm not sure if it can be replaced by self.os == :windows |
| 11 | - WINDOWS_VARIANT_REGEX = /mswin32|cygwin|mingw|bccwin |
| 11 | + WINDOWS_VARIANT_REGEX = /mswin32|cygwin|mingw|bccwin/.freeze |
| 12 12 | |
| 13 13 | # e.g. 11/27/2020 01:02 AM <SYMLINKD> ExcludeSomething [C:\projects\arduino-ci\SampleProjects\ExcludeSomething] |
| 14 | - DIR_SYMLINK_REGEX = %r{\d+/\d+/\d+\s+[^<]+<SYMLINKD?>\s+(.*) \[([^\]]+)\]} |
| 14 | + DIR_SYMLINK_REGEX = %r{\d+/\d+/\d+\s+[^<]+<SYMLINKD?>\s+(.*) \[([^\]]+)\]}.freeze |
| 15 15 | |
| 16 16 | # Cross-platform way of finding an executable in the $PATH. |
| 17 17 | # via https://stackoverflow.com/a/5471032/2063546 |
data/lib/arduino_ci/version.rb CHANGED
metadata CHANGED
| @@ -1,14 +1,14 @@ | |
| 1 1 | --- !ruby/object:Gem::Specification |
| 2 2 | name: arduino_ci |
| 3 3 | version: !ruby/object:Gem::Version |
| 4 | - version: 1. |
| 4 | + version: 1.1.0 |
| 5 5 | platform: ruby |
| 6 6 | authors: |
| 7 7 | - Ian Katz |
| 8 | - autorequire: |
| 8 | + autorequire: |
| 9 9 | bindir: exe |
| 10 10 | cert_chain: [] |
| 11 | - date: 2020- |
| 11 | + date: 2020-12-02 00:00:00.000000000 Z |
| 12 12 | dependencies: |
| 13 13 | - !ruby/object:Gem::Dependency |
| 14 14 | name: os |
| @@ -383,7 +383,7 @@ homepage: http://github.com/Arduino-CI/arduino_ci | |
| 383 383 | licenses: |
| 384 384 | - Apache-2.0 |
| 385 385 | metadata: {} |
| 386 | - post_install_message: |
| 386 | + post_install_message: |
| 387 387 | rdoc_options: [] |
| 388 388 | require_paths: |
| 389 389 | - lib |
| @@ -398,9 +398,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 398 398 | - !ruby/object:Gem::Version |
| 399 399 | version: '0' |
| 400 400 | requirements: [] |
| 401 | - |
| 402 | - |
| 403 | - signing_key: |
| 401 | + rubygems_version: 3.0.3 |
| 402 | + signing_key: |
| 404 403 | specification_version: 4 |
| 405 404 | summary: Tools for building and unit testing Arduino libraries |
| 406 405 | test_files: [] |