arduino_ci 0.3.0 → 1.3.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 +125 -69
- data/REFERENCE.md +711 -0
- data/cpp/arduino/Arduino.h +1 -7
- data/cpp/arduino/ArduinoDefines.h +3 -0
- data/cpp/arduino/AvrMath.h +117 -17
- data/cpp/arduino/Client.h +27 -0
- data/cpp/arduino/EEPROM.h +64 -0
- data/cpp/arduino/Godmode.cpp +7 -0
- data/cpp/arduino/Godmode.h +121 -15
- data/cpp/arduino/HardwareSerial.h +4 -4
- data/cpp/arduino/IPAddress.h +59 -0
- data/cpp/arduino/Print.h +9 -12
- data/cpp/arduino/Printable.h +8 -0
- data/cpp/arduino/SPI.h +11 -3
- data/cpp/arduino/Server.h +5 -0
- data/cpp/arduino/Udp.h +27 -0
- data/cpp/arduino/Wire.h +197 -77
- data/cpp/arduino/avr/io.h +10 -1
- data/cpp/arduino/avr/pgmspace.h +76 -46
- data/cpp/unittest/ArduinoUnitTests.h +32 -0
- data/cpp/unittest/Assertion.h +54 -26
- data/cpp/unittest/Compare.h +58 -51
- data/cpp/unittest/OstreamHelpers.h +4 -0
- data/exe/arduino_ci.rb +538 -0
- data/exe/arduino_ci_remote.rb +2 -393
- data/exe/arduino_library_location.rb +2 -2
- data/exe/ensure_arduino_installation.rb +7 -1
- data/lib/arduino_ci.rb +1 -0
- data/lib/arduino_ci/arduino_backend.rb +238 -0
- data/lib/arduino_ci/arduino_downloader.rb +43 -73
- data/lib/arduino_ci/arduino_downloader_linux.rb +17 -55
- data/lib/arduino_ci/arduino_downloader_osx.rb +21 -33
- data/lib/arduino_ci/arduino_downloader_windows.rb +11 -53
- data/lib/arduino_ci/arduino_installation.rb +18 -80
- data/lib/arduino_ci/ci_config.rb +8 -11
- data/lib/arduino_ci/cpp_library.rb +250 -59
- data/lib/arduino_ci/host.rb +59 -4
- data/lib/arduino_ci/library_properties.rb +101 -0
- data/lib/arduino_ci/version.rb +1 -1
- data/misc/default.yml +57 -6
- metadata +19 -87
- data/cpp/arduino/Arduino.h.orig +0 -143
- data/exe/libasan.rb +0 -29
- data/lib/arduino_ci/arduino_cmd.rb +0 -332
- data/lib/arduino_ci/arduino_cmd_linux.rb +0 -17
- data/lib/arduino_ci/arduino_cmd_linux_builder.rb +0 -19
- data/lib/arduino_ci/arduino_cmd_osx.rb +0 -17
- data/lib/arduino_ci/arduino_cmd_windows.rb +0 -17
data/cpp/arduino/Arduino.h.orig
DELETED
@@ -1,143 +0,0 @@
|
|
1
|
-
#pragma once
|
2
|
-
/*
|
3
|
-
Mock Arduino.h library.
|
4
|
-
|
5
|
-
Where possible, variable names from the Arduino library are used to avoid conflicts
|
6
|
-
|
7
|
-
*/
|
8
|
-
// Chars and strings
|
9
|
-
|
10
|
-
#include "ArduinoDefines.h"
|
11
|
-
|
12
|
-
#include "WCharacter.h"
|
13
|
-
#include "WString.h"
|
14
|
-
#include "Print.h"
|
15
|
-
#include "Stream.h"
|
16
|
-
#include "HardwareSerial.h"
|
17
|
-
#include "SPI.h"
|
18
|
-
#include "Nullptr.h"
|
19
|
-
|
20
|
-
typedef bool boolean;
|
21
|
-
typedef uint8_t byte;
|
22
|
-
|
23
|
-
#include "binary.h"
|
24
|
-
|
25
|
-
// Math and Trig
|
26
|
-
#include "AvrMath.h"
|
27
|
-
|
28
|
-
#include "Godmode.h"
|
29
|
-
|
30
|
-
|
31
|
-
// Bits and Bytes
|
32
|
-
#define bit(b) (1UL << (b))
|
33
|
-
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
34
|
-
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
|
35
|
-
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
|
36
|
-
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
|
37
|
-
#define highByte(w) ((uint8_t) ((w) >> 8))
|
38
|
-
#define lowByte(w) ((uint8_t) ((w) & 0xff))
|
39
|
-
|
40
|
-
// Arduino defines this
|
41
|
-
#define _NOP() do { 0; } while (0)
|
42
|
-
|
43
|
-
// might as well use that NO-op macro for these, while unit testing
|
44
|
-
// you need interrupts? interrupt yourself
|
45
|
-
#define yield() _NOP()
|
46
|
-
#define interrupts() _NOP()
|
47
|
-
#define noInterrupts() _NOP()
|
48
|
-
|
49
|
-
// TODO: correctly establish this per-board!
|
50
|
-
#define F_CPU 1000000UL
|
51
|
-
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
|
52
|
-
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
|
53
|
-
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
|
54
|
-
|
55
|
-
typedef unsigned int word;
|
56
|
-
|
57
|
-
#define bit(b) (1UL << (b))
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
/*
|
62
|
-
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
|
63
|
-
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout);
|
64
|
-
|
65
|
-
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
|
66
|
-
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
|
67
|
-
|
68
|
-
*/
|
69
|
-
|
70
|
-
// Get the bit location within the hardware port of the given virtual pin.
|
71
|
-
// This comes from the pins_*.c file for the active board configuration.
|
72
|
-
|
73
|
-
#define analogInPinToBit(P) (P)
|
74
|
-
#define digitalPinToInterrupt(P) (P)
|
75
|
-
|
76
|
-
/*
|
77
|
-
// On the ATmega1280, the addresses of some of the port registers are
|
78
|
-
// greater than 255, so we can't store them in uint8_t's.
|
79
|
-
extern const uint16_t PROGMEM port_to_mode_PGM[];
|
80
|
-
extern const uint16_t PROGMEM port_to_input_PGM[];
|
81
|
-
extern const uint16_t PROGMEM port_to_output_PGM[];
|
82
|
-
|
83
|
-
extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
|
84
|
-
// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
|
85
|
-
extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
|
86
|
-
extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
|
87
|
-
|
88
|
-
// Get the bit location within the hardware port of the given virtual pin.
|
89
|
-
// This comes from the pins_*.c file for the active board configuration.
|
90
|
-
//
|
91
|
-
// These perform slightly better as macros compared to inline functions
|
92
|
-
//
|
93
|
-
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
|
94
|
-
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
|
95
|
-
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
|
96
|
-
#define analogInPinToBit(P) (P)
|
97
|
-
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
|
98
|
-
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
|
99
|
-
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
|
100
|
-
|
101
|
-
*/
|
102
|
-
|
103
|
-
|
104
|
-
/* TODO
|
105
|
-
|
106
|
-
// USB
|
107
|
-
#include "USBAPI.h"
|
108
|
-
Keyboard
|
109
|
-
Mouse
|
110
|
-
|
111
|
-
*/
|
112
|
-
|
113
|
-
// uint16_t makeWord(uint16_t w);
|
114
|
-
// uint16_t makeWord(byte h, byte l);
|
115
|
-
inline unsigned int makeWord(unsigned int w) { return w; }
|
116
|
-
inline unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; }
|
117
|
-
|
118
|
-
#define word(...) makeWord(__VA_ARGS__)
|
119
|
-
|
120
|
-
<<<<<<< Updated upstream
|
121
|
-
|
122
|
-
=======
|
123
|
-
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
124
|
-
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
125
|
-
|
126
|
-
// audio is taken care of in GODMODE
|
127
|
-
|
128
|
-
|
129
|
-
// BIG TODO ON THIS ONE
|
130
|
-
// $ find . | grep pins_
|
131
|
-
// ./arduino-1.8.5/hardware/arduino/avr/variants/circuitplay32u4/pins_arduino.h
|
132
|
-
// ./arduino-1.8.5/hardware/arduino/avr/variants/eightanaloginputs/pins_arduino.h
|
133
|
-
// ./arduino-1.8.5/hardware/arduino/avr/variants/ethernet/pins_arduino.h
|
134
|
-
// ./arduino-1.8.5/hardware/arduino/avr/variants/gemma/pins_arduino.h
|
135
|
-
// ./arduino-1.8.5/hardware/arduino/avr/variants/leonardo/pins_arduino.h
|
136
|
-
// ./arduino-1.8.5/hardware/arduino/avr/variants/mega/pins_arduino.h
|
137
|
-
// ./arduino-1.8.5/hardware/arduino/avr/variants/micro/pins_arduino.h
|
138
|
-
// ./arduino-1.8.5/hardware/arduino/avr/variants/robot_control/pins_arduino.h
|
139
|
-
// ./arduino-1.8.5/hardware/arduino/avr/variants/robot_motor/pins_arduino.h
|
140
|
-
// ./arduino-1.8.5/hardware/arduino/avr/variants/standard/pins_arduino.h
|
141
|
-
// ./arduino-1.8.5/hardware/arduino/avr/variants/yun/pins_arduino.h
|
142
|
-
// #include "pins_arduino.h"
|
143
|
-
>>>>>>> Stashed changes
|
data/exe/libasan.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
require 'arduino_ci'
|
3
|
-
require 'set'
|
4
|
-
require 'pathname'
|
5
|
-
|
6
|
-
WIDTH = 80
|
7
|
-
|
8
|
-
# initialize command and config
|
9
|
-
config = ArduinoCI::CIConfig.default.from_project_library
|
10
|
-
@arduino_cmd = ArduinoCI::ArduinoInstallation.autolocate!
|
11
|
-
|
12
|
-
# initialize library under test
|
13
|
-
installed_library_path = @arduino_cmd.install_local_library(Pathname.new("."))
|
14
|
-
cpp_library = ArduinoCI::CppLibrary.new(installed_library_path, @arduino_cmd.lib_dir)
|
15
|
-
|
16
|
-
# check GCC
|
17
|
-
compilers = config.compilers_to_use
|
18
|
-
compilers.each do |gcc_binary|
|
19
|
-
puts "Checking #{gcc_binary} version"
|
20
|
-
puts cpp_library.gcc_version(gcc_binary).split("\n").map { |l| " #{l}" }.join("\n")
|
21
|
-
exists = cpp_library.libasan?(gcc_binary)
|
22
|
-
puts "libasan availability for #{gcc_binary}: #{exists}"
|
23
|
-
next unless exists
|
24
|
-
|
25
|
-
puts "========== Stdout:"
|
26
|
-
puts @arduino_cmd.last_out
|
27
|
-
puts "========== Stderr:"
|
28
|
-
puts @arduino_cmd.last_err
|
29
|
-
end
|
@@ -1,332 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
require 'pathname'
|
3
|
-
|
4
|
-
# workaround for https://github.com/arduino/Arduino/issues/3535
|
5
|
-
WORKAROUND_LIB = "USBHost".freeze
|
6
|
-
|
7
|
-
module ArduinoCI
|
8
|
-
|
9
|
-
# To report errors that we can't resolve or possibly even explain
|
10
|
-
class ArduinoExecutionError < StandardError; end
|
11
|
-
|
12
|
-
# Wrap the Arduino executable. This requires, in some cases, a faked display.
|
13
|
-
class ArduinoCmd
|
14
|
-
|
15
|
-
# Enable a shortcut syntax for command line flags
|
16
|
-
# @param name [String] What the flag will be called (prefixed with 'flag_')
|
17
|
-
# @return [void]
|
18
|
-
# @macro [attach] flag
|
19
|
-
# The text of the command line flag for $1
|
20
|
-
# @!attribute [r] flag_$1
|
21
|
-
# @return [String] the text of the command line flag (`$2` in this case)
|
22
|
-
def self.flag(name, text = nil)
|
23
|
-
text = "(flag #{name} not defined)" if text.nil?
|
24
|
-
self.class_eval("def flag_#{name};\"#{text}\";end", __FILE__, __LINE__)
|
25
|
-
end
|
26
|
-
|
27
|
-
# the array of command components to launch the Arduino executable
|
28
|
-
# @return [Array<String>]
|
29
|
-
attr_accessor :base_cmd
|
30
|
-
|
31
|
-
# the actual path to the executable on this platform
|
32
|
-
# @return [Pathname]
|
33
|
-
attr_accessor :binary_path
|
34
|
-
|
35
|
-
# part of a workaround for https://github.com/arduino/Arduino/issues/3535
|
36
|
-
attr_reader :libraries_indexed
|
37
|
-
|
38
|
-
# @return [String] STDOUT of the most recently-run command
|
39
|
-
attr_reader :last_out
|
40
|
-
|
41
|
-
# @return [String] STDERR of the most recently-run command
|
42
|
-
attr_reader :last_err
|
43
|
-
|
44
|
-
# @return [String] the most recently-run command
|
45
|
-
attr_reader :last_msg
|
46
|
-
|
47
|
-
# set the command line flags (undefined for now).
|
48
|
-
# These vary between gui/cli. Inline comments added for greppability
|
49
|
-
flag :get_pref # flag_get_pref
|
50
|
-
flag :set_pref # flag_set_pref
|
51
|
-
flag :save_prefs # flag_save_prefs
|
52
|
-
flag :use_board # flag_use_board
|
53
|
-
flag :install_boards # flag_install_boards
|
54
|
-
flag :install_library # flag_install_library
|
55
|
-
flag :verify # flag_verify
|
56
|
-
|
57
|
-
def initialize
|
58
|
-
@prefs_cache = {}
|
59
|
-
@prefs_fetched = false
|
60
|
-
@libraries_indexed = false
|
61
|
-
@last_out = ""
|
62
|
-
@last_err = ""
|
63
|
-
@last_msg = ""
|
64
|
-
end
|
65
|
-
|
66
|
-
# Convert a preferences dump into a flat hash
|
67
|
-
# @param arduino_output [String] The raw Arduino executable output
|
68
|
-
# @return [Hash] preferences as a hash
|
69
|
-
def parse_pref_string(arduino_output)
|
70
|
-
lines = arduino_output.split("\n").select { |l| l.include? "=" }
|
71
|
-
ret = lines.each_with_object({}) do |e, acc|
|
72
|
-
parts = e.split("=", 2)
|
73
|
-
acc[parts[0]] = parts[1]
|
74
|
-
acc
|
75
|
-
end
|
76
|
-
ret
|
77
|
-
end
|
78
|
-
|
79
|
-
# @return [String] the path to the Arduino libraries directory
|
80
|
-
def lib_dir
|
81
|
-
Pathname.new(get_pref("sketchbook.path")) + "libraries"
|
82
|
-
end
|
83
|
-
|
84
|
-
# fetch preferences in their raw form
|
85
|
-
# @return [String] Preferences as a set of lines
|
86
|
-
def _prefs_raw
|
87
|
-
resp = run_and_capture(flag_get_pref)
|
88
|
-
fail_msg = "Arduino binary failed to operate as expected; you will have to troubleshoot it manually"
|
89
|
-
raise ArduinoExecutionError, "#{fail_msg}. The command was #{@last_msg}" unless resp[:success]
|
90
|
-
|
91
|
-
@prefs_fetched = true
|
92
|
-
resp[:out]
|
93
|
-
end
|
94
|
-
|
95
|
-
# Get the Arduino preferences, from cache if possible
|
96
|
-
# @return [Hash] The full set of preferences
|
97
|
-
def prefs
|
98
|
-
prefs_raw = _prefs_raw unless @prefs_fetched
|
99
|
-
return nil if prefs_raw.nil?
|
100
|
-
|
101
|
-
@prefs_cache = parse_pref_string(prefs_raw)
|
102
|
-
@prefs_cache.clone
|
103
|
-
end
|
104
|
-
|
105
|
-
# get a preference key
|
106
|
-
# @param key [String] The preferences key to look up
|
107
|
-
# @return [String] The preference value
|
108
|
-
def get_pref(key)
|
109
|
-
data = @prefs_fetched ? @prefs_cache : prefs
|
110
|
-
data[key]
|
111
|
-
end
|
112
|
-
|
113
|
-
# underlying preference-setter.
|
114
|
-
# @param key [String] The preference name
|
115
|
-
# @param value [String] The value to set to
|
116
|
-
# @return [bool] whether the command succeeded
|
117
|
-
def _set_pref(key, value)
|
118
|
-
run_and_capture(flag_set_pref, "#{key}=#{value}", flag_save_prefs)[:success]
|
119
|
-
end
|
120
|
-
|
121
|
-
# set a preference key/value pair, and update the cache.
|
122
|
-
# @param key [String] the preference key
|
123
|
-
# @param value [String] the preference value
|
124
|
-
# @return [bool] whether the command succeeded
|
125
|
-
def set_pref(key, value)
|
126
|
-
prefs unless @prefs_fetched # update cache first
|
127
|
-
success = _set_pref(key, value)
|
128
|
-
@prefs_cache[key] = value if success
|
129
|
-
success
|
130
|
-
end
|
131
|
-
|
132
|
-
def _wrap_run(work_fn, *args, **kwargs)
|
133
|
-
# do some work to extract & merge environment variables if they exist
|
134
|
-
has_env = !args.empty? && args[0].class == Hash
|
135
|
-
env_vars = has_env ? args[0] : {}
|
136
|
-
actual_args = has_env ? args[1..-1] : args # need to shift over if we extracted args
|
137
|
-
full_args = @base_cmd + actual_args
|
138
|
-
full_cmd = env_vars.empty? ? full_args : [env_vars] + full_args
|
139
|
-
|
140
|
-
shell_vars = env_vars.map { |k, v| "#{k}=#{v}" }.join(" ")
|
141
|
-
@last_msg = " $ #{shell_vars} #{full_args.join(' ')}"
|
142
|
-
work_fn.call(*full_cmd, **kwargs)
|
143
|
-
end
|
144
|
-
|
145
|
-
# build and run the arduino command
|
146
|
-
def run_and_output(*args, **kwargs)
|
147
|
-
_wrap_run((proc { |*a, **k| Host.run_and_output(*a, **k) }), *args, **kwargs)
|
148
|
-
end
|
149
|
-
|
150
|
-
# run a command and capture its output
|
151
|
-
# @return [Hash] {:out => String, :err => String, :success => bool}
|
152
|
-
def run_and_capture(*args, **kwargs)
|
153
|
-
ret = _wrap_run((proc { |*a, **k| Host.run_and_capture(*a, **k) }), *args, **kwargs)
|
154
|
-
@last_err = ret[:err]
|
155
|
-
@last_out = ret[:out]
|
156
|
-
ret
|
157
|
-
end
|
158
|
-
|
159
|
-
# Board manager URLs
|
160
|
-
# @return [Array<String>] The additional URLs used by the board manager
|
161
|
-
def board_manager_urls
|
162
|
-
url_list = get_pref("boardsmanager.additional.urls")
|
163
|
-
return [] if url_list.nil?
|
164
|
-
|
165
|
-
url_list.split(",")
|
166
|
-
end
|
167
|
-
|
168
|
-
# Set board manager URLs
|
169
|
-
# @return [Array<String>] The additional URLs used by the board manager
|
170
|
-
def board_manager_urls=(all_urls)
|
171
|
-
set_pref("boardsmanager.additional.urls", all_urls.join(","))
|
172
|
-
end
|
173
|
-
|
174
|
-
# check whether a board is installed
|
175
|
-
# we do this by just selecting a board.
|
176
|
-
# the arduino binary will error if unrecognized and do a successful no-op if it's installed
|
177
|
-
# @param boardname [String] The board to test
|
178
|
-
# @return [bool] Whether the board is installed
|
179
|
-
def board_installed?(boardname)
|
180
|
-
run_and_capture(flag_use_board, boardname)[:success]
|
181
|
-
end
|
182
|
-
|
183
|
-
# install a board by name
|
184
|
-
# @param name [String] the board name
|
185
|
-
# @return [bool] whether the command succeeded
|
186
|
-
def install_boards(boardfamily)
|
187
|
-
# TODO: find out why IO.pipe fails but File::NULL succeeds :(
|
188
|
-
result = run_and_capture(flag_install_boards, boardfamily)
|
189
|
-
already_installed = result[:err].include?("Platform is already installed!")
|
190
|
-
result[:success] || already_installed
|
191
|
-
end
|
192
|
-
|
193
|
-
# install a library by name
|
194
|
-
# @param name [String] the library name
|
195
|
-
# @return [bool] whether the command succeeded
|
196
|
-
def _install_library(library_name)
|
197
|
-
result = run_and_capture(flag_install_library, library_name)
|
198
|
-
|
199
|
-
already_installed = result[:err].include?("Library is already installed: #{library_name}")
|
200
|
-
success = result[:success] || already_installed
|
201
|
-
|
202
|
-
@libraries_indexed = (@libraries_indexed || success) if library_name == WORKAROUND_LIB
|
203
|
-
success
|
204
|
-
end
|
205
|
-
|
206
|
-
# index the set of libraries by installing a dummy library
|
207
|
-
# related to WORKAROUND_LIB and https://github.com/arduino/Arduino/issues/3535
|
208
|
-
# TODO: unclear if this is still necessary
|
209
|
-
def index_libraries
|
210
|
-
return true if @libraries_indexed
|
211
|
-
|
212
|
-
_install_library(WORKAROUND_LIB)
|
213
|
-
@libraries_indexed
|
214
|
-
end
|
215
|
-
|
216
|
-
# install a library by name
|
217
|
-
# @param name [String] the library name
|
218
|
-
# @return [bool] whether the command succeeded
|
219
|
-
def install_library(library_name)
|
220
|
-
index_libraries
|
221
|
-
_install_library(library_name)
|
222
|
-
end
|
223
|
-
|
224
|
-
# generate the (very likely) path of a library given its name
|
225
|
-
# @param library_name [String] The name of the library
|
226
|
-
# @return [Pathname] The fully qualified library name
|
227
|
-
def library_path(library_name)
|
228
|
-
Pathname.new(lib_dir) + library_name
|
229
|
-
end
|
230
|
-
|
231
|
-
# Determine whether a library is present in the lib dir
|
232
|
-
#
|
233
|
-
# Note that `true` doesn't guarantee that the library is valid/installed
|
234
|
-
# and `false` doesn't guarantee that the library isn't built-in
|
235
|
-
#
|
236
|
-
# @param library_name [String] The name of the library
|
237
|
-
# @return [bool]
|
238
|
-
def library_present?(library_name)
|
239
|
-
library_path(library_name).exist?
|
240
|
-
end
|
241
|
-
|
242
|
-
# update the library index
|
243
|
-
# @return [bool] Whether the update succeeded
|
244
|
-
def update_library_index
|
245
|
-
# install random lib so the arduino IDE grabs a new library index
|
246
|
-
# see: https://github.com/arduino/Arduino/issues/3535
|
247
|
-
install_library(WORKAROUND_LIB)
|
248
|
-
end
|
249
|
-
|
250
|
-
# use a particular board for compilation
|
251
|
-
# @param boardname [String] The board to use
|
252
|
-
# @return [bool] whether the command succeeded
|
253
|
-
def use_board(boardname)
|
254
|
-
run_and_capture(flag_use_board, boardname, flag_save_prefs)[:success]
|
255
|
-
end
|
256
|
-
|
257
|
-
# use a particular board for compilation, installing it if necessary
|
258
|
-
# @param boardname [String] The board to use
|
259
|
-
# @return [bool] whether the command succeeded
|
260
|
-
def use_board!(boardname)
|
261
|
-
return true if use_board(boardname)
|
262
|
-
|
263
|
-
boardfamily = boardname.split(":")[0..1].join(":")
|
264
|
-
puts "Board '#{boardname}' not found; attempting to install '#{boardfamily}'"
|
265
|
-
return false unless install_boards(boardfamily) # guess board family from first 2 :-separated fields
|
266
|
-
|
267
|
-
use_board(boardname)
|
268
|
-
end
|
269
|
-
|
270
|
-
# @param path [String] The sketch to verify
|
271
|
-
# @return [bool] whether the command succeeded
|
272
|
-
def verify_sketch(path)
|
273
|
-
ext = File.extname path
|
274
|
-
unless ext.casecmp(".ino").zero?
|
275
|
-
@last_msg = "Refusing to verify sketch with '#{ext}' extension -- rename it to '.ino'!"
|
276
|
-
return false
|
277
|
-
end
|
278
|
-
unless File.exist? path
|
279
|
-
@last_msg = "Can't verify Sketch at nonexistent path '#{path}'!"
|
280
|
-
return false
|
281
|
-
end
|
282
|
-
ret = run_and_capture(flag_verify, path)
|
283
|
-
ret[:success]
|
284
|
-
end
|
285
|
-
|
286
|
-
# ensure that the given library is installed, or symlinked as appropriate
|
287
|
-
# return the path of the prepared library, or nil
|
288
|
-
# @param path [Pathname] library to use
|
289
|
-
# @return [String] the path of the installed library
|
290
|
-
def install_local_library(path)
|
291
|
-
src_path = path.realpath
|
292
|
-
library_name = src_path.basename
|
293
|
-
destination_path = library_path(library_name)
|
294
|
-
|
295
|
-
# things get weird if the sketchbook contains the library.
|
296
|
-
# check that first
|
297
|
-
if destination_path.exist?
|
298
|
-
uhoh = "There is already a library '#{library_name}' in the library directory"
|
299
|
-
return destination_path if destination_path == src_path
|
300
|
-
|
301
|
-
# maybe it's a symlink? that would be OK
|
302
|
-
if destination_path.symlink?
|
303
|
-
return destination_path if destination_path.readlink == src_path
|
304
|
-
|
305
|
-
@last_msg = "#{uhoh} and it's not symlinked to #{src_path}"
|
306
|
-
return nil
|
307
|
-
end
|
308
|
-
|
309
|
-
@last_msg = "#{uhoh}. It may need to be removed manually."
|
310
|
-
return nil
|
311
|
-
end
|
312
|
-
|
313
|
-
# install the library
|
314
|
-
Host.symlink(src_path, destination_path)
|
315
|
-
destination_path
|
316
|
-
end
|
317
|
-
|
318
|
-
# @param installed_library_path [String] The library to query
|
319
|
-
# @return [Array<String>] Example sketch files
|
320
|
-
def library_examples(installed_library_path)
|
321
|
-
example_path = Pathname.new(installed_library_path) + "examples"
|
322
|
-
return [] unless File.exist?(example_path)
|
323
|
-
|
324
|
-
examples = example_path.children.select(&:directory?).map(&:to_path).map(&File.method(:basename))
|
325
|
-
files = examples.map do |e|
|
326
|
-
proj_file = example_path + e + "#{e}.ino"
|
327
|
-
proj_file.exist? ? proj_file.to_s : nil
|
328
|
-
end
|
329
|
-
files.reject(&:nil?).sort_by(&:to_s)
|
330
|
-
end
|
331
|
-
end
|
332
|
-
end
|