arduino_ci 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -7
- data/cpp/arduino/Arduino.h +65 -3
- data/cpp/arduino/Godmode.cpp +1 -0
- data/cpp/arduino/Godmode.h +5 -0
- data/cpp/arduino/WString.h +16 -3
- data/exe/arduino_ci_remote.rb +1 -1
- data/lib/arduino_ci/arduino_cmd.rb +1 -1
- data/lib/arduino_ci/arduino_cmd_windows.rb +34 -0
- data/lib/arduino_ci/arduino_downloader.rb +204 -0
- data/lib/arduino_ci/arduino_downloader.rb.orig +219 -0
- data/lib/arduino_ci/arduino_downloader_linux.rb +86 -0
- data/lib/arduino_ci/arduino_downloader_linux.rb.orig +79 -0
- data/lib/arduino_ci/arduino_downloader_osx.rb +66 -0
- data/lib/arduino_ci/arduino_downloader_osx.rb.orig +88 -0
- data/lib/arduino_ci/arduino_downloader_windows.rb +101 -0
- data/lib/arduino_ci/arduino_installation.rb +58 -79
- data/lib/arduino_ci/arduino_installation.rb.orig +116 -0
- data/lib/arduino_ci/display_manager.rb +1 -0
- data/lib/arduino_ci/host.rb +11 -0
- data/lib/arduino_ci/version.rb +1 -1
- data/lib/arduino_ci.rb +1 -1
- metadata +27 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3120211b8610970115b711ea7647e43db7382f65baf3f5b58290c914e6bb68d
|
4
|
+
data.tar.gz: 976468bc18dd707eb5eeab43d020e034e57e9d898cd2cb140e2e7c2398a9ca11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa3afee9f49c16b9ab7e05ce252fd5254cf1e01ab27f5b654de6050278b924169c425c72331cfe02047890497ed001a55af50c55d0bf3e861a67537234b351b2
|
7
|
+
data.tar.gz: 365c09a2d5063e08e1ed57c7cd02b8d5aa8ea9b9899e7214408e4b6b81cb150f49523755f2c0f1f31923a228acd2e13e27ff0abbb2124eb67765cb8168bc01e9
|
data/README.md
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
-
[![Gem Version](https://badge.fury.io/rb/arduino_ci.svg)](https://rubygems.org/gems/arduino_ci)
|
2
|
-
[![Build Status](https://travis-ci.org/ifreecarve/arduino_ci.svg)](https://travis-ci.org/ifreecarve/arduino_ci)
|
3
|
-
[![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://www.rubydoc.info/gems/arduino_ci/0.1.9)
|
4
1
|
|
5
|
-
# ArduinoCI Ruby gem (`arduino_ci`)
|
2
|
+
# 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.10)
|
6
3
|
|
7
|
-
|
4
|
+
|
5
|
+
[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.
|
6
|
+
|
7
|
+
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.
|
8
|
+
|
9
|
+
You don't have to take my word for it; let the build logs speak for themselves:
|
10
|
+
|
11
|
+
Platform | CI Status
|
12
|
+
---------|:---------
|
13
|
+
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)
|
14
|
+
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)
|
15
|
+
Windows | [![Windows Build status](https://ci.appveyor.com/api/projects/status/8f6e39dea319m83q?svg=true)](https://ci.appveyor.com/project/ianfixes/arduino-ci)
|
8
16
|
|
9
17
|
|
10
18
|
## Installation In Your GitHub Project And Using Travis CI
|
@@ -373,12 +381,12 @@ This software is in alpha. But [SampleProjects/DoSomething](SampleProjects/DoSo
|
|
373
381
|
|
374
382
|
* The Arduino library is not fully mocked.
|
375
383
|
* I don't have preprocessor defines for all the Arduino board flavors
|
376
|
-
* https://github.com/
|
384
|
+
* https://github.com/ianfixes/arduino_ci/issues
|
377
385
|
|
378
386
|
|
379
387
|
## Author
|
380
388
|
|
381
|
-
This gem was written by Ian Katz (
|
389
|
+
This gem was written by Ian Katz (ianfixes@gmail.com) in 2018. It's released under the Apache 2.0 license.
|
382
390
|
|
383
391
|
|
384
392
|
## See Also
|
data/cpp/arduino/Arduino.h
CHANGED
@@ -59,6 +59,14 @@ typedef unsigned int word;
|
|
59
59
|
|
60
60
|
|
61
61
|
|
62
|
+
/*
|
63
|
+
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
|
64
|
+
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout);
|
65
|
+
|
66
|
+
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
|
67
|
+
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
|
68
|
+
|
69
|
+
*/
|
62
70
|
|
63
71
|
// Get the bit location within the hardware port of the given virtual pin.
|
64
72
|
// This comes from the pins_*.c file for the active board configuration.
|
@@ -66,6 +74,43 @@ typedef unsigned int word;
|
|
66
74
|
#define analogInPinToBit(P) (P)
|
67
75
|
#define digitalPinToInterrupt(P) (P)
|
68
76
|
|
77
|
+
/*
|
78
|
+
// On the ATmega1280, the addresses of some of the port registers are
|
79
|
+
// greater than 255, so we can't store them in uint8_t's.
|
80
|
+
extern const uint16_t PROGMEM port_to_mode_PGM[];
|
81
|
+
extern const uint16_t PROGMEM port_to_input_PGM[];
|
82
|
+
extern const uint16_t PROGMEM port_to_output_PGM[];
|
83
|
+
|
84
|
+
extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
|
85
|
+
// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
|
86
|
+
extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
|
87
|
+
extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
|
88
|
+
|
89
|
+
// Get the bit location within the hardware port of the given virtual pin.
|
90
|
+
// This comes from the pins_*.c file for the active board configuration.
|
91
|
+
//
|
92
|
+
// These perform slightly better as macros compared to inline functions
|
93
|
+
//
|
94
|
+
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
|
95
|
+
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
|
96
|
+
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
|
97
|
+
#define analogInPinToBit(P) (P)
|
98
|
+
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
|
99
|
+
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
|
100
|
+
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
|
101
|
+
|
102
|
+
*/
|
103
|
+
|
104
|
+
|
105
|
+
/* TODO
|
106
|
+
|
107
|
+
// USB
|
108
|
+
#include "USBAPI.h"
|
109
|
+
Keyboard
|
110
|
+
Mouse
|
111
|
+
|
112
|
+
*/
|
113
|
+
|
69
114
|
// uint16_t makeWord(uint16_t w);
|
70
115
|
// uint16_t makeWord(byte h, byte l);
|
71
116
|
inline unsigned int makeWord(unsigned int w) { return w; }
|
@@ -73,6 +118,23 @@ inline unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8)
|
|
73
118
|
|
74
119
|
#define word(...) makeWord(__VA_ARGS__)
|
75
120
|
|
76
|
-
|
77
|
-
|
78
|
-
|
121
|
+
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
122
|
+
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
123
|
+
|
124
|
+
// audio is taken care of in GODMODE
|
125
|
+
|
126
|
+
|
127
|
+
// BIG TODO ON THIS ONE
|
128
|
+
// $ find . | grep pins_
|
129
|
+
// ./arduino-1.8.5/hardware/arduino/avr/variants/circuitplay32u4/pins_arduino.h
|
130
|
+
// ./arduino-1.8.5/hardware/arduino/avr/variants/eightanaloginputs/pins_arduino.h
|
131
|
+
// ./arduino-1.8.5/hardware/arduino/avr/variants/ethernet/pins_arduino.h
|
132
|
+
// ./arduino-1.8.5/hardware/arduino/avr/variants/gemma/pins_arduino.h
|
133
|
+
// ./arduino-1.8.5/hardware/arduino/avr/variants/leonardo/pins_arduino.h
|
134
|
+
// ./arduino-1.8.5/hardware/arduino/avr/variants/mega/pins_arduino.h
|
135
|
+
// ./arduino-1.8.5/hardware/arduino/avr/variants/micro/pins_arduino.h
|
136
|
+
// ./arduino-1.8.5/hardware/arduino/avr/variants/robot_control/pins_arduino.h
|
137
|
+
// ./arduino-1.8.5/hardware/arduino/avr/variants/robot_motor/pins_arduino.h
|
138
|
+
// ./arduino-1.8.5/hardware/arduino/avr/variants/standard/pins_arduino.h
|
139
|
+
// ./arduino-1.8.5/hardware/arduino/avr/variants/yun/pins_arduino.h
|
140
|
+
// #include "pins_arduino.h"
|
data/cpp/arduino/Godmode.cpp
CHANGED
@@ -38,6 +38,7 @@ long random(long vmax)
|
|
38
38
|
{
|
39
39
|
GodmodeState* godmode = GODMODE();
|
40
40
|
godmode->seed += 4294967291; // it's a prime that fits in 32 bits
|
41
|
+
godmode->seed = godmode->seed % 4294967296; // explicitly wrap in case we're on a 64-bit impl
|
41
42
|
return godmode->seed % vmax;
|
42
43
|
}
|
43
44
|
|
data/cpp/arduino/Godmode.h
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
#include "ArduinoDefines.h"
|
3
3
|
#include <avr/io.h>
|
4
4
|
#include "WString.h"
|
5
|
+
#include "ci/Queue.h"
|
5
6
|
#include "PinHistory.h"
|
6
7
|
|
7
8
|
// random
|
@@ -38,6 +39,10 @@ class GodmodeState {
|
|
38
39
|
unsigned long readDelayMicros;
|
39
40
|
};
|
40
41
|
|
42
|
+
struct ToneDef {
|
43
|
+
|
44
|
+
};
|
45
|
+
|
41
46
|
public:
|
42
47
|
unsigned long micros;
|
43
48
|
unsigned long seed;
|
data/cpp/arduino/WString.h
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
3
|
#include <stdlib.h>
|
4
|
+
#include <stdexcept>
|
4
5
|
#include <string.h>
|
5
6
|
#include <algorithm>
|
6
7
|
#include <iostream>
|
@@ -11,8 +12,8 @@ typedef std::string string;
|
|
11
12
|
|
12
13
|
// work around some portability issues
|
13
14
|
#if defined(__clang__)
|
14
|
-
#define ARDUINOCI_ISNAN
|
15
|
-
#define ARDUINOCI_ISINF
|
15
|
+
#define ARDUINOCI_ISNAN isnan
|
16
|
+
#define ARDUINOCI_ISINF isinf
|
16
17
|
#elif defined(__GNUC__) || defined(__GNUG__)
|
17
18
|
#define ARDUINOCI_ISNAN std::isnan
|
18
19
|
#define ARDUINOCI_ISINF std::isinf
|
@@ -73,6 +74,8 @@ class String: public string
|
|
73
74
|
explicit String(unsigned int val , unsigned char base=10): string(mytoa(val, base)) {}
|
74
75
|
explicit String(long val, unsigned char base=10): string(mytoas(val, base)) {}
|
75
76
|
explicit String(unsigned long val, unsigned char base=10): string(mytoa(val, base)) {}
|
77
|
+
explicit String(long long val, unsigned char base=10): string(mytoas(val, base)) {}
|
78
|
+
explicit String(unsigned long long val, unsigned char base=10): string(mytoa(val, base)) {}
|
76
79
|
|
77
80
|
explicit String(float val, unsigned char decimalPlaces=2): string(dtoas(val, decimalPlaces)) {}
|
78
81
|
explicit String(double val, unsigned char decimalPlaces=2): string(dtoas(val, decimalPlaces)) {}
|
@@ -95,6 +98,8 @@ class String: public string
|
|
95
98
|
unsigned char concat(unsigned int num) { append(String(num)); return 1; }
|
96
99
|
unsigned char concat(long num) { append(String(num)); return 1; }
|
97
100
|
unsigned char concat(unsigned long num) { append(String(num)); return 1; }
|
101
|
+
unsigned char concat(long long num) { append(String(num)); return 1; }
|
102
|
+
unsigned char concat(unsigned long long num) { append(String(num)); return 1; }
|
98
103
|
unsigned char concat(float num) { append(String(num)); return 1; }
|
99
104
|
unsigned char concat(double num) { append(String(num)); return 1; }
|
100
105
|
|
@@ -107,6 +112,8 @@ class String: public string
|
|
107
112
|
String & operator += (unsigned int num) { concat(num); return *this; }
|
108
113
|
String & operator += (long num) { concat(num); return *this; }
|
109
114
|
String & operator += (unsigned long num) { concat(num); return *this; }
|
115
|
+
String & operator += (long long num) { concat(num); return *this; }
|
116
|
+
String & operator += (unsigned long long num) { concat(num); return *this; }
|
110
117
|
String & operator += (float num) { concat(num); return *this; }
|
111
118
|
String & operator += (double num) { concat(num); return *this; }
|
112
119
|
|
@@ -169,9 +176,15 @@ class String: public string
|
|
169
176
|
assign(substr(b, e - b + 1));
|
170
177
|
}
|
171
178
|
|
172
|
-
long toInt(void) const { return std::stol(*this); }
|
173
179
|
float toFloat(void) const { return std::stof(*this); }
|
174
180
|
double toDouble(void) const { return std::stod(*this); }
|
181
|
+
long toInt(void) const {
|
182
|
+
try {
|
183
|
+
return std::stol(*this);
|
184
|
+
} catch (std::out_of_range) {
|
185
|
+
return std::stoll(*this);
|
186
|
+
}
|
187
|
+
}
|
175
188
|
|
176
189
|
};
|
177
190
|
|
data/exe/arduino_ci_remote.rb
CHANGED
@@ -121,7 +121,7 @@ elsif config.platforms_to_unittest.empty?
|
|
121
121
|
else
|
122
122
|
config.platforms_to_unittest.each do |p|
|
123
123
|
board = all_platforms[p][:board]
|
124
|
-
assure("Switching to board for #{p} (#{board})") { @arduino_cmd.use_board(board) } unless last_board == board
|
124
|
+
# assure("Switching to board for #{p} (#{board})") { @arduino_cmd.use_board(board) } unless last_board == board
|
125
125
|
last_board = board
|
126
126
|
cpp_library.test_files.each do |unittest_path|
|
127
127
|
unittest_name = File.basename(unittest_path)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "arduino_ci/host"
|
2
|
+
require 'arduino_ci/arduino_cmd'
|
3
|
+
|
4
|
+
module ArduinoCI
|
5
|
+
|
6
|
+
# Implementation of OSX commands
|
7
|
+
class ArduinoCmdWindows < ArduinoCmd
|
8
|
+
flag :get_pref, "--get-pref"
|
9
|
+
flag :set_pref, "--pref"
|
10
|
+
flag :save_prefs, "--save-prefs"
|
11
|
+
flag :use_board, "--board"
|
12
|
+
flag :install_boards, "--install-boards"
|
13
|
+
flag :install_library, "--install-library"
|
14
|
+
flag :verify, "--verify"
|
15
|
+
|
16
|
+
# run the arduino command
|
17
|
+
# @return [bool] whether the command succeeded
|
18
|
+
def _run_and_output(*args, **kwargs)
|
19
|
+
Host.run_and_output(*args, **kwargs)
|
20
|
+
end
|
21
|
+
|
22
|
+
# run the arduino command
|
23
|
+
# @return [Hash] keys for :success, :out, and :err
|
24
|
+
def _run_and_capture(*args, **kwargs)
|
25
|
+
Host.run_and_capture(*args, **kwargs)
|
26
|
+
end
|
27
|
+
|
28
|
+
def _lib_dir
|
29
|
+
File.join(ENV['userprofile'], "Documents", "Arduino", "libraries")
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require 'open-uri'
|
3
|
+
require 'zip'
|
4
|
+
|
5
|
+
DOWNLOAD_ATTEMPTS = 3
|
6
|
+
|
7
|
+
module ArduinoCI
|
8
|
+
|
9
|
+
# Manage the OS-specific download & install of Arduino
|
10
|
+
class ArduinoDownloader
|
11
|
+
|
12
|
+
def initialize(desired_ide_version)
|
13
|
+
@desired_ide_version = desired_ide_version
|
14
|
+
end
|
15
|
+
|
16
|
+
# Provide guidelines to the implementer of this class
|
17
|
+
def self.must_implement(method)
|
18
|
+
raise NotImplementedError, "#{self.class.name} failed to implement ArduinoDownloader.#{method}"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Make any preparations or run any checks prior to making changes
|
22
|
+
# @return [string] Error message, or nil if success
|
23
|
+
def prepare
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
# The autolocated executable of the installation
|
28
|
+
#
|
29
|
+
# @return [string] or nil
|
30
|
+
def self.autolocated_executable
|
31
|
+
# Arbitrarily, I'm going to pick the force installed location first
|
32
|
+
# if it exists. I'm not sure why we would have both, but if we did
|
33
|
+
# a force install then let's make sure we actually use it.
|
34
|
+
locations = [self.force_installed_executable, self.existing_executable]
|
35
|
+
locations.each do |loc|
|
36
|
+
next if loc.nil?
|
37
|
+
next unless File.exist? loc
|
38
|
+
return loc
|
39
|
+
end
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
|
43
|
+
# The autolocated directory of the installation
|
44
|
+
#
|
45
|
+
# @return [string] or nil
|
46
|
+
def self.autolocated_installation
|
47
|
+
# Arbitrarily, I'm going to pick the force installed location first
|
48
|
+
# if it exists. I'm not sure why we would have both, but if we did
|
49
|
+
# a force install then let's make sure we actually use it.
|
50
|
+
locations = [self.force_install_location, self.existing_installation]
|
51
|
+
locations.each do |loc|
|
52
|
+
next if loc.nil?
|
53
|
+
next unless File.exist? loc
|
54
|
+
return loc
|
55
|
+
end
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
|
59
|
+
# The path to the directory of an existing installation, or nil
|
60
|
+
# @return [string]
|
61
|
+
def self.existing_installation
|
62
|
+
self.must_implement(__method__)
|
63
|
+
end
|
64
|
+
|
65
|
+
# The executable Arduino file in an existing installation, or nil
|
66
|
+
# @return [string]
|
67
|
+
def self.existing_executable
|
68
|
+
self.must_implement(__method__)
|
69
|
+
end
|
70
|
+
|
71
|
+
# The executable Arduino file in a forced installation, or nil
|
72
|
+
# @return [string]
|
73
|
+
def self.force_installed_executable
|
74
|
+
self.must_implement(__method__)
|
75
|
+
end
|
76
|
+
|
77
|
+
# The technology that will be used to complete the download
|
78
|
+
# (for logging purposes)
|
79
|
+
# @return [string]
|
80
|
+
def downloader
|
81
|
+
"open-uri"
|
82
|
+
end
|
83
|
+
|
84
|
+
# The technology that will be used to extract the download
|
85
|
+
# (for logging purposes)
|
86
|
+
# @return [string]
|
87
|
+
def extracter
|
88
|
+
"Zip"
|
89
|
+
end
|
90
|
+
|
91
|
+
# The URL of the desired IDE package (zip/tar/etc) for this platform
|
92
|
+
# @return [string]
|
93
|
+
def package_url
|
94
|
+
"https://downloads.arduino.cc/#{package_file}"
|
95
|
+
end
|
96
|
+
|
97
|
+
# The local file (dir) name of the desired IDE package (zip/tar/etc)
|
98
|
+
# @return [string]
|
99
|
+
def package_file
|
100
|
+
self.class.must_implement(__method__)
|
101
|
+
end
|
102
|
+
|
103
|
+
# The local filename of the extracted IDE package (zip/tar/etc)
|
104
|
+
# @return [string]
|
105
|
+
def extracted_file
|
106
|
+
self.class.must_implement(__method__)
|
107
|
+
end
|
108
|
+
|
109
|
+
# @return [String] The location where a forced install will go
|
110
|
+
def self.force_install_location
|
111
|
+
File.join(ENV['HOME'], 'arduino_ci_ide')
|
112
|
+
end
|
113
|
+
|
114
|
+
# Download the package_url to package_file
|
115
|
+
# @return [bool] whether successful
|
116
|
+
def download
|
117
|
+
# Turned off ssl verification
|
118
|
+
# This should be acceptable because it won't happen on a user's machine, just CI
|
119
|
+
|
120
|
+
# define a progress-bar printer
|
121
|
+
chunk_size = 1024 * 1024 * 1024
|
122
|
+
total_size = 0
|
123
|
+
dots = 0
|
124
|
+
dot_printer = lambda do |size|
|
125
|
+
total_size += size
|
126
|
+
needed_dots = (total_size / chunk_size).to_i
|
127
|
+
unprinted_dots = needed_dots - dots
|
128
|
+
print("." * unprinted_dots) if unprinted_dots > 0
|
129
|
+
dots = needed_dots
|
130
|
+
end
|
131
|
+
|
132
|
+
open(package_url, ssl_verify_mode: 0, progress_proc: dot_printer) do |url|
|
133
|
+
File.open(package_file, 'wb') { |file| file.write(url.read) }
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Extract the package_file to extracted_file
|
138
|
+
# @return [bool] whether successful
|
139
|
+
def extract
|
140
|
+
Zip::File.open(package_file) do |zip|
|
141
|
+
batch_size = [1, (zip.size / 100).to_i].max
|
142
|
+
dots = 0
|
143
|
+
zip.each do |file|
|
144
|
+
print "." if (dots % batch_size).zero?
|
145
|
+
file.restore_permissions = true
|
146
|
+
file.extract { accept_all }
|
147
|
+
dots += 1
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Move the extracted package file from extracted_file to the force_install_location
|
153
|
+
# @return [bool] whether successful
|
154
|
+
def install
|
155
|
+
# Move only the content of the directory
|
156
|
+
FileUtils.mv extracted_file, self.class.force_install_location
|
157
|
+
end
|
158
|
+
|
159
|
+
# Forcibly install Arduino on linux from the web
|
160
|
+
# @return [bool] Whether the command succeeded
|
161
|
+
def execute
|
162
|
+
error_preparing = prepare
|
163
|
+
unless error_preparing.nil?
|
164
|
+
puts "Arduino force-install failed preparation: #{error_preparing}"
|
165
|
+
return false
|
166
|
+
end
|
167
|
+
|
168
|
+
attempts = 0
|
169
|
+
|
170
|
+
loop do
|
171
|
+
if File.exist? package_file
|
172
|
+
puts "Arduino package seems to have been downloaded already" if attempts.zero?
|
173
|
+
break
|
174
|
+
elsif attempts >= DOWNLOAD_ATTEMPTS
|
175
|
+
break puts "After #{DOWNLOAD_ATTEMPTS} attempts, failed to download #{package_url}"
|
176
|
+
else
|
177
|
+
print "Attempting to download Arduino package with #{downloader}"
|
178
|
+
download
|
179
|
+
puts
|
180
|
+
end
|
181
|
+
attempts += 1
|
182
|
+
end
|
183
|
+
|
184
|
+
if File.exist? extracted_file
|
185
|
+
puts "Arduino package seems to have been extracted already"
|
186
|
+
elsif File.exist? package_file
|
187
|
+
print "Extracting archive with #{extracter}"
|
188
|
+
extract
|
189
|
+
puts
|
190
|
+
end
|
191
|
+
|
192
|
+
if File.exist? self.class.force_install_location
|
193
|
+
puts "Arduino package seems to have been installed already"
|
194
|
+
elsif File.exist? extracted_file
|
195
|
+
install
|
196
|
+
else
|
197
|
+
puts "Arduino force-install failed"
|
198
|
+
end
|
199
|
+
|
200
|
+
File.exist? self.class.force_install_location
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
end
|