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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba79db50704899ffaddb90377d82f1f115f10c8c3b70d967074d867c80e5133b
4
- data.tar.gz: 57d1b65dee62b5c3ad9f5e9cb2ed867f18e7fcd5fffc15ccab835de31ddf021c
3
+ metadata.gz: b3120211b8610970115b711ea7647e43db7382f65baf3f5b58290c914e6bb68d
4
+ data.tar.gz: 976468bc18dd707eb5eeab43d020e034e57e9d898cd2cb140e2e7c2398a9ca11
5
5
  SHA512:
6
- metadata.gz: 68cb0b6c5778c1d6478b0aff085a9937971744d20d8f863f8c57b3bb8e9ae2bfc1eac12bb00cf696171e571718f6b5ad4d0fb3837b4307ef612488c9370bcaf7
7
- data.tar.gz: 24c7888ed4ddfd10c5eec94294d0608adec270b83ae1f9486b3f4a72763d3ba66723531a8ed250dd7004891b35f1ce19524f5b40318f7e2b953a7cbf8e630dfa
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
- [Arduino CI](https://github.com/ifreecarve/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.
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/ifreecarve/arduino_ci/issues
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 (ifreecarve@gmail.com) in 2018. It's released under the Apache 2.0 license.
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
@@ -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"
@@ -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
 
@@ -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;
@@ -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 ::isnan
15
- #define ARDUINOCI_ISINF ::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
 
@@ -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)
@@ -274,7 +274,7 @@ module ArduinoCI
274
274
  end
275
275
 
276
276
  # install the library
277
- FileUtils.ln_s(realpath, destination_path)
277
+ Host.symlink(realpath, destination_path)
278
278
  destination_path
279
279
  end
280
280
 
@@ -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