class ArduinoCI::ArduinoDownloader
Manage the OS-specific download & install of Arduino
Public Class Methods
The autolocated executable of the installation
@return [Pathname] or nil
# File lib/arduino_ci/arduino_downloader.rb, line 35 def self.autolocated_executable # Arbitrarily, I'm going to pick the force installed location first # if it exists. I'm not sure why we would have both, but if we did # a force install then let's make sure we actually use it. locations = [self.force_installed_executable, self.existing_executable] locations.find { |loc| !loc.nil? && File.exist?(loc) } end
The technology that will be used to complete the download (for logging purposes) @return [string]
# File lib/arduino_ci/arduino_downloader.rb, line 70 def self.downloader "open-uri" end
The executable Arduino file in an existing installation, or nil @return [Pathname]
# File lib/arduino_ci/arduino_downloader.rb, line 45 def self.existing_executable self.must_implement(__method__) end
Extract the package_file
to extracted_file
@return [bool] whether successful
# File lib/arduino_ci/arduino_downloader.rb, line 83 def self.extract(_package_file) self.must_implement(__method__) end
The local filename of the extracted IDE package (zip/tar/etc) @return [string]
# File lib/arduino_ci/arduino_downloader.rb, line 57 def self.extracted_file self.must_implement(__method__) end
The technology that will be used to extract the download (for logging purposes) @return [string]
# File lib/arduino_ci/arduino_downloader.rb, line 77 def self.extracter self.must_implement(__method__) end
The executable Arduino file in a forced installation, or nil @return [Pathname]
# File lib/arduino_ci/arduino_downloader.rb, line 63 def self.force_installed_executable Pathname.new(ENV['HOME']) + self.extracted_file end
Provide guidelines to the implementer of this class
# File lib/arduino_ci/arduino_downloader.rb, line 22 def self.must_implement(method) raise NotImplementedError, "#{self.class.name} failed to implement ArduinoDownloader.#{method}" end
@param desired_version [string] Version string e.g. 1.8.7 @param output [IO] $stdout, $stderr, File.new(/dev/null, 'w'), etc. where console output will be sent
# File lib/arduino_ci/arduino_downloader.rb, line 16 def initialize(desired_version, output = $stdout) @desired_version = desired_version @output = output end
Public Instance Methods
Download the package_url
to package_file
@return [bool] whether successful
# File lib/arduino_ci/arduino_downloader.rb, line 95 def download # Turned off ssl verification # This should be acceptable because it won't happen on a user's machine, just CI # define a progress-bar printer chunk_size = 1024 * 1024 * 1024 total_size = 0 dots = 0 dot_printer = lambda do |size| total_size += size needed_dots = (total_size / chunk_size).to_i unprinted_dots = needed_dots - dots @output.print("." * unprinted_dots) if unprinted_dots.positive? dots = needed_dots end open(package_url, ssl_verify_mode: 0, progress_proc: dot_printer) do |url| File.open(package_file, 'wb') { |file| file.write(url.read) } end rescue Net::OpenTimeout, Net::ReadTimeout, OpenURI::HTTPError, URI::InvalidURIError => e @output.puts "\nArduino force-install failed downloading #{package_url}: #{e}" end
Forcibly install Arduino on linux from the web @return [bool] Whether the command succeeded
# File lib/arduino_ci/arduino_downloader.rb, line 126 def execute error_preparing = prepare unless error_preparing.nil? @output.puts "Arduino force-install failed preparation: #{error_preparing}" return false end arduino_package = "Arduino #{@desired_version} package" attempts = 0 loop do if File.exist?(package_file) @output.puts "#{arduino_package} seems to have been downloaded already at #{package_file}" if attempts.zero? break elsif attempts >= DOWNLOAD_ATTEMPTS break @output.puts "After #{DOWNLOAD_ATTEMPTS} attempts, failed to download #{package_url}" else @output.print "Attempting to download #{arduino_package} with #{self.class.downloader}" download @output.puts end attempts += 1 end if File.exist?(self.class.extracted_file) @output.puts "#{arduino_package} seems to have been extracted already at #{self.class.extracted_file}" elsif File.exist?(package_file) @output.print "Extracting archive with #{self.class.extracter}" self.class.extract(package_file) @output.puts end if File.exist?(self.class.force_installed_executable) @output.puts "#{arduino_package} seems to have been installed already at #{self.class.force_installed_executable}" elsif File.exist?(self.class.extracted_file) install else @output.puts "Could not find extracted archive (tried #{self.class.extracted_file})" end File.exist?(self.class.force_installed_executable) end
Move the extracted package file from extracted_file
to the force_installed_executable
@return [bool] whether successful
# File lib/arduino_ci/arduino_downloader.rb, line 120 def install FileUtils.mv self.class.extracted_file.to_s, self.class.force_installed_executable.to_s end
The local file (dir) name of the desired IDE package (zip/tar/etc) @return [string]
# File lib/arduino_ci/arduino_downloader.rb, line 51 def package_file self.class.must_implement(__method__) end
The URL of the desired IDE package (zip/tar/etc) for this platform @return [string]
# File lib/arduino_ci/arduino_downloader.rb, line 89 def package_url "https://github.com/arduino/arduino-cli/releases/download/#{@desired_version}/#{package_file}" end
Make any preparations or run any checks prior to making changes @return [string] Error message, or nil if success
# File lib/arduino_ci/arduino_downloader.rb, line 28 def prepare nil end