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: []
|