Skip to content

Commit b730e42

Browse files
committed
big refactor to enable no-x-required arduino-builder
1 parent d798161 commit b730e42

File tree

6 files changed

+125
-41
lines changed

6 files changed

+125
-41
lines changed

lib/arduino_ci/arduino_cmd.rb

+42-13
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ def autolocate!
2222
end
2323

2424
attr_accessor :installation
25-
attr_reader :prefs_cache
2625
attr_reader :prefs_response_time
2726
attr_reader :library_is_indexed
2827

@@ -31,26 +30,47 @@ def initialize(installation)
3130
@display_mgr = DisplayManager::instance
3231
@installation = installation
3332
@prefs_response_time = nil
34-
@prefs_cache = prefs
33+
@prefs_cache = nil
3534
@library_is_indexed = false
3635
end
3736

37+
def _parse_pref_string(arduino_output)
38+
lines = arduino_output.split("\n").select { |l| l.include? "=" }
39+
ret = lines.each_with_object({}) do |e, acc|
40+
parts = e.split("=", 2)
41+
acc[parts[0]] = parts[1]
42+
acc
43+
end
44+
ret
45+
end
46+
3847
# fetch preferences to a hash
39-
def prefs
48+
def _prefs
4049
resp = nil
41-
@display_mgr.with_display do
50+
if @installation.requires_x
51+
@display_mgr.with_display do
52+
start = Time.now
53+
resp = run_and_capture("--get-pref")
54+
@prefs_response_time = Time.now - start
55+
end
56+
else
4257
start = Time.now
4358
resp = run_and_capture("--get-pref")
4459
@prefs_response_time = Time.now - start
4560
end
4661
return nil unless resp[:success]
47-
lines = resp[:out].split("\n").select { |l| l.include? "=" }
48-
ret = lines.each_with_object({}) do |e, acc|
49-
parts = e.split("=", 2)
50-
acc[parts[0]] = parts[1]
51-
acc
52-
end
53-
ret
62+
_parse_pref_string(resp[:out])
63+
end
64+
65+
def prefs
66+
@prefs_cache = _prefs if @prefs_cache.nil?
67+
@prefs_cache.clone
68+
end
69+
70+
# get a preference key
71+
def get_pref(key)
72+
data = @prefs_cache.nil? ? prefs : @prefs_cache
73+
data[key]
5474
end
5575

5676
# set a preference key/value pair
@@ -65,13 +85,22 @@ def set_pref(key, value)
6585

6686
# run the arduino command
6787
def run(*args, **kwargs)
68-
full_args = [@installation.cmd_path] + args
69-
@display_mgr.run(*full_args, **kwargs)
88+
full_args = @installation.base_cmd + args
89+
if @installation.requires_x
90+
@display_mgr.run(*full_args, **kwargs)
91+
else
92+
Host.run(*full_args, **kwargs)
93+
end
7094
end
7195

7296
def run_with_gui_guess(message, *args, **kwargs)
7397
# On Travis CI, we get an error message in the GUI instead of on STDERR
7498
# so, assume that if we don't get a rapid reply that things are not installed
99+
100+
# if we don't need X, we can skip this whole thing
101+
return run_and_capture(*args, **kwargs)[:success] unless @installation.requires_x
102+
103+
prefs if @prefs_response_time.nil?
75104
x3 = @prefs_response_time * 3
76105
Timeout.timeout(x3) do
77106
result = run_and_capture(*args, **kwargs)

lib/arduino_ci/arduino_installation.rb

+62-19
Original file line numberDiff line numberDiff line change
@@ -6,53 +6,96 @@ module ArduinoCI
66

77
# Manage the OS-specific install location of Arduino
88
class ArduinoInstallation
9-
attr_accessor :cmd_path
9+
attr_accessor :base_cmd
1010
attr_accessor :lib_dir
11+
attr_accessor :requires_x
1112

1213
class << self
1314
def force_install_location
1415
File.join(ENV['HOME'], 'arduino_ci_ide')
1516
end
1617

18+
def from_forced_install
19+
ret = new
20+
builder = File.join(force_install_location, "arduino-builder")
21+
if File.exist? builder
22+
ret.base_cmd = [builder]
23+
ret.requires_x = false
24+
else
25+
ret.base_cmd = [File.join(force_install_location, "arduino")]
26+
ret.requires_x = true
27+
end
28+
ret.lib_dir = File.join(force_install_location, "libraries")
29+
# TODO: "libraries" is what's in the adafruit install.sh script
30+
ret
31+
end
32+
1733
# attempt to find a workable Arduino executable across platforms
1834
def autolocate
19-
ret = new
35+
osx_root = "/Applications/Arduino.app"
36+
old_way = false
37+
if File.exist? osx_root
38+
ret = new
39+
osx_place = "#{osx_root}/Contents/MacOS"
2040

21-
osx_place = "/Applications/Arduino.app/Contents/MacOS"
22-
if File.exist? osx_place
23-
ret.cmd_path = File.join(osx_place, "Arduino")
41+
if old_way
42+
ret.base_cmd = [File.join(osx_place, "Arduino")]
43+
else
44+
jvm_runtime = `/usr/libexec/java_home`
45+
ret.base_cmd = [
46+
"java",
47+
"-cp", "#{osx_root}/Contents/Java/*",
48+
"-DAPP_DIR=#{osx_root}/Contents/Java",
49+
"-Djava.ext.dirs=$JVM_RUNTIME/Contents/Home/lib/ext/:#{jvm_runtime}/Contents/Home/jre/lib/ext/",
50+
"-Dfile.encoding=UTF-8",
51+
"-Dapple.awt.UIElement=true",
52+
"-Xms128M",
53+
"-Xmx512M",
54+
"processing.app.Base",
55+
]
56+
end
2457
ret.lib_dir = File.join(osx_place, "Libraries")
58+
ret.requires_x = false
2559
return ret
2660
end
2761

62+
# # AAARRRRGGGGHHH
63+
# # Even though arduino-builder is an awesome CLI for Arduino,
64+
# # ALL THE OPTIONS ARE DIFFERENT (single vs double dash for flags)
65+
# # USELESS FOR THE TIME BEING
66+
#
67+
# posix_place = Host.which("arduino-builder")
68+
# unless posix_place.nil?
69+
# ret = new
70+
# ret.base_cmd = [posix_place]
71+
# ret.lib_dir = File.join(ENV['HOME'], "Sketchbook") # assume linux
72+
# ret.requires_x = false
73+
# # https://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use/how-to-install-a-library
74+
# return ret
75+
# end
76+
2877
posix_place = Host.which("arduino")
2978
unless posix_place.nil?
30-
ret.cmd_path = posix_place
79+
ret = new
80+
ret.base_cmd = [posix_place]
3181
ret.lib_dir = File.join(ENV['HOME'], "Sketchbook") # assume linux
82+
ret.requires_x = true
3283
# https://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use/how-to-install-a-library
3384
return ret
3485
end
3586

36-
if File.exist? force_install_location
37-
ret.cmd_path = File.join(force_install_location, "arduino")
38-
ret.lib_dir = File.join(force_install_location, "libraries")
39-
# TODO: "libraries" is what's in the adafruit install.sh script
40-
return ret
41-
end
87+
return from_forced_install if File.exist? force_install_location
4288

43-
ret
89+
new
4490
end
4591

4692
# Attempt to find a workable Arduino executable across platforms, and install it if we don't
4793
def autolocate!
4894
candidate = autolocate
49-
return candidate unless candidate.cmd_path.nil?
50-
# force the install
95+
return candidate unless candidate.base_cmd.nil?
5196

52-
if force_install
53-
candidate.cmd_path = File.join(force_install_location, "arduino")
54-
candidate.lib_dir = File.join(force_install_location, "libraries")
55-
end
97+
# force the install
98+
candidate = from_forced_install if force_install
5699
candidate
57100
end
58101

lib/arduino_ci/display_manager.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,7 @@ def run(*args, **kwargs)
148148
env_vars.merge!(args[0]) if has_env
149149
actual_args = has_env ? args[1..-1] : args # need to shift over if we extracted args
150150
full_cmd = env_vars.empty? ? actual_args : [env_vars] + actual_args
151-
shell_vars = env_vars.map { |k, v| "#{k}=#{v}" }.join(" ")
152-
puts " $ #{shell_vars} #{actual_args.join(' ')}"
153-
ret = system(*full_cmd, **kwargs)
154-
status = ret ? "succeeded" : "failed"
155-
puts "#{actual_args[0]} has #{status}"
151+
ret = Host.run(*full_cmd, **kwargs)
156152
end
157153
ret
158154
end

lib/arduino_ci/host.rb

+16
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,21 @@ def self.which(cmd)
1515
end
1616
nil
1717
end
18+
19+
# run a command in a display
20+
def self.run(*args, **kwargs)
21+
# do some work to extract & merge environment variables if they exist
22+
has_env = !args.empty? && args[0].class == Hash
23+
env_vars = has_env ? args[0] : {}
24+
actual_args = has_env ? args[1..-1] : args # need to shift over if we extracted args
25+
full_cmd = env_vars.empty? ? actual_args : [env_vars] + actual_args
26+
shell_vars = env_vars.map { |k, v| "#{k}=#{v}" }.join(" ")
27+
puts " $ #{shell_vars} #{actual_args.join(' ')}"
28+
ret = system(*full_cmd, **kwargs)
29+
status = ret ? "succeeded" : "failed"
30+
puts "#{actual_args[0]} has #{status}"
31+
ret
32+
end
33+
1834
end
1935
end

spec/arduino_cmd_spec.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ def get_sketch(dir, file)
1515
context "autolocate!" do
1616
it "Finds the Arduino executable" do
1717
arduino_cmd = ArduinoCI::ArduinoCmd.autolocate!
18-
expect(arduino_cmd.installation.cmd_path).not_to be nil
19-
expect(arduino_cmd.prefs_cache.class).to be Hash
18+
expect(arduino_cmd.installation.base_cmd).not_to be nil
19+
expect(arduino_cmd.prefs.class).to be Hash
2020
expect(arduino_cmd.prefs_response_time).not_to be nil
2121
end
2222
end
@@ -42,7 +42,7 @@ def get_sketch(dir, file)
4242
ArduinoCI::DisplayManager::instance.enable
4343

4444
it "Sets key to what it was before" do
45-
upload_verify = arduino_cmd.prefs_cache["upload.verify"]
45+
upload_verify = arduino_cmd.get_pref("upload.verify")
4646
result = arduino_cmd.set_pref("upload.verify", upload_verify)
4747
expect(result).to be true
4848
end

spec/arduino_installation_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
context "autolocate!" do
1717
it "doesn't fail" do
1818
installation = ArduinoCI::ArduinoInstallation.autolocate!
19-
expect(installation.cmd_path).not_to be nil
19+
expect(installation.base_cmd).not_to be nil
2020
expect(installation.lib_dir).not_to be nil
2121
end
2222
end

0 commit comments

Comments
 (0)