Skip to content

Commit 7216786

Browse files
committed
Enable redirection of installation output
1 parent 96079b6 commit 7216786

5 files changed

+41
-20
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
66

77
## [Unreleased]
88
### Added
9+
- `ArduinoInstallation` and `ArduinoDownloader` now allow console output to optionally be set to an `IO` object of choice during `force_install`
10+
- `ArduinoInstallation::force_install` now optionally accepts a version string
911

1012
### Changed
1113
- Unit tests and examples are now executed alphabetically by filename

lib/arduino_ci/arduino_downloader.rb

+20-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
require "fileutils"
1+
require 'fileutils'
2+
require 'net/http'
23
require 'open-uri'
34
require 'zip'
45

@@ -9,8 +10,11 @@ module ArduinoCI
910
# Manage the OS-specific download & install of Arduino
1011
class ArduinoDownloader
1112

12-
def initialize(desired_ide_version)
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)
1316
@desired_ide_version = desired_ide_version
17+
@output = output
1418
end
1519

1620
# Provide guidelines to the implementer of this class
@@ -115,15 +119,15 @@ def download
115119
total_size += size
116120
needed_dots = (total_size / chunk_size).to_i
117121
unprinted_dots = needed_dots - dots
118-
print("." * unprinted_dots) if unprinted_dots > 0
122+
@output.print("." * unprinted_dots) if unprinted_dots > 0
119123
dots = needed_dots
120124
end
121125

122126
open(package_url, ssl_verify_mode: 0, progress_proc: dot_printer) do |url|
123127
File.open(package_file, 'wb') { |file| file.write(url.read) }
124128
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}"
127131
end
128132

129133
# Extract the package_file to extracted_file
@@ -133,7 +137,7 @@ def extract
133137
batch_size = [1, (zip.size / 100).to_i].max
134138
dots = 0
135139
zip.each do |file|
136-
print "." if (dots % batch_size).zero?
140+
@output.print "." if (dots % batch_size).zero?
137141
file.restore_permissions = true
138142
file.extract { accept_all }
139143
dots += 1
@@ -153,40 +157,40 @@ def install
153157
def execute
154158
error_preparing = prepare
155159
unless error_preparing.nil?
156-
puts "Arduino force-install failed preparation: #{error_preparing}"
160+
@output.puts "Arduino force-install failed preparation: #{error_preparing}"
157161
return false
158162
end
159163

160164
attempts = 0
161165

162166
loop do
163167
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?
165169
break
166170
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}"
168172
else
169-
print "Attempting to download Arduino package with #{downloader}"
173+
@output.print "Attempting to download Arduino package with #{downloader}"
170174
download
171-
puts
175+
@output.puts
172176
end
173177
attempts += 1
174178
end
175179

176180
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"
178182
elsif File.exist? package_file
179-
print "Extracting archive with #{extracter}"
183+
@output.print "Extracting archive with #{extracter}"
180184
extract
181-
puts
185+
@output.puts
182186
end
183187

184188
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"
186190
elsif File.exist? extracted_file
187191
install
188192
else
189-
puts "Could not find extracted archive (tried #{extracted_file})"
193+
@output.puts "Could not find extracted archive (tried #{extracted_file})"
190194
end
191195

192196
File.exist? self.class.force_install_location

lib/arduino_ci/arduino_downloader_windows.rb

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
require 'shellwords' # fingers crossed this works on win32
33
require 'win32/registry'
44
require "arduino_ci/arduino_downloader"
5+
require 'net/http'
56
require "fileutils"
67

78
module ArduinoCI
@@ -30,6 +31,8 @@ def download
3031
open(URI.parse(package_url), ssl_verify_mode: 0) do |url|
3132
File.open(package_file, 'wb') { |file| file.write(url.read) }
3233
end
34+
rescue Net::OpenTimeout, Net::ReadTimeout, OpenURI::HTTPError, URI::InvalidURIError => e
35+
@output.puts "\nArduino force-install failed downloading #{package_url}: #{e}"
3336
end
3437

3538
# Move the extracted package file from extracted_file to the force_install_location

lib/arduino_ci/arduino_installation.rb

+4-4
Original file line numberDiff line numberDiff line change
@@ -97,25 +97,25 @@ def autolocate_osx
9797

9898
# Attempt to find a workable Arduino executable across platforms, and install it if we don't
9999
# @return [ArduinoCI::ArduinoCmd] an instance of a command
100-
def autolocate!
100+
def autolocate!(output = $stdout)
101101
candidate = autolocate
102102
return candidate unless candidate.nil?
103103

104104
# 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)
106106

107107
autolocate
108108
end
109109

110110
# Forcibly install Arduino from the web
111111
# @return [bool] Whether the command succeeded
112-
def force_install
112+
def force_install(output = $stdout, version = DESIRED_ARDUINO_IDE_VERSION)
113113
worker_class = case Host.os
114114
when :osx then ArduinoDownloaderOSX
115115
when :windows then ArduinoDownloaderWindows
116116
when :linux then ArduinoDownloaderLinux
117117
end
118-
worker = worker_class.new(DESIRED_ARDUINO_IDE_VERSION)
118+
worker = worker_class.new(version, output)
119119
worker.execute
120120
end
121121

spec/arduino_installation_spec.rb

+12
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,17 @@
1515
end
1616
end
1717

18+
context "force_install" do
19+
it "Can redirect output" do
20+
output = StringIO.new
21+
output.rewind
22+
expect(output.read.empty?).to be true
23+
# install a bogus version to save time downloading
24+
arduino_cmd = ArduinoCI::ArduinoInstallation.force_install(output, "BOGUS VERSION")
25+
output.rewind
26+
expect(output.read.empty?).to be false
27+
end
28+
end
29+
1830
end
1931

0 commit comments

Comments
 (0)