arduino_ci 0.1.17 → 0.1.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/cpp/arduino/Arduino.h +2 -0
- data/cpp/arduino/avr/pgmspace.h +17 -16
- data/cpp/unittest/ArduinoUnitTests.cpp +3 -0
- data/cpp/unittest/ArduinoUnitTests.h +63 -23
- data/cpp/unittest/Assertion.h +2 -0
- data/exe/arduino_ci_remote.rb +44 -19
- data/exe/arduino_ci_remote.rb.orig +387 -0
- data/exe/arduino_library_location.rb +7 -0
- data/lib/arduino_ci/arduino_cmd.rb +6 -3
- data/lib/arduino_ci/arduino_downloader.rb +20 -16
- data/lib/arduino_ci/arduino_downloader_windows.rb +3 -0
- data/lib/arduino_ci/arduino_installation.rb +4 -4
- data/lib/arduino_ci/cpp_library.rb +46 -11
- data/lib/arduino_ci/version.rb +1 -1
- data/misc/default.yml +1 -0
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7de3ae0cd1c73eb41fe0b7f897e20f7a3d2e5c0
|
4
|
+
data.tar.gz: 29dc639c29a0dcb3841e3dd903002e1fc72ef892
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf8434e69d4b3cc1c65d4b37db875133fdd1055e2d435b3936c15ef1e731c9160238a597ed2e2f8c21d28ce4522963e02371482ddfebc00307b2b16c2bfebf9d
|
7
|
+
data.tar.gz: db0f703d2d7dad26ccc1a54f098e64ef9953ef66266f4379e1936ff915dfb38e04899304ca666ea79fac8e1dee52868979b96d6ef2937a7a085a6383dec1f176
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
# ArduinoCI Ruby gem (`arduino_ci`) [![Gem Version](https://badge.fury.io/rb/arduino_ci.svg)](https://rubygems.org/gems/arduino_ci) [![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://www.rubydoc.info/gems/arduino_ci/0.1.
|
2
|
+
# ArduinoCI Ruby gem (`arduino_ci`) [![Gem Version](https://badge.fury.io/rb/arduino_ci.svg)](https://rubygems.org/gems/arduino_ci) [![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://www.rubydoc.info/gems/arduino_ci/0.1.18)
|
3
3
|
|
4
4
|
You want your Arduino library to be automatically built and tested every time someone contributes code to your project on GitHub, but the Arduino IDE lacks the ability to run unit tests. [Arduino CI](https://github.com/ianfixes/arduino_ci) provides that ability.
|
5
5
|
|
data/cpp/arduino/Arduino.h
CHANGED
data/cpp/arduino/avr/pgmspace.h
CHANGED
@@ -29,25 +29,26 @@ out.each { |l| puts d(l) }
|
|
29
29
|
|
30
30
|
// everything's a no-op
|
31
31
|
#define PSTR(s) ((const char *)(s))
|
32
|
-
#define pgm_read_byte_near(x) (x)
|
33
|
-
#define pgm_read_word_near(x) (x)
|
34
|
-
#define pgm_read_dword_near(x) (x)
|
35
|
-
#define pgm_read_float_near(x) (x)
|
36
|
-
#define pgm_read_ptr_near(x) (x)
|
37
32
|
|
38
|
-
#define
|
39
|
-
#define
|
40
|
-
#define
|
41
|
-
#define
|
42
|
-
#define
|
33
|
+
#define pgm_read_byte_near(address_short) (* (const uint8_t *) (address_short) )
|
34
|
+
#define pgm_read_word_near(address_short) (* (const uint16_t *) (address_short) )
|
35
|
+
#define pgm_read_dword_near(address_short) (* (const uint32_t *) (address_short) )
|
36
|
+
#define pgm_read_float_near(address_short) (* (const float *) (address_short) )
|
37
|
+
#define pgm_read_ptr_near(address_short) (* (const void *) (address_short) )
|
43
38
|
|
39
|
+
#define pgm_read_byte_far(address_long) (* (const uint8_t *) (address_long) )
|
40
|
+
#define pgm_read_word_far(address_long) (* (const uint16_t *) (address_long) )
|
41
|
+
#define pgm_read_dword_far(address_long) (* (const uint32_t *) (address_long) )
|
42
|
+
#define pgm_read_float_far(address_long) (* (const float *) (address_long) )
|
43
|
+
#define pgm_read_ptr_far(address_long) (* (const void *) (address_long) )
|
44
44
|
|
45
|
-
#define pgm_read_byte(
|
46
|
-
#define pgm_read_word(
|
47
|
-
#define pgm_read_dword(
|
48
|
-
#define pgm_read_float(
|
49
|
-
#define pgm_read_ptr(
|
50
|
-
|
45
|
+
#define pgm_read_byte(address_short) pgm_read_byte_near(address_short)
|
46
|
+
#define pgm_read_word(address_short) pgm_read_word_near(address_short)
|
47
|
+
#define pgm_read_dword(address_short) pgm_read_dword_near(address_short)
|
48
|
+
#define pgm_read_float(address_short) pgm_read_float_near(address_short)
|
49
|
+
#define pgm_read_ptr(address_short) pgm_read_ptr_near(address_short)
|
50
|
+
|
51
|
+
#define pgm_get_far_address(var) ( (uint_farptr_t) (&(var)) )
|
51
52
|
|
52
53
|
#define memchr_P(...) ::memchr(__VA_ARGS__)
|
53
54
|
#define memcmp_P(...) ::memcmp(__VA_ARGS__)
|
@@ -15,6 +15,26 @@ struct TestData {
|
|
15
15
|
int result;
|
16
16
|
};
|
17
17
|
|
18
|
+
class TestSetup
|
19
|
+
{
|
20
|
+
public:
|
21
|
+
TestSetup() {
|
22
|
+
sInstance = this;
|
23
|
+
}
|
24
|
+
virtual void run() {}
|
25
|
+
static TestSetup *sInstance;
|
26
|
+
};
|
27
|
+
|
28
|
+
class TestTeardown
|
29
|
+
{
|
30
|
+
public:
|
31
|
+
TestTeardown() {
|
32
|
+
sInstance = this;
|
33
|
+
}
|
34
|
+
virtual void run() {}
|
35
|
+
static TestTeardown *sInstance;
|
36
|
+
};
|
37
|
+
|
18
38
|
class Test
|
19
39
|
{
|
20
40
|
public:
|
@@ -49,29 +69,29 @@ class Test
|
|
49
69
|
}
|
50
70
|
|
51
71
|
template <typename A, typename B> void onAssert(
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
const char* file,
|
73
|
+
int line,
|
74
|
+
const char* description,
|
75
|
+
bool pass,
|
76
|
+
const char* lhsRelevance,
|
77
|
+
const char* lhsLabel,
|
78
|
+
const A &lhs,
|
79
|
+
const char* opLabel,
|
80
|
+
const char* rhsRelevance,
|
81
|
+
const char* rhsLabel,
|
82
|
+
const B &rhs
|
83
|
+
) {
|
84
|
+
cerr << " " << (pass ? "" : "not ") << "ok " << ++mAssertCounter << " - ";
|
85
|
+
cerr << description << " " << lhsLabel << " " << opLabel << " " << rhsLabel << endl;
|
86
|
+
if (!pass) {
|
87
|
+
cerr << " ---" << endl;
|
88
|
+
cerr << " operator: " << opLabel << endl;
|
89
|
+
cerr << " " << lhsRelevance << ": " << lhs << endl;
|
90
|
+
cerr << " " << rhsRelevance << ": " << rhs << endl;
|
91
|
+
cerr << " at:" << endl;
|
92
|
+
cerr << " file: " << file << endl;
|
93
|
+
cerr << " line: " << line << endl;
|
94
|
+
cerr << " ..." << endl;
|
75
95
|
}
|
76
96
|
}
|
77
97
|
};
|
@@ -152,7 +172,9 @@ class Test
|
|
152
172
|
static int run_and_report(int argc, char *argv[]) {
|
153
173
|
// TODO: pick a reporter based on args
|
154
174
|
ReporterTAP rep;
|
175
|
+
if (TestSetup::sInstance) TestSetup::sInstance->run();
|
155
176
|
Results results = run(&rep);
|
177
|
+
if (TestTeardown::sInstance) TestTeardown::sInstance->run();
|
156
178
|
return results.failed + results.skipped;
|
157
179
|
}
|
158
180
|
|
@@ -217,6 +239,24 @@ class Test
|
|
217
239
|
} test_##name##_instance; \
|
218
240
|
void test_##name ::task()
|
219
241
|
|
242
|
+
/**
|
243
|
+
* The unittest_setup and unittest_teardown functions are intended to be used
|
244
|
+
* to set up "external" dependencies that needs to present but are not directly
|
245
|
+
* related to the functionality that you are testing, for instance a LCD.
|
246
|
+
*/
|
247
|
+
#define unittest_setup() \
|
248
|
+
class unittest_setup_class : public TestSetup { \
|
249
|
+
public: \
|
250
|
+
virtual void run() override; \
|
251
|
+
} unittest_setup_instance; \
|
252
|
+
void unittest_setup_class::run()
|
253
|
+
|
254
|
+
#define unittest_teardown() \
|
255
|
+
class unittest_teardown_class : public TestTeardown { \
|
256
|
+
public: \
|
257
|
+
virtual void run() override; \
|
258
|
+
} unittest_teardown_instance; \
|
259
|
+
void unittest_teardown_class::run()
|
220
260
|
|
221
261
|
#define unittest_main() \
|
222
262
|
int main(int argc, char *argv[]) { \
|
data/cpp/unittest/Assertion.h
CHANGED
@@ -38,6 +38,7 @@
|
|
38
38
|
#define assertMoreOrEqual(arg1,arg2) assertOp("assertMoreOrEqual","upperBound",arg1,compareMoreOrEqual,">=","lowerBound",arg2)
|
39
39
|
#define assertTrue(arg) assertEqual(true, arg)
|
40
40
|
#define assertFalse(arg) assertEqual(false, arg)
|
41
|
+
#define assertNull(arg) assertEqual((void*)NULL, (void*)arg)
|
41
42
|
|
42
43
|
/** macro generates optional output and calls fail() followed by a return if false. */
|
43
44
|
#define assureEqual(arg1,arg2) assureOp("assureEqual","expected",arg1,compareEqual,"==","actual",arg2)
|
@@ -48,4 +49,5 @@
|
|
48
49
|
#define assureMoreOrEqual(arg1,arg2) assureOp("assureMoreOrEqual","upperBound",arg1,compareMoreOrEqual,">=","lowerBound",arg2)
|
49
50
|
#define assureTrue(arg) assureEqual(true, arg)
|
50
51
|
#define assureFalse(arg) assureEqual(false, arg)
|
52
|
+
#define assureNull(arg) assureEqual((void*)NULL, (void*)arg)
|
51
53
|
|
data/exe/arduino_ci_remote.rb
CHANGED
@@ -13,22 +13,36 @@ FIND_FILES_INDENT = 4
|
|
13
13
|
# Use some basic parsing to allow command-line overrides of config
|
14
14
|
class Parser
|
15
15
|
def self.parse(options)
|
16
|
-
|
17
|
-
|
16
|
+
unit_config = {}
|
17
|
+
output_options = {
|
18
|
+
skip_unittests: false,
|
19
|
+
skip_compilation: false,
|
20
|
+
ci_config: {
|
21
|
+
"unittest" => unit_config
|
22
|
+
},
|
23
|
+
}
|
18
24
|
|
19
25
|
opt_parser = OptionParser.new do |opts|
|
20
26
|
opts.banner = "Usage: #{File.basename(__FILE__)} [options]"
|
21
27
|
|
28
|
+
opts.on("--skip-unittests", "Don't run unit tests") do |p|
|
29
|
+
output_options[:skip_unittests] = p
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on("--skip-compilation", "Don't compile example sketches") do |p|
|
33
|
+
output_options[:skip_compilation] = p
|
34
|
+
end
|
35
|
+
|
22
36
|
opts.on("--testfile-select=GLOB", "Unit test file (or glob) to select") do |p|
|
23
|
-
|
24
|
-
|
25
|
-
|
37
|
+
unit_config["testfiles"] ||= {}
|
38
|
+
unit_config["testfiles"]["select"] ||= []
|
39
|
+
unit_config["testfiles"]["select"] << p
|
26
40
|
end
|
27
41
|
|
28
42
|
opts.on("--testfile-reject=GLOB", "Unit test file (or glob) to reject") do |p|
|
29
|
-
|
30
|
-
|
31
|
-
|
43
|
+
unit_config["testfiles"] ||= {}
|
44
|
+
unit_config["testfiles"]["reject"] ||= []
|
45
|
+
unit_config["testfiles"]["reject"] << p
|
32
46
|
end
|
33
47
|
|
34
48
|
opts.on("-h", "--help", "Prints this help") do
|
@@ -38,7 +52,7 @@ class Parser
|
|
38
52
|
end
|
39
53
|
|
40
54
|
opt_parser.parse!(options)
|
41
|
-
|
55
|
+
output_options
|
42
56
|
end
|
43
57
|
end
|
44
58
|
|
@@ -154,9 +168,11 @@ def display_files(pathname)
|
|
154
168
|
end
|
155
169
|
|
156
170
|
def perform_unit_tests(file_config)
|
157
|
-
|
158
|
-
|
159
|
-
|
171
|
+
if @cli_options[:skip_unittests]
|
172
|
+
inform("Skipping unit tests") { "as requested via command line" }
|
173
|
+
return
|
174
|
+
end
|
175
|
+
config = file_config.with_override_config(@cli_options[:ci_config])
|
160
176
|
cpp_library = ArduinoCI::CppLibrary.new(Pathname.new("."), @arduino_cmd.lib_dir)
|
161
177
|
|
162
178
|
# check GCC
|
@@ -220,6 +236,10 @@ def perform_unit_tests(file_config)
|
|
220
236
|
end
|
221
237
|
|
222
238
|
def perform_compilation_tests(config)
|
239
|
+
if @cli_options[:skip_compilation]
|
240
|
+
inform("Skipping compilation of examples") { "as requested via command line" }
|
241
|
+
return
|
242
|
+
end
|
223
243
|
|
224
244
|
# index the existing libraries
|
225
245
|
attempt("Indexing libraries") { @arduino_cmd.index_libraries } unless @arduino_cmd.libraries_indexed
|
@@ -228,17 +248,22 @@ def perform_compilation_tests(config)
|
|
228
248
|
installed_library_path = attempt("Installing library under test") do
|
229
249
|
@arduino_cmd.install_local_library(Pathname.new("."))
|
230
250
|
end
|
231
|
-
|
251
|
+
|
252
|
+
if !installed_library_path.nil? && installed_library_path.exist?
|
232
253
|
inform("Library installed at") { installed_library_path.to_s }
|
233
254
|
else
|
234
255
|
assure_multiline("Library installed successfully") do
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
256
|
+
if installed_library_path.nil?
|
257
|
+
puts @arduino_cmd.last_msg
|
258
|
+
else
|
259
|
+
# print out the contents of the deepest directory we actually find
|
260
|
+
@arduino_cmd.lib_dir.ascend do |path_part|
|
261
|
+
next unless path_part.exist?
|
262
|
+
|
263
|
+
break display_files(path_part)
|
264
|
+
end
|
265
|
+
false
|
240
266
|
end
|
241
|
-
false
|
242
267
|
end
|
243
268
|
end
|
244
269
|
library_examples = @arduino_cmd.library_examples(installed_library_path)
|
@@ -0,0 +1,387 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'arduino_ci'
|
3
|
+
require 'set'
|
4
|
+
require 'pathname'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
WIDTH = 80
|
8
|
+
FIND_FILES_INDENT = 4
|
9
|
+
|
10
|
+
@failure_count = 0
|
11
|
+
@passfail = proc { |result| result ? "✓" : "✗" }
|
12
|
+
|
13
|
+
# Use some basic parsing to allow command-line overrides of config
|
14
|
+
class Parser
|
15
|
+
def self.parse(options)
|
16
|
+
unit_config = {}
|
17
|
+
output_options = {
|
18
|
+
skip_unittests: false,
|
19
|
+
skip_compilation: false,
|
20
|
+
ci_config: {
|
21
|
+
"unittest" => unit_config
|
22
|
+
},
|
23
|
+
}
|
24
|
+
|
25
|
+
opt_parser = OptionParser.new do |opts|
|
26
|
+
opts.banner = "Usage: #{File.basename(__FILE__)} [options]"
|
27
|
+
|
28
|
+
opts.on("--skip-unittests", "Don't run unit tests") do |p|
|
29
|
+
output_options[:skip_unittests] = p
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on("--skip-compilation", "Don't compile example sketches") do |p|
|
33
|
+
output_options[:skip_compilation] = p
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on("--testfile-select=GLOB", "Unit test file (or glob) to select") do |p|
|
37
|
+
unit_config["testfiles"] ||= {}
|
38
|
+
unit_config["testfiles"]["select"] ||= []
|
39
|
+
unit_config["testfiles"]["select"] << p
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on("--testfile-reject=GLOB", "Unit test file (or glob) to reject") do |p|
|
43
|
+
unit_config["testfiles"] ||= {}
|
44
|
+
unit_config["testfiles"]["reject"] ||= []
|
45
|
+
unit_config["testfiles"]["reject"] << p
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on("-h", "--help", "Prints this help") do
|
49
|
+
puts opts
|
50
|
+
exit
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
opt_parser.parse!(options)
|
55
|
+
output_options
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Read in command line options and make them read-only
|
60
|
+
@cli_options = (Parser.parse ARGV).freeze
|
61
|
+
|
62
|
+
# terminate after printing any debug info. TODO: capture debug info
|
63
|
+
def terminate(final = nil)
|
64
|
+
puts "Failures: #{@failure_count}"
|
65
|
+
unless @failure_count.zero? || final
|
66
|
+
puts "Last message: #{@arduino_cmd.last_msg}"
|
67
|
+
puts "========== Stdout:"
|
68
|
+
puts @arduino_cmd.last_out
|
69
|
+
puts "========== Stderr:"
|
70
|
+
puts @arduino_cmd.last_err
|
71
|
+
end
|
72
|
+
retcode = @failure_count.zero? ? 0 : 1
|
73
|
+
exit(retcode)
|
74
|
+
end
|
75
|
+
|
76
|
+
# make a nice status line for an action and react to the action
|
77
|
+
# TODO / note to self: inform_multline is tougher to write
|
78
|
+
# without altering the signature because it only leaves space
|
79
|
+
# for the checkmark _after_ the multiline, it doesn't know how
|
80
|
+
# to make that conditionally the body
|
81
|
+
# @param message String the text of the progress indicator
|
82
|
+
# @param multiline boolean whether multiline output is expected
|
83
|
+
# @param mark_fn block (string) -> string that says how to describe the result
|
84
|
+
# @param on_fail_msg String custom message for failure
|
85
|
+
# @param tally_on_fail boolean whether to increment @failure_count
|
86
|
+
# @param abort_on_fail boolean whether to abort immediately on failure (i.e. if this is a fatal error)
|
87
|
+
def perform_action(message, multiline, mark_fn, on_fail_msg, tally_on_fail, abort_on_fail)
|
88
|
+
line = "#{message}... "
|
89
|
+
endline = "...#{message} "
|
90
|
+
if multiline
|
91
|
+
puts line
|
92
|
+
else
|
93
|
+
print line
|
94
|
+
end
|
95
|
+
STDOUT.flush
|
96
|
+
result = yield
|
97
|
+
mark = mark_fn.nil? ? "" : mark_fn.call(result)
|
98
|
+
# if multline, put checkmark at full width
|
99
|
+
print endline if multiline
|
100
|
+
puts mark.to_s.rjust(WIDTH - line.length, " ")
|
101
|
+
unless result
|
102
|
+
puts on_fail_msg unless on_fail_msg.nil?
|
103
|
+
@failure_count += 1 if tally_on_fail
|
104
|
+
# print out error messaging here if we've captured it
|
105
|
+
terminate if abort_on_fail
|
106
|
+
end
|
107
|
+
result
|
108
|
+
end
|
109
|
+
|
110
|
+
# Make a nice status for something that defers any failure code until script exit
|
111
|
+
def attempt(message, &block)
|
112
|
+
perform_action(message, false, @passfail, nil, true, false, &block)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Make a nice status for something that defers any failure code until script exit
|
116
|
+
def attempt_multiline(message, &block)
|
117
|
+
perform_action(message, true, @passfail, nil, true, false, &block)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Make a nice status for something that kills the script immediately on failure
|
121
|
+
FAILED_ASSURANCE_MESSAGE = "This may indicate a problem with ArduinoCI, or your configuration".freeze
|
122
|
+
def assure(message, &block)
|
123
|
+
perform_action(message, false, @passfail, FAILED_ASSURANCE_MESSAGE, true, true, &block)
|
124
|
+
end
|
125
|
+
|
126
|
+
def assure_multiline(message, &block)
|
127
|
+
perform_action(message, true, @passfail, FAILED_ASSURANCE_MESSAGE, true, true, &block)
|
128
|
+
end
|
129
|
+
|
130
|
+
def inform(message, &block)
|
131
|
+
perform_action(message, false, proc { |x| x }, nil, false, false, &block)
|
132
|
+
end
|
133
|
+
|
134
|
+
def inform_multiline(message, &block)
|
135
|
+
perform_action(message, true, nil, nil, false, false, &block)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Assure that a platform exists and return its definition
|
139
|
+
def assured_platform(purpose, name, config)
|
140
|
+
platform_definition = config.platform_definition(name)
|
141
|
+
assure("Requested #{purpose} platform '#{name}' is defined in 'platforms' YML") do
|
142
|
+
!platform_definition.nil?
|
143
|
+
end
|
144
|
+
platform_definition
|
145
|
+
end
|
146
|
+
|
147
|
+
# Return true if the file (or one of the dirs containing it) is hidden
|
148
|
+
def file_is_hidden_somewhere?(path)
|
149
|
+
# this is clunkly but pre-2.2-ish ruby doesn't return ascend as an enumerator
|
150
|
+
path.ascend do |part|
|
151
|
+
return true if part.basename.to_s.start_with? "."
|
152
|
+
end
|
153
|
+
false
|
154
|
+
end
|
155
|
+
|
156
|
+
# print out some files
|
157
|
+
def display_files(pathname)
|
158
|
+
# `find` doesn't follow symlinks, so we should instead
|
159
|
+
realpath = pathname.symlink? ? pathname.readlink : pathname
|
160
|
+
|
161
|
+
# suppress directories and dotfile-based things
|
162
|
+
all_files = realpath.find.select(&:file?)
|
163
|
+
non_hidden = all_files.reject { |path| file_is_hidden_somewhere?(path) }
|
164
|
+
|
165
|
+
# print files with an indent
|
166
|
+
margin = " " * FIND_FILES_INDENT
|
167
|
+
non_hidden.each { |p| puts "#{margin}#{p}" }
|
168
|
+
end
|
169
|
+
|
170
|
+
def perform_unit_tests(file_config)
|
171
|
+
<<<<<<< HEAD
|
172
|
+
puts file_config.to_h[:unittest].to_s
|
173
|
+
config = file_config.with_override_config(@cli_options)
|
174
|
+
puts config.to_h[:unittest].to_s
|
175
|
+
=======
|
176
|
+
if @cli_options[:skip_unittests]
|
177
|
+
inform("Skipping unit tests") { "as requested via command line" }
|
178
|
+
return
|
179
|
+
end
|
180
|
+
config = file_config.with_override_config(@cli_options[:ci_config])
|
181
|
+
>>>>>>> 9c4b0f0... Allow skipping of unittests and/or compilation in arduino_ci_remote.rb
|
182
|
+
cpp_library = ArduinoCI::CppLibrary.new(Pathname.new("."), @arduino_cmd.lib_dir)
|
183
|
+
|
184
|
+
# check GCC
|
185
|
+
compilers = config.compilers_to_use
|
186
|
+
assure("The set of compilers (#{compilers.length}) isn't empty") { !compilers.empty? }
|
187
|
+
compilers.each do |gcc_binary|
|
188
|
+
attempt_multiline("Checking #{gcc_binary} version") do
|
189
|
+
version = cpp_library.gcc_version(gcc_binary)
|
190
|
+
next nil unless version
|
191
|
+
|
192
|
+
puts version.split("\n").map { |l| " #{l}" }.join("\n")
|
193
|
+
version
|
194
|
+
end
|
195
|
+
inform("libasan availability for #{gcc_binary}") { cpp_library.libasan?(gcc_binary) }
|
196
|
+
end
|
197
|
+
|
198
|
+
# Ensure platforms exist for unit test, and save their info in all_platform_info keyed by name
|
199
|
+
all_platform_info = {}
|
200
|
+
config.platforms_to_unittest.each { |p| all_platform_info[p] = assured_platform("unittest", p, config) }
|
201
|
+
|
202
|
+
# iterate boards / tests
|
203
|
+
if !cpp_library.tests_dir.exist?
|
204
|
+
inform_multiline("Skipping unit tests; no tests dir at #{cpp_library.tests_dir}") do
|
205
|
+
puts " In case that's an error, this is what was found in the library:"
|
206
|
+
display_files(cpp_library.tests_dir.parent)
|
207
|
+
true
|
208
|
+
end
|
209
|
+
elsif cpp_library.test_files.empty?
|
210
|
+
inform_multiline("Skipping unit tests; no test files were found in #{cpp_library.tests_dir}") do
|
211
|
+
puts " In case that's an error, this is what was found in the tests directory:"
|
212
|
+
display_files(cpp_library.tests_dir)
|
213
|
+
true
|
214
|
+
end
|
215
|
+
elsif config.platforms_to_unittest.empty?
|
216
|
+
inform("Skipping unit tests") { "no platforms were requested" }
|
217
|
+
else
|
218
|
+
config.platforms_to_unittest.each do |p|
|
219
|
+
config.allowable_unittest_files(cpp_library.test_files).each do |unittest_path|
|
220
|
+
unittest_name = unittest_path.basename.to_s
|
221
|
+
compilers.each do |gcc_binary|
|
222
|
+
attempt_multiline("Unit testing #{unittest_name} with #{gcc_binary}") do
|
223
|
+
exe = cpp_library.build_for_test_with_configuration(
|
224
|
+
unittest_path,
|
225
|
+
config.aux_libraries_for_unittest,
|
226
|
+
gcc_binary,
|
227
|
+
config.gcc_config(p)
|
228
|
+
)
|
229
|
+
puts
|
230
|
+
unless exe
|
231
|
+
puts "Last command: #{cpp_library.last_cmd}"
|
232
|
+
puts cpp_library.last_out
|
233
|
+
puts cpp_library.last_err
|
234
|
+
next false
|
235
|
+
end
|
236
|
+
cpp_library.run_test_file(exe)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def perform_compilation_tests(config)
|
245
|
+
if @cli_options[:skip_compilation]
|
246
|
+
inform("Skipping compilation of examples") { "as requested via command line" }
|
247
|
+
return
|
248
|
+
end
|
249
|
+
|
250
|
+
# index the existing libraries
|
251
|
+
attempt("Indexing libraries") { @arduino_cmd.index_libraries } unless @arduino_cmd.libraries_indexed
|
252
|
+
|
253
|
+
# initialize library under test
|
254
|
+
installed_library_path = attempt("Installing library under test") do
|
255
|
+
@arduino_cmd.install_local_library(Pathname.new("."))
|
256
|
+
end
|
257
|
+
if installed_library_path.exist?
|
258
|
+
inform("Library installed at") { installed_library_path.to_s }
|
259
|
+
else
|
260
|
+
assure_multiline("Library installed successfully") do
|
261
|
+
# print out the contents of the deepest directory we actually find
|
262
|
+
@arduino_cmd.lib_dir.ascend do |path_part|
|
263
|
+
next unless path_part.exist?
|
264
|
+
|
265
|
+
break display_files(path_part)
|
266
|
+
end
|
267
|
+
false
|
268
|
+
end
|
269
|
+
end
|
270
|
+
library_examples = @arduino_cmd.library_examples(installed_library_path)
|
271
|
+
|
272
|
+
# gather up all required boards for compilation so we can install them up front.
|
273
|
+
# start with the "platforms to unittest" and add the examples
|
274
|
+
# while we're doing that, get the aux libraries as well
|
275
|
+
example_platform_info = {}
|
276
|
+
board_package_url = {}
|
277
|
+
aux_libraries = Set.new(config.aux_libraries_for_unittest + config.aux_libraries_for_build)
|
278
|
+
# while collecting the platforms, ensure they're defined
|
279
|
+
|
280
|
+
library_examples.each do |path|
|
281
|
+
ovr_config = config.from_example(path)
|
282
|
+
ovr_config.platforms_to_build.each do |platform|
|
283
|
+
# assure the platform if we haven't already
|
284
|
+
next if example_platform_info.key?(platform)
|
285
|
+
|
286
|
+
platform_info = assured_platform("library example", platform, config)
|
287
|
+
next if platform_info.nil?
|
288
|
+
|
289
|
+
example_platform_info[platform] = platform_info
|
290
|
+
package = platform_info[:package]
|
291
|
+
board_package_url[package] = ovr_config.package_url(package)
|
292
|
+
end
|
293
|
+
aux_libraries.merge(ovr_config.aux_libraries_for_build)
|
294
|
+
end
|
295
|
+
|
296
|
+
# with all platform info, we can extract unique packages and their urls
|
297
|
+
# do that, set the URLs, and download the packages
|
298
|
+
all_packages = example_platform_info.values.map { |v| v[:package] }.uniq.reject(&:nil?)
|
299
|
+
|
300
|
+
# inform about builtin packages
|
301
|
+
all_packages.select { |p| config.package_builtin?(p) }.each do |p|
|
302
|
+
inform("Using built-in board package") { p }
|
303
|
+
end
|
304
|
+
|
305
|
+
# make sure any non-builtin package has a URL defined
|
306
|
+
all_packages.reject { |p| config.package_builtin?(p) }.each do |p|
|
307
|
+
assure("Board package #{p} has a defined URL") { board_package_url[p] }
|
308
|
+
end
|
309
|
+
|
310
|
+
# set up all the board manager URLs.
|
311
|
+
# we can safely reject nils now, they would be for the builtins
|
312
|
+
all_urls = all_packages.map { |p| board_package_url[p] }.uniq.reject(&:nil?)
|
313
|
+
|
314
|
+
unless all_urls.empty?
|
315
|
+
assure("Setting board manager URLs") do
|
316
|
+
@arduino_cmd.board_manager_urls = all_urls
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
all_packages.each do |p|
|
321
|
+
assure("Installing board package #{p}") do
|
322
|
+
@arduino_cmd.install_boards(p)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
aux_libraries.each do |l|
|
327
|
+
if @arduino_cmd.library_present?(l)
|
328
|
+
inform("Using pre-existing library") { l.to_s }
|
329
|
+
else
|
330
|
+
assure("Installing aux library '#{l}'") { @arduino_cmd.install_library(l) }
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
last_board = nil
|
335
|
+
if config.platforms_to_build.empty?
|
336
|
+
inform("Skipping builds") { "no platforms were requested" }
|
337
|
+
return
|
338
|
+
elsif library_examples.empty?
|
339
|
+
inform_multiline("Skipping builds; no examples found in #{installed_library_path}") do
|
340
|
+
display_files(installed_library_path)
|
341
|
+
end
|
342
|
+
return
|
343
|
+
end
|
344
|
+
|
345
|
+
attempt("Setting compiler warning level") { @arduino_cmd.set_pref("compiler.warning_level", "all") }
|
346
|
+
|
347
|
+
# switching boards takes time, so iterate board first
|
348
|
+
# _then_ whichever examples match it
|
349
|
+
examples_by_platform = library_examples.each_with_object({}) do |example_path, acc|
|
350
|
+
ovr_config = config.from_example(example_path)
|
351
|
+
ovr_config.platforms_to_build.each do |p|
|
352
|
+
acc[p] = [] unless acc.key?(p)
|
353
|
+
acc[p] << example_path
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
examples_by_platform.each do |platform, example_paths|
|
358
|
+
board = example_platform_info[platform][:board]
|
359
|
+
assure("Switching to board for #{platform} (#{board})") { @arduino_cmd.use_board(board) } unless last_board == board
|
360
|
+
last_board = board
|
361
|
+
|
362
|
+
example_paths.each do |example_path|
|
363
|
+
example_name = File.basename(example_path)
|
364
|
+
attempt("Verifying #{example_name}") do
|
365
|
+
ret = @arduino_cmd.verify_sketch(example_path)
|
366
|
+
unless ret
|
367
|
+
puts
|
368
|
+
puts "Last command: #{@arduino_cmd.last_msg}"
|
369
|
+
puts @arduino_cmd.last_err
|
370
|
+
end
|
371
|
+
ret
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
end
|
377
|
+
|
378
|
+
# initialize command and config
|
379
|
+
config = ArduinoCI::CIConfig.default.from_project_library
|
380
|
+
|
381
|
+
@arduino_cmd = ArduinoCI::ArduinoInstallation.autolocate!
|
382
|
+
inform("Located Arduino binary") { @arduino_cmd.binary_path.to_s }
|
383
|
+
|
384
|
+
perform_unit_tests(config)
|
385
|
+
perform_compilation_tests(config)
|
386
|
+
|
387
|
+
terminate(true)
|
@@ -190,7 +190,10 @@ module ArduinoCI
|
|
190
190
|
# @param name [String] the library name
|
191
191
|
# @return [bool] whether the command succeeded
|
192
192
|
def _install_library(library_name)
|
193
|
-
|
193
|
+
result = run_and_capture(flag_install_library, library_name)
|
194
|
+
|
195
|
+
already_installed = result[:err].include?("Library is already installed: #{library_name}")
|
196
|
+
success = result[:success] || already_installed
|
194
197
|
|
195
198
|
@libraries_indexed = (@libraries_indexed || success) if library_name == WORKAROUND_LIB
|
196
199
|
success
|
@@ -237,7 +240,7 @@ module ArduinoCI
|
|
237
240
|
def update_library_index
|
238
241
|
# install random lib so the arduino IDE grabs a new library index
|
239
242
|
# see: https://github.com/arduino/Arduino/issues/3535
|
240
|
-
install_library(
|
243
|
+
install_library(WORKAROUND_LIB)
|
241
244
|
end
|
242
245
|
|
243
246
|
# use a particular board for compilation
|
@@ -319,7 +322,7 @@ module ArduinoCI
|
|
319
322
|
proj_file = example_path + e + "#{e}.ino"
|
320
323
|
proj_file.exist? ? proj_file.to_s : nil
|
321
324
|
end
|
322
|
-
files.reject(&:nil?)
|
325
|
+
files.reject(&:nil?).sort_by(&:to_s)
|
323
326
|
end
|
324
327
|
end
|
325
328
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require
|
1
|
+
require 'fileutils'
|
2
|
+
require 'net/http'
|
2
3
|
require 'open-uri'
|
3
4
|
require 'zip'
|
4
5
|
|
@@ -9,8 +10,11 @@ module ArduinoCI
|
|
9
10
|
# Manage the OS-specific download & install of Arduino
|
10
11
|
class ArduinoDownloader
|
11
12
|
|
12
|
-
|
13
|
+
# @param desired_ide_version [string] Version string e.g. 1.8.7
|
14
|
+
# @param output [IO] $stdout, $stderr, File.new(/dev/null, 'w'), etc. where console output will be sent
|
15
|
+
def initialize(desired_ide_version, output = $stdout)
|
13
16
|
@desired_ide_version = desired_ide_version
|
17
|
+
@output = output
|
14
18
|
end
|
15
19
|
|
16
20
|
# Provide guidelines to the implementer of this class
|
@@ -115,15 +119,15 @@ module ArduinoCI
|
|
115
119
|
total_size += size
|
116
120
|
needed_dots = (total_size / chunk_size).to_i
|
117
121
|
unprinted_dots = needed_dots - dots
|
118
|
-
print("." * unprinted_dots) if unprinted_dots > 0
|
122
|
+
@output.print("." * unprinted_dots) if unprinted_dots > 0
|
119
123
|
dots = needed_dots
|
120
124
|
end
|
121
125
|
|
122
126
|
open(package_url, ssl_verify_mode: 0, progress_proc: dot_printer) do |url|
|
123
127
|
File.open(package_file, 'wb') { |file| file.write(url.read) }
|
124
128
|
end
|
125
|
-
rescue Net::OpenTimeout, Net::ReadTimeout => e
|
126
|
-
puts "\nArduino force-install failed downloading #{package_url}: #{e}"
|
129
|
+
rescue Net::OpenTimeout, Net::ReadTimeout, OpenURI::HTTPError, URI::InvalidURIError => e
|
130
|
+
@output.puts "\nArduino force-install failed downloading #{package_url}: #{e}"
|
127
131
|
end
|
128
132
|
|
129
133
|
# Extract the package_file to extracted_file
|
@@ -133,7 +137,7 @@ module ArduinoCI
|
|
133
137
|
batch_size = [1, (zip.size / 100).to_i].max
|
134
138
|
dots = 0
|
135
139
|
zip.each do |file|
|
136
|
-
print "." if (dots % batch_size).zero?
|
140
|
+
@output.print "." if (dots % batch_size).zero?
|
137
141
|
file.restore_permissions = true
|
138
142
|
file.extract { accept_all }
|
139
143
|
dots += 1
|
@@ -153,7 +157,7 @@ module ArduinoCI
|
|
153
157
|
def execute
|
154
158
|
error_preparing = prepare
|
155
159
|
unless error_preparing.nil?
|
156
|
-
puts "Arduino force-install failed preparation: #{error_preparing}"
|
160
|
+
@output.puts "Arduino force-install failed preparation: #{error_preparing}"
|
157
161
|
return false
|
158
162
|
end
|
159
163
|
|
@@ -161,32 +165,32 @@ module ArduinoCI
|
|
161
165
|
|
162
166
|
loop do
|
163
167
|
if File.exist? package_file
|
164
|
-
puts "Arduino package seems to have been downloaded already" if attempts.zero?
|
168
|
+
@output.puts "Arduino package seems to have been downloaded already" if attempts.zero?
|
165
169
|
break
|
166
170
|
elsif attempts >= DOWNLOAD_ATTEMPTS
|
167
|
-
break puts "After #{DOWNLOAD_ATTEMPTS} attempts, failed to download #{package_url}"
|
171
|
+
break @output.puts "After #{DOWNLOAD_ATTEMPTS} attempts, failed to download #{package_url}"
|
168
172
|
else
|
169
|
-
print "Attempting to download Arduino package with #{downloader}"
|
173
|
+
@output.print "Attempting to download Arduino package with #{downloader}"
|
170
174
|
download
|
171
|
-
puts
|
175
|
+
@output.puts
|
172
176
|
end
|
173
177
|
attempts += 1
|
174
178
|
end
|
175
179
|
|
176
180
|
if File.exist? extracted_file
|
177
|
-
puts "Arduino package seems to have been extracted already"
|
181
|
+
@output.puts "Arduino package seems to have been extracted already"
|
178
182
|
elsif File.exist? package_file
|
179
|
-
print "Extracting archive with #{extracter}"
|
183
|
+
@output.print "Extracting archive with #{extracter}"
|
180
184
|
extract
|
181
|
-
puts
|
185
|
+
@output.puts
|
182
186
|
end
|
183
187
|
|
184
188
|
if File.exist? self.class.force_install_location
|
185
|
-
puts "Arduino package seems to have been installed already"
|
189
|
+
@output.puts "Arduino package seems to have been installed already"
|
186
190
|
elsif File.exist? extracted_file
|
187
191
|
install
|
188
192
|
else
|
189
|
-
puts "Could not find extracted archive (tried #{extracted_file})"
|
193
|
+
@output.puts "Could not find extracted archive (tried #{extracted_file})"
|
190
194
|
end
|
191
195
|
|
192
196
|
File.exist? self.class.force_install_location
|
@@ -2,6 +2,7 @@ require 'base64'
|
|
2
2
|
require 'shellwords' # fingers crossed this works on win32
|
3
3
|
require 'win32/registry'
|
4
4
|
require "arduino_ci/arduino_downloader"
|
5
|
+
require 'net/http'
|
5
6
|
require "fileutils"
|
6
7
|
|
7
8
|
module ArduinoCI
|
@@ -30,6 +31,8 @@ module ArduinoCI
|
|
30
31
|
open(URI.parse(package_url), ssl_verify_mode: 0) do |url|
|
31
32
|
File.open(package_file, 'wb') { |file| file.write(url.read) }
|
32
33
|
end
|
34
|
+
rescue Net::OpenTimeout, Net::ReadTimeout, OpenURI::HTTPError, URI::InvalidURIError => e
|
35
|
+
@output.puts "\nArduino force-install failed downloading #{package_url}: #{e}"
|
33
36
|
end
|
34
37
|
|
35
38
|
# Move the extracted package file from extracted_file to the force_install_location
|
@@ -97,25 +97,25 @@ module ArduinoCI
|
|
97
97
|
|
98
98
|
# Attempt to find a workable Arduino executable across platforms, and install it if we don't
|
99
99
|
# @return [ArduinoCI::ArduinoCmd] an instance of a command
|
100
|
-
def autolocate!
|
100
|
+
def autolocate!(output = $stdout)
|
101
101
|
candidate = autolocate
|
102
102
|
return candidate unless candidate.nil?
|
103
103
|
|
104
104
|
# force the install
|
105
|
-
raise ArduinoInstallationError, "Failed to force-install Arduino" unless force_install
|
105
|
+
raise ArduinoInstallationError, "Failed to force-install Arduino" unless force_install(output)
|
106
106
|
|
107
107
|
autolocate
|
108
108
|
end
|
109
109
|
|
110
110
|
# Forcibly install Arduino from the web
|
111
111
|
# @return [bool] Whether the command succeeded
|
112
|
-
def force_install
|
112
|
+
def force_install(output = $stdout, version = DESIRED_ARDUINO_IDE_VERSION)
|
113
113
|
worker_class = case Host.os
|
114
114
|
when :osx then ArduinoDownloaderOSX
|
115
115
|
when :windows then ArduinoDownloaderWindows
|
116
116
|
when :linux then ArduinoDownloaderLinux
|
117
117
|
end
|
118
|
-
worker = worker_class.new(
|
118
|
+
worker = worker_class.new(version, output)
|
119
119
|
worker.execute
|
120
120
|
end
|
121
121
|
|
@@ -32,6 +32,9 @@ module ArduinoCI
|
|
32
32
|
# @return [String] the last command
|
33
33
|
attr_reader :last_cmd
|
34
34
|
|
35
|
+
# @return [Array<Pathname>] Directories suspected of being vendor-bundle
|
36
|
+
attr_reader :vendor_bundle_cache
|
37
|
+
|
35
38
|
# @param base_dir [Pathname] The path to the library being tested
|
36
39
|
# @param arduino_lib_dir [Pathname] The path to the libraries directory
|
37
40
|
def initialize(base_dir, arduino_lib_dir)
|
@@ -45,26 +48,57 @@ module ArduinoCI
|
|
45
48
|
@last_out = ""
|
46
49
|
@last_msg = ""
|
47
50
|
@has_libasan_cache = {}
|
51
|
+
@vendor_bundle_cache = nil
|
48
52
|
end
|
49
53
|
|
50
54
|
# Guess whether a file is part of the vendor bundle (indicating we should ignore it).
|
51
55
|
#
|
52
|
-
#
|
56
|
+
# A safe way to do this seems to be to check whether any of the installed gems
|
57
|
+
# appear to be a subdirectory of (but not equal to) the working directory.
|
58
|
+
# That gets us the vendor directory (or multiple directories). We can check
|
59
|
+
# if the given path is contained by any of those.
|
60
|
+
#
|
53
61
|
# @param path [Pathname] The path to check
|
54
62
|
# @return [bool]
|
55
63
|
def vendor_bundle?(path)
|
56
|
-
#
|
57
|
-
|
58
|
-
|
64
|
+
# Cache bundle information, as it is (1) time consuming to fetch and (2) not going to change while we run
|
65
|
+
if @vendor_bundle_cache.nil?
|
66
|
+
bundle_info = Host.run_and_capture("bundle show --paths")
|
67
|
+
if !bundle_info[:success]
|
68
|
+
# if the bundle show command fails, assume there isn't a bundle
|
69
|
+
@vendor_bundle_cache = false
|
70
|
+
else
|
71
|
+
# Get all the places where gems are stored. We combine a few things here:
|
72
|
+
# by preemptively switching to the parent directory, we can both ensure that
|
73
|
+
# we skip any gems that are equal to the working directory AND exploit some
|
74
|
+
# commonality in the paths to cut down our search locations
|
75
|
+
#
|
76
|
+
# NOT CONFUSING THE WORKING DIRECTORY WITH VENDOR BUNDLE IS SUPER IMPORTANT
|
77
|
+
# because if we do, we won't be able to run CI on this library itself.
|
78
|
+
bundle_paths = bundle_info[:out].lines
|
79
|
+
.map { |l| Pathname.new(l.chomp) }
|
80
|
+
.select(&:exist?)
|
81
|
+
.map(&:realpath)
|
82
|
+
.map(&:parent)
|
83
|
+
.uniq
|
84
|
+
wd = Pathname.new(".").realpath
|
85
|
+
@vendor_bundle_cache = bundle_paths.select do |gem_path|
|
86
|
+
gem_path.ascend do |part|
|
87
|
+
break true if wd == part
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
59
92
|
|
60
|
-
|
93
|
+
# no bundle existed
|
94
|
+
return false if @vendor_bundle_cache == false
|
61
95
|
|
62
|
-
#
|
63
|
-
|
64
|
-
|
65
|
-
|
96
|
+
# With vendor bundles located, check this file against those
|
97
|
+
@vendor_bundle_cache.any? do |gem_path|
|
98
|
+
path.ascend do |part|
|
99
|
+
break true if gem_path == part
|
100
|
+
end
|
66
101
|
end
|
67
|
-
false
|
68
102
|
end
|
69
103
|
|
70
104
|
# Guess whether a file is part of the tests/ dir (indicating library compilation should ignore it).
|
@@ -109,7 +143,8 @@ module ArduinoCI
|
|
109
143
|
real = some_dir.realpath
|
110
144
|
files = Find.find(real).map { |p| Pathname.new(p) }.reject(&:directory?)
|
111
145
|
cpp = files.select { |path| CPP_EXTENSIONS.include?(path.extname.downcase) }
|
112
|
-
cpp.reject { |path| path.basename.to_s.start_with?(".") }
|
146
|
+
not_hidden = cpp.reject { |path| path.basename.to_s.start_with?(".") }
|
147
|
+
not_hidden.sort_by(&:to_s)
|
113
148
|
end
|
114
149
|
|
115
150
|
# CPP files that are part of the project library under test
|
data/lib/arduino_ci/version.rb
CHANGED
data/misc/default.yml
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: 0.1.
|
4
|
+
version: 0.1.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian Katz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-01-
|
11
|
+
date: 2019-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: os
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.15'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: keepachangelog_manager
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.0.1
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.0.1
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rspec
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -99,6 +113,8 @@ email:
|
|
99
113
|
- ianfixes@gmail.com
|
100
114
|
executables:
|
101
115
|
- arduino_ci_remote.rb
|
116
|
+
- arduino_ci_remote.rb.orig
|
117
|
+
- arduino_library_location.rb
|
102
118
|
- ensure_arduino_installation.rb
|
103
119
|
- libasan.rb
|
104
120
|
extensions: []
|
@@ -408,6 +424,8 @@ files:
|
|
408
424
|
- cpp/unittest/Assertion.h
|
409
425
|
- cpp/unittest/Compare.h
|
410
426
|
- exe/arduino_ci_remote.rb
|
427
|
+
- exe/arduino_ci_remote.rb.orig
|
428
|
+
- exe/arduino_library_location.rb
|
411
429
|
- exe/ensure_arduino_installation.rb
|
412
430
|
- exe/libasan.rb
|
413
431
|
- lib/arduino_ci.rb
|