diff --git a/CHANGELOG.md b/CHANGELOG.md index 44a4f817..8f5e2904 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,16 +6,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added - - Provide an `itoa` function. It is present in Arduino's runtime environment but not on most (all?) host systems because itoa is not a portable standard function. ### Changed +- Simplified the use of `Array.each` with a return statement; it's now simply `Array.find` +- `autolocate!` for Arduino installations now raises `ArduinoInstallationError` if `force_install` fails +- Errors due to missing YAML are now named `ConfigurationError` ### Deprecated ### Removed ### Fixed +- Determining a working OSX launch command no longer breaks on non-English installations ### Security diff --git a/REFERENCE.md b/REFERENCE.md index 2aaae553..0e962846 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -405,7 +405,8 @@ unittest(interrupt_attachment) { assertEqual(state->interrupt[7].mode, 3); detachInterrupt(7); assertFalse(state->interrupt[7].attached); -}``` +} +``` ### SPI diff --git a/lib/arduino_ci/arduino_downloader.rb b/lib/arduino_ci/arduino_downloader.rb index 290983ed..867d6965 100644 --- a/lib/arduino_ci/arduino_downloader.rb +++ b/lib/arduino_ci/arduino_downloader.rb @@ -32,13 +32,7 @@ def self.autolocated_executable # 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.each do |loc| - next if loc.nil? - next unless File.exist? loc - - return loc - end - nil + locations.find { |loc| !loc.nil? && File.exist?(loc) } end # The autolocated directory of the installation @@ -49,13 +43,7 @@ def self.autolocated_installation # 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_install_location, self.existing_installation] - locations.each do |loc| - next if loc.nil? - next unless File.exist? loc - - return loc - end - nil + locations.find { |loc| !loc.nil? && File.exist?(loc) } end # The path to the directory of an existing installation, or nil @@ -198,7 +186,7 @@ def execute elsif File.exist? extracted_file install else - puts "Arduino force-install failed" + puts "Could not find extracted archive (tried #{extracted_file})" end File.exist? self.class.force_install_location diff --git a/lib/arduino_ci/arduino_downloader_osx.rb b/lib/arduino_ci/arduino_downloader_osx.rb index 9ff7588d..02ea2347 100644 --- a/lib/arduino_ci/arduino_downloader_osx.rb +++ b/lib/arduino_ci/arduino_downloader_osx.rb @@ -27,21 +27,17 @@ def self.force_install_location # @param Array a list of places to look # @return [string] def self.find_existing_arduino_dir(paths) - paths.each do |path| - return path if File.exist? path - end - nil + paths.find(&File.method(:exist?)) end # An existing Arduino file in one of the given directories, or nil # @param Array a list of places to look for the executable # @return [string] def self.find_existing_arduino_exe(paths) - paths.each do |path| + paths.find do |path| exe = File.join(path, "MacOS", "Arduino") - return exe if File.exist? exe + File.exist? exe end - nil end # The path to the directory of an existing installation, or nil diff --git a/lib/arduino_ci/arduino_downloader_windows.rb b/lib/arduino_ci/arduino_downloader_windows.rb index cde8c763..fc3b004e 100644 --- a/lib/arduino_ci/arduino_downloader_windows.rb +++ b/lib/arduino_ci/arduino_downloader_windows.rb @@ -81,10 +81,10 @@ def self.existing_installation # @return [string] def self.existing_executable arduino_reg = 'SOFTWARE\WOW6432Node\Arduino' - Win32::Registry::HKEY_LOCAL_MACHINE.open(arduino_reg) do |reg| + Win32::Registry::HKEY_LOCAL_MACHINE.open(arduino_reg).find do |reg| path = reg.read_s('Install_Dir') exe = File.join(path, "arduino_debug.exe") - return exe if File.exist? exe + File.exist? exe end rescue nil @@ -93,10 +93,7 @@ def self.existing_executable # The executable Arduino file in a forced installation, or nil # @return [string] def self.force_installed_executable - exe = File.join(self.force_install_location, "arduino_debug.exe") - return nil if exe.nil? - - exe + File.join(self.force_install_location, "arduino_debug.exe") end end diff --git a/lib/arduino_ci/arduino_installation.rb b/lib/arduino_ci/arduino_installation.rb index bb083af8..2ae016f5 100644 --- a/lib/arduino_ci/arduino_installation.rb +++ b/lib/arduino_ci/arduino_installation.rb @@ -13,6 +13,8 @@ module ArduinoCI + class ArduinoInstallationError < StandardError; end + # Manage the OS-specific install location of Arduino class ArduinoInstallation @@ -78,7 +80,13 @@ def autolocate_osx # don't want to see is a java error. args = launcher + ["--bogus-option"] result = Host.run_and_capture(*args) - next unless result[:err].include? "Error: unknown option: --bogus-option" + + # NOTE: Was originally searching for "Error: unknown option: --bogus-option" + # but also need to find "Erreur: option inconnue : --bogus-option" + # and who knows how many other languages. + # For now, just search for the end of the error and hope that the java-style + # launch of this won't include a similar string in it + next unless result[:err].include? ": --bogus-option" ret.base_cmd = launcher ret.binary_path = Pathname.new(osx_root) @@ -94,7 +102,8 @@ def autolocate! return candidate unless candidate.nil? # force the install - force_install + raise ArduinoInstallationError, "Failed to force-install Arduino" unless force_install + autolocate end diff --git a/lib/arduino_ci/ci_config.rb b/lib/arduino_ci/ci_config.rb index 25165be9..549fd316 100644 --- a/lib/arduino_ci/ci_config.rb +++ b/lib/arduino_ci/ci_config.rb @@ -35,6 +35,8 @@ }.freeze module ArduinoCI + class ConfigurationError < StandardError; end + # The filename controlling (overriding) the defaults for testing. # Files with this name can be used in the root directory of the Arduino library and in any/all of the example directories CONFIG_FILENAMES = [ @@ -108,7 +110,7 @@ def validate_data(rootname, source, schema) # @return [ArduinoCI::CIConfig] a reference to self def load_yaml(path) yml = YAML.load_file(path) - raise "The YAML file at #{path} failed to load" unless yml + raise ConfigurationError, "The YAML file at #{path} failed to load" unless yml if yml.include?("packages") yml["packages"].each do |k, v|