From 048705e640c2d10198cc4c1467044d61cbc139b8 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Sun, 6 May 2018 08:32:31 -0400 Subject: [PATCH 01/10] add OSX to Travis config --- .travis.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4f51fddf..ba9b194e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,9 @@ sudo: false language: ruby -# rvm: -# - "2.0.0" -# - "2.1.0" -# - "2.2.0" -# - rbx -# - "2.5.0" +os: + - linux + - osx #before_install: gem install bundler -v 1.15.4 script: From f119b8378d60430a11a5c1da0747928521c7541e Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Sun, 6 May 2018 11:55:06 -0400 Subject: [PATCH 02/10] centralize download and unzip logic into ruby libs --- lib/arduino_ci/arduino_downloader.rb | 41 ++++++++++++++++---- lib/arduino_ci/arduino_downloader_linux.rb | 14 ++++++- lib/arduino_ci/arduino_downloader_osx.rb | 17 +------- lib/arduino_ci/arduino_downloader_posix.rb | 38 ------------------ lib/arduino_ci/arduino_downloader_windows.rb | 6 --- spec/arduino_downloader_spec.rb | 8 ++-- 6 files changed, 51 insertions(+), 73 deletions(-) delete mode 100644 lib/arduino_ci/arduino_downloader_posix.rb diff --git a/lib/arduino_ci/arduino_downloader.rb b/lib/arduino_ci/arduino_downloader.rb index 87f998c1..a04addd8 100644 --- a/lib/arduino_ci/arduino_downloader.rb +++ b/lib/arduino_ci/arduino_downloader.rb @@ -1,3 +1,7 @@ +require "fileutils" +require 'open-uri' +require 'zip' + DOWNLOAD_ATTEMPTS = 3 module ArduinoCI @@ -74,14 +78,14 @@ def self.force_installed_executable # (for logging purposes) # @return [string] def downloader - self.class.must_implement(__method__) + "open-uri" end # The technology that will be used to extract the download # (for logging purposes) # @return [string] def extracter - self.class.must_implement(__method__) + "Zip" end # The URL of the desired IDE package (zip/tar/etc) for this platform @@ -107,22 +111,44 @@ def self.force_install_location File.join(ENV['HOME'], 'arduino_ci_ide') end - # Download the package_url to package_file, and maybe print a line of dots...... + # Download the package_url to package_file # @return [bool] whether successful def download - self.class.must_implement(__method__) + # 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 + print("." * unprinted_dots) if unprinted_dots > 0 + 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 end # Extract the package_file to extracted_file # @return [bool] whether successful def extract - self.class.must_implement(__method__) + Zip::File.open(package_file) do |zip| + zip.each do |file| + file.extract(file.name) + end + end end # Move the extracted package file from extracted_file to the force_install_location # @return [bool] whether successful def install - self.class.must_implement(__method__) + # Move only the content of the directory + FileUtils.mv extracted_file, self.class.force_install_location end # Forcibly install Arduino on linux from the web @@ -143,8 +169,9 @@ def execute elsif attempts >= DOWNLOAD_ATTEMPTS break puts "After #{DOWNLOAD_ATTEMPTS} attempts, failed to download #{package_url}" else - puts "Attempting to download Arduino package with #{downloader}" + print "Attempting to download Arduino package with #{downloader}" download + puts end attempts += 1 end diff --git a/lib/arduino_ci/arduino_downloader_linux.rb b/lib/arduino_ci/arduino_downloader_linux.rb index d0fcdb0c..12c7db95 100644 --- a/lib/arduino_ci/arduino_downloader_linux.rb +++ b/lib/arduino_ci/arduino_downloader_linux.rb @@ -1,11 +1,11 @@ -require "arduino_ci/arduino_downloader_posix" +require "arduino_ci/arduino_downloader" USE_BUILDER = false module ArduinoCI # Manage the linux download & install of Arduino - class ArduinoDownloaderLinux < ArduinoDownloaderPosix + class ArduinoDownloaderLinux < ArduinoDownloader # The local filename of the desired IDE package (zip/tar/etc) # @return [string] @@ -13,6 +13,16 @@ def package_file "#{extracted_file}-linux64.tar.xz" end + # Make any preparations or run any checks prior to making changes + # @return [string] Error message, or nil if success + def prepare + reqs = [extracter] + reqs.each do |req| + return "#{req} does not appear to be installed!" unless Host.which(req) + end + nil + end + # The technology that will be used to extract the download # (for logging purposes) # @return [string] diff --git a/lib/arduino_ci/arduino_downloader_osx.rb b/lib/arduino_ci/arduino_downloader_osx.rb index c695c9ee..a9954a72 100644 --- a/lib/arduino_ci/arduino_downloader_osx.rb +++ b/lib/arduino_ci/arduino_downloader_osx.rb @@ -1,9 +1,9 @@ -require "arduino_ci/arduino_downloader_posix" +require "arduino_ci/arduino_downloader" module ArduinoCI # Manage the OSX download & install of Arduino - class ArduinoDownloaderOSX < ArduinoDownloaderPosix + class ArduinoDownloaderOSX < ArduinoDownloader # The local filename of the desired IDE package (zip/tar/etc) # @return [string] @@ -11,19 +11,6 @@ def package_file "arduino-#{@desired_ide_version}-macosx.zip" end - # The technology that will be used to extract the download - # (for logging purposes) - # @return [string] - def extracter - "unzip" - end - - # Extract the package_file to extracted_file - # @return [bool] whether successful - def extract - system(extracter, package_file) - end - # The local file (dir) name of the extracted IDE package (zip/tar/etc) # @return [string] def extracted_file diff --git a/lib/arduino_ci/arduino_downloader_posix.rb b/lib/arduino_ci/arduino_downloader_posix.rb deleted file mode 100644 index 9b9eeece..00000000 --- a/lib/arduino_ci/arduino_downloader_posix.rb +++ /dev/null @@ -1,38 +0,0 @@ -require "arduino_ci/arduino_downloader" - -module ArduinoCI - - # Manage the POSIX download & install of Arduino - class ArduinoDownloaderPosix < ArduinoDownloader - - # Make any preparations or run any checks prior to making changes - # @return [string] Error message, or nil if success - def prepare - reqs = [downloader, extracter] - reqs.each do |req| - return "#{req} does not appear to be installed!" unless Host.which(req) - end - nil - end - - # The technology that will be used to complete the download - # (for logging purposes) - # @return [string] - def downloader - "wget" - end - - # Download the package_url to package_file - # @return [bool] whether successful - def download - system(downloader, "--quiet", "--progress=dot:giga", package_url) - end - - # Move the extracted package file from extracted_file to the force_install_location - # @return [bool] whether successful - def install - system("mv", extracted_file, self.class.force_install_location) - end - - end -end diff --git a/lib/arduino_ci/arduino_downloader_windows.rb b/lib/arduino_ci/arduino_downloader_windows.rb index 417ff49f..31dc0b9f 100644 --- a/lib/arduino_ci/arduino_downloader_windows.rb +++ b/lib/arduino_ci/arduino_downloader_windows.rb @@ -2,8 +2,6 @@ require 'shellwords' # fingers crossed this works on win32 require 'win32/registry' require "arduino_ci/arduino_downloader" -require 'open-uri' -require 'zip' require "fileutils" module ArduinoCI @@ -39,8 +37,6 @@ def download def install # Move only the content of the directory FileUtils.mv extracted_file, self.class.force_install_location - # clean up the no longer required root extracted folder - FileUtils.rm_rf extracted_file end # The local filename of the desired IDE package (zip/tar/etc) @@ -64,8 +60,6 @@ def extract file.extract(file.name) end end - # clean up the no longer required zip - FileUtils.rm_rf package_file end # The local file (dir) name of the extracted IDE package (zip/tar/etc) diff --git a/spec/arduino_downloader_spec.rb b/spec/arduino_downloader_spec.rb index 185cdd2c..819b75a2 100644 --- a/spec/arduino_downloader_spec.rb +++ b/spec/arduino_downloader_spec.rb @@ -17,8 +17,6 @@ it "has correct instance properties" do ad = ArduinoCI::ArduinoDownloader.new(DESIRED_VERSION) expect(ad.prepare).to be nil - expect{ad.downloader}.to raise_error(NotImplementedError) - expect{ad.extracter}.to raise_error(NotImplementedError) expect{ad.package_url}.to raise_error(NotImplementedError) expect{ad.package_file}.to raise_error(NotImplementedError) end @@ -42,7 +40,7 @@ it "has correct instance properties" do ad = ArduinoCI::ArduinoDownloaderLinux.new(DESIRED_VERSION) expect(ad.prepare).to be nil - expect(ad.downloader).to eq("wget") + expect(ad.downloader).to eq("open-uri") expect(ad.extracter).to eq("tar") expect(ad.package_url).to eq("https://downloads.arduino.cc/arduino-rhubarb-linux64.tar.xz") expect(ad.package_file).to eq("arduino-rhubarb-linux64.tar.xz") @@ -67,8 +65,8 @@ it "has correct instance properties" do ad = ArduinoCI::ArduinoDownloaderOSX.new(DESIRED_VERSION) expect(ad.prepare).to be nil - expect(ad.downloader).to eq("wget") - expect(ad.extracter).to eq("unzip") + expect(ad.downloader).to eq("open-uri") + expect(ad.extracter).to eq("Zip") expect(ad.package_url).to eq("https://downloads.arduino.cc/arduino-rhubarb-macosx.zip") expect(ad.package_file).to eq("arduino-rhubarb-macosx.zip") end From 28aec2b0400a021d52500391535febd9dca2b4a4 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Sun, 6 May 2018 12:47:22 -0400 Subject: [PATCH 03/10] fix paths for OSX force install --- lib/arduino_ci/arduino_downloader_osx.rb | 6 +++--- lib/arduino_ci/arduino_installation.rb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/arduino_ci/arduino_downloader_osx.rb b/lib/arduino_ci/arduino_downloader_osx.rb index a9954a72..3885d2db 100644 --- a/lib/arduino_ci/arduino_downloader_osx.rb +++ b/lib/arduino_ci/arduino_downloader_osx.rb @@ -41,19 +41,19 @@ def self.find_existing_arduino_exe(paths) # The path to the directory of an existing installation, or nil # @return [string] def self.existing_installation - self.find_existing_arduino_dir(["/Applications/Arduino.app/Contents"]) + self.find_existing_arduino_dir(["/Applications/Arduino.app"]) end # The executable Arduino file in an existing installation, or nil # @return [string] def self.existing_executable - self.find_existing_arduino_exe(["/Applications/Arduino.app/Contents"]) + self.find_existing_arduino_exe(["/Applications/Arduino.app"]) end # The executable Arduino file in a forced installation, or nil # @return [string] def self.force_installed_executable - self.find_existing_arduino_exe([File.join(self.force_install_location, "Contents")]) + self.find_existing_arduino_exe([self.force_install_location]) end end diff --git a/lib/arduino_ci/arduino_installation.rb b/lib/arduino_ci/arduino_installation.rb index 20229467..4d9800cf 100644 --- a/lib/arduino_ci/arduino_installation.rb +++ b/lib/arduino_ci/arduino_installation.rb @@ -60,7 +60,7 @@ def autolocate_osx "processing.app.Base", ], # failsafe way - [File.join(osx_root, "MacOS", "Arduino")] + [File.join(osx_root, "Contents", "MacOS", "Arduino")] ] # create return and find a command launcher that works From 28d46f14dce0030627795d138a548001d6128d46 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Sun, 6 May 2018 13:24:23 -0400 Subject: [PATCH 04/10] put OSX Arduino in the Arduino.app directory, since it's particular about that --- lib/arduino_ci/arduino_downloader_osx.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/arduino_ci/arduino_downloader_osx.rb b/lib/arduino_ci/arduino_downloader_osx.rb index 3885d2db..9ff7588d 100644 --- a/lib/arduino_ci/arduino_downloader_osx.rb +++ b/lib/arduino_ci/arduino_downloader_osx.rb @@ -17,6 +17,12 @@ def extracted_file "Arduino.app" end + # @return [String] The location where a forced install will go + def self.force_install_location + # include the .app extension + File.join(ENV['HOME'], 'Arduino.app') + end + # An existing Arduino directory in one of the given directories, or nil # @param Array a list of places to look # @return [string] From d9b1b298f35cb22981ae63c4683b6c262e259620 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Sun, 6 May 2018 13:24:40 -0400 Subject: [PATCH 05/10] show progress bar for unzip oeprations --- lib/arduino_ci/arduino_downloader.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/arduino_ci/arduino_downloader.rb b/lib/arduino_ci/arduino_downloader.rb index a04addd8..cd754423 100644 --- a/lib/arduino_ci/arduino_downloader.rb +++ b/lib/arduino_ci/arduino_downloader.rb @@ -138,8 +138,12 @@ def download # @return [bool] whether successful def extract Zip::File.open(package_file) do |zip| + batch_size = [1, (zip.size / 100).to_i].max + dots = 0 zip.each do |file| + print "." if (dots % batch_size).zero? file.extract(file.name) + dots += 1 end end end @@ -179,8 +183,9 @@ def execute if File.exist? extracted_file puts "Arduino package seems to have been extracted already" elsif File.exist? package_file - puts "Extracting archive with #{extracter}" + print "Extracting archive with #{extracter}" extract + puts end if File.exist? self.class.force_install_location From a59c87f65c61087706274135e7d4c0233a93116d Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Sun, 6 May 2018 13:39:55 -0400 Subject: [PATCH 06/10] Fix permissions on extracted files --- lib/arduino_ci/arduino_downloader.rb | 3 ++- spec/arduino_downloader_spec.rb | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/arduino_ci/arduino_downloader.rb b/lib/arduino_ci/arduino_downloader.rb index cd754423..9244178d 100644 --- a/lib/arduino_ci/arduino_downloader.rb +++ b/lib/arduino_ci/arduino_downloader.rb @@ -142,7 +142,8 @@ def extract dots = 0 zip.each do |file| print "." if (dots % batch_size).zero? - file.extract(file.name) + file.restore_permissions = true + file.extract { accept_all } dots += 1 end end diff --git a/spec/arduino_downloader_spec.rb b/spec/arduino_downloader_spec.rb index 819b75a2..693d5816 100644 --- a/spec/arduino_downloader_spec.rb +++ b/spec/arduino_downloader_spec.rb @@ -59,7 +59,7 @@ # expect(ad.existing_executable).to be nil # expect(ad.force_installed_executable).to be nil - expect(ad.force_install_location).to eq(File.join(ENV['HOME'], 'arduino_ci_ide')) + expect(ad.force_install_location).to eq(File.join(ENV['HOME'], 'Arduino.app')) end it "has correct instance properties" do From 86df2729bfc0e4afc52c6668dd62cab171e4ee81 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Sun, 6 May 2018 13:54:40 -0400 Subject: [PATCH 07/10] expose g++ for OSX CI --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index ba9b194e..96488121 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ os: #before_install: gem install bundler -v 1.15.4 script: + - g++ -v - bundle install - bundle exec rubocop --version - bundle exec rubocop -D . From 182ee636f6ecec2a2b991ae3cea4803a76333636 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Sun, 6 May 2018 15:09:56 -0400 Subject: [PATCH 08/10] get separate badges for Travis --- .travis.yml | 12 ++++++++++++ README.md | 19 +++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 96488121..e93a54e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,18 @@ os: - linux - osx +env: + - BADGE=linux + - BADGE=osx + +# hack to get some OS-specific badges +matrix: + exclude: + - os: linux + env: BADGE=osx + - os: osx + env: BADGE=linux + #before_install: gem install bundler -v 1.15.4 script: - g++ -v diff --git a/README.md b/README.md index 6b01acef..782bf75f 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,18 @@ -[![Gem Version](https://badge.fury.io/rb/arduino_ci.svg)](https://rubygems.org/gems/arduino_ci) -[![Linux Build Status](https://travis-ci.org/ianfixes/arduino_ci.svg)](https://travis-ci.org/ianfixes/arduino_ci) -[![Windows Build status](https://ci.appveyor.com/api/projects/status/8f6e39dea319m83q?svg=true)](https://ci.appveyor.com/project/ianfixes/arduino-ci) -[![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://www.rubydoc.info/gems/arduino_ci/0.1.9) -# ArduinoCI Ruby gem (`arduino_ci`) +# ArduinoCI Ruby gem (`arduino_ci`) [![Gem Version](https://badge.fury.io/rb/arduino_ci.svg)](https://rubygems.org/gems/arduino_ci)[![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://www.rubydoc.info/gems/arduino_ci/0.1.9) -[Arduino CI](https://github.com/ianfixes/arduino_ci) is a Ruby gem for executing Continuous Integration (CI) tests on an Arduino library -- both locally and as part of a service like Travis CI. + +[Arduino CI](https://github.com/ianfixes/arduino_ci) is a cross-platform Ruby gem for executing Continuous Integration (CI) tests on an Arduino library -- both locally and as part of a service like Travis CI. + +It doesn't matter whether your contributors are using OSX, Linux, or Windows; everyone can run unit tests locally with `arduino_ci`, and be assured that the CI system used by the GitHub project maintainer will run the same tests and get the same results. + +You don't have to take my word for it; let the build logs speak for themselves: + +Platform | CI Status +---------|:--------- +OSX | [![OSX Build Status](http://badges.herokuapp.com/travis/ianfixes/arduino_ci?env=BADGE=osx&label=build&branch=master)](https://travis-ci.org/ianfixes/arduino_ci) +Linux | [![Linux Build Status](http://badges.herokuapp.com/travis/ianfixes/arduino_ci?env=BADGE=linux&label=build&branch=master)](https://travis-ci.org/ianfixes/arduino_ci) +Windows | [![Windows Build status](https://ci.appveyor.com/api/projects/status/8f6e39dea319m83q?svg=true)](https://ci.appveyor.com/project/ianfixes/arduino-ci) ## Installation In Your GitHub Project And Using Travis CI From 8ad528fe3df6c2577089318c755b953e312e9c44 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Sun, 6 May 2018 16:14:05 -0400 Subject: [PATCH 09/10] Fix std::out_of_range on old g++ compilers --- cpp/arduino/WString.h | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/arduino/WString.h b/cpp/arduino/WString.h index 498de157..b85e76ac 100644 --- a/cpp/arduino/WString.h +++ b/cpp/arduino/WString.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include From 89c5f8a1f70eafcb2935ffddfd903573683a33e7 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Sun, 6 May 2018 16:22:34 -0400 Subject: [PATCH 10/10] work around 'error: expected unqualified-id' on clang / OSX --- cpp/arduino/WString.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/arduino/WString.h b/cpp/arduino/WString.h index b85e76ac..f79f3361 100644 --- a/cpp/arduino/WString.h +++ b/cpp/arduino/WString.h @@ -12,8 +12,8 @@ typedef std::string string; // work around some portability issues #if defined(__clang__) - #define ARDUINOCI_ISNAN ::isnan - #define ARDUINOCI_ISINF ::isinf + #define ARDUINOCI_ISNAN isnan + #define ARDUINOCI_ISINF isinf #elif defined(__GNUC__) || defined(__GNUG__) #define ARDUINOCI_ISNAN std::isnan #define ARDUINOCI_ISINF std::isinf