arduino_ci 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,5 @@
1
1
  require 'fileutils'
2
+ require 'pathname'
2
3
  require 'net/http'
3
4
  require 'open-uri'
4
5
  require 'zip'
@@ -10,10 +11,10 @@ module ArduinoCI
10
11
  # Manage the OS-specific download & install of Arduino
11
12
  class ArduinoDownloader
12
13
 
13
- # @param desired_ide_version [string] Version string e.g. 1.8.7
14
+ # @param desired_version [string] Version string e.g. 1.8.7
14
15
  # @param output [IO] $stdout, $stderr, File.new(/dev/null, 'w'), etc. where console output will be sent
15
- def initialize(desired_ide_version, output = $stdout)
16
- @desired_ide_version = desired_ide_version
16
+ def initialize(desired_version, output = $stdout)
17
+ @desired_version = desired_version
17
18
  @output = output
18
19
  end
19
20
 
@@ -30,7 +31,7 @@ module ArduinoCI
30
31
 
31
32
  # The autolocated executable of the installation
32
33
  #
33
- # @return [string] or nil
34
+ # @return [Pathname] or nil
34
35
  def self.autolocated_executable
35
36
  # Arbitrarily, I'm going to pick the force installed location first
36
37
  # if it exists. I'm not sure why we would have both, but if we did
@@ -39,70 +40,54 @@ module ArduinoCI
39
40
  locations.find { |loc| !loc.nil? && File.exist?(loc) }
40
41
  end
41
42
 
42
- # The autolocated directory of the installation
43
- #
44
- # @return [string] or nil
45
- def self.autolocated_installation
46
- # Arbitrarily, I'm going to pick the force installed location first
47
- # if it exists. I'm not sure why we would have both, but if we did
48
- # a force install then let's make sure we actually use it.
49
- locations = [self.force_install_location, self.existing_installation]
50
- locations.find { |loc| !loc.nil? && File.exist?(loc) }
43
+ # The executable Arduino file in an existing installation, or nil
44
+ # @return [Pathname]
45
+ def self.existing_executable
46
+ self.must_implement(__method__)
51
47
  end
52
48
 
53
- # The path to the directory of an existing installation, or nil
49
+ # The local file (dir) name of the desired IDE package (zip/tar/etc)
54
50
  # @return [string]
55
- def self.existing_installation
56
- self.must_implement(__method__)
51
+ def package_file
52
+ self.class.must_implement(__method__)
57
53
  end
58
54
 
59
- # The executable Arduino file in an existing installation, or nil
55
+ # The local filename of the extracted IDE package (zip/tar/etc)
60
56
  # @return [string]
61
- def self.existing_executable
57
+ def self.extracted_file
62
58
  self.must_implement(__method__)
63
59
  end
64
60
 
65
61
  # The executable Arduino file in a forced installation, or nil
66
- # @return [string]
62
+ # @return [Pathname]
67
63
  def self.force_installed_executable
68
- self.must_implement(__method__)
64
+ Pathname.new(ENV['HOME']) + self.extracted_file
69
65
  end
70
66
 
71
67
  # The technology that will be used to complete the download
72
68
  # (for logging purposes)
73
69
  # @return [string]
74
- def downloader
70
+ def self.downloader
75
71
  "open-uri"
76
72
  end
77
73
 
78
74
  # The technology that will be used to extract the download
79
75
  # (for logging purposes)
80
76
  # @return [string]
81
- def extracter
82
- "Zip"
83
- end
84
-
85
- # The URL of the desired IDE package (zip/tar/etc) for this platform
86
- # @return [string]
87
- def package_url
88
- "https://downloads.arduino.cc/#{package_file}"
77
+ def self.extracter
78
+ self.must_implement(__method__)
89
79
  end
90
80
 
91
- # The local file (dir) name of the desired IDE package (zip/tar/etc)
92
- # @return [string]
93
- def package_file
94
- self.class.must_implement(__method__)
81
+ # Extract the package_file to extracted_file
82
+ # @return [bool] whether successful
83
+ def self.extract(_package_file)
84
+ self.must_implement(__method__)
95
85
  end
96
86
 
97
- # The local filename of the extracted IDE package (zip/tar/etc)
87
+ # The URL of the desired IDE package (zip/tar/etc) for this platform
98
88
  # @return [string]
99
- def extracted_file
100
- self.class.must_implement(__method__)
101
- end
102
-
103
- # @return [String] The location where a forced install will go
104
- def self.force_install_location
105
- File.join(ENV['HOME'], 'arduino_ci_ide')
89
+ def package_url
90
+ "https://github.com/arduino/arduino-cli/releases/download/#{@desired_version}/#{package_file}"
106
91
  end
107
92
 
108
93
  # Download the package_url to package_file
@@ -130,26 +115,10 @@ module ArduinoCI
130
115
  @output.puts "\nArduino force-install failed downloading #{package_url}: #{e}"
131
116
  end
132
117
 
133
- # Extract the package_file to extracted_file
134
- # @return [bool] whether successful
135
- def extract
136
- Zip::File.open(package_file) do |zip|
137
- batch_size = [1, (zip.size / 100).to_i].max
138
- dots = 0
139
- zip.each do |file|
140
- @output.print "." if (dots % batch_size).zero?
141
- file.restore_permissions = true
142
- file.extract { accept_all }
143
- dots += 1
144
- end
145
- end
146
- end
147
-
148
- # Move the extracted package file from extracted_file to the force_install_location
118
+ # Move the extracted package file from extracted_file to the force_installed_executable
149
119
  # @return [bool] whether successful
150
120
  def install
151
- # Move only the content of the directory
152
- FileUtils.mv extracted_file, self.class.force_install_location
121
+ FileUtils.mv self.class.extracted_file.to_s, self.class.force_installed_executable.to_s
153
122
  end
154
123
 
155
124
  # Forcibly install Arduino on linux from the web
@@ -161,40 +130,40 @@ module ArduinoCI
161
130
  return false
162
131
  end
163
132
 
164
- arduino_package = "Arduino #{@desired_ide_version} package"
133
+ arduino_package = "Arduino #{@desired_version} package"
165
134
  attempts = 0
166
135
 
167
136
  loop do
168
- if File.exist? package_file
169
- @output.puts "#{arduino_package} seems to have been downloaded already" if attempts.zero?
137
+ if File.exist?(package_file)
138
+ @output.puts "#{arduino_package} seems to have been downloaded already at #{package_file}" if attempts.zero?
170
139
  break
171
140
  elsif attempts >= DOWNLOAD_ATTEMPTS
172
141
  break @output.puts "After #{DOWNLOAD_ATTEMPTS} attempts, failed to download #{package_url}"
173
142
  else
174
- @output.print "Attempting to download #{arduino_package} with #{downloader}"
143
+ @output.print "Attempting to download #{arduino_package} with #{self.class.downloader}"
175
144
  download
176
145
  @output.puts
177
146
  end
178
147
  attempts += 1
179
148
  end
180
149
 
181
- if File.exist? extracted_file
182
- @output.puts "#{arduino_package} seems to have been extracted already"
183
- elsif File.exist? package_file
184
- @output.print "Extracting archive with #{extracter}"
185
- extract
150
+ if File.exist?(self.class.extracted_file)
151
+ @output.puts "#{arduino_package} seems to have been extracted already at #{self.class.extracted_file}"
152
+ elsif File.exist?(package_file)
153
+ @output.print "Extracting archive with #{self.class.extracter}"
154
+ self.class.extract(package_file)
186
155
  @output.puts
187
156
  end
188
157
 
189
- if File.exist? self.class.force_install_location
190
- @output.puts "#{arduino_package} seems to have been installed already"
191
- elsif File.exist? extracted_file
158
+ if File.exist?(self.class.force_installed_executable)
159
+ @output.puts "#{arduino_package} seems to have been installed already at #{self.class.force_installed_executable}"
160
+ elsif File.exist?(self.class.extracted_file)
192
161
  install
193
162
  else
194
- @output.puts "Could not find extracted archive (tried #{extracted_file})"
163
+ @output.puts "Could not find extracted archive (tried #{self.class.extracted_file})"
195
164
  end
196
165
 
197
- File.exist? self.class.force_install_location
166
+ File.exist?(self.class.force_installed_executable)
198
167
  end
199
168
 
200
169
  end
@@ -1,7 +1,5 @@
1
1
  require "arduino_ci/arduino_downloader"
2
2
 
3
- USE_BUILDER = false
4
-
5
3
  module ArduinoCI
6
4
 
7
5
  # Manage the linux download & install of Arduino
@@ -10,13 +8,25 @@ module ArduinoCI
10
8
  # The local filename of the desired IDE package (zip/tar/etc)
11
9
  # @return [string]
12
10
  def package_file
13
- "#{extracted_file}-linux64.tar.xz"
11
+ "arduino-cli_#{@desired_version}_Linux_64bit.tar.gz"
12
+ end
13
+
14
+ # The local file (dir) name of the extracted IDE package (zip/tar/etc)
15
+ # @return [string]
16
+ def self.extracted_file
17
+ "arduino-cli"
18
+ end
19
+
20
+ # The executable Arduino file in an existing installation, or nil
21
+ # @return [string]
22
+ def self.existing_executable
23
+ Host.which("arduino-cli")
14
24
  end
15
25
 
16
26
  # Make any preparations or run any checks prior to making changes
17
27
  # @return [string] Error message, or nil if success
18
28
  def prepare
19
- reqs = [extracter]
29
+ reqs = [self.class.extracter]
20
30
  reqs.each do |req|
21
31
  return "#{req} does not appear to be installed!" unless Host.which(req)
22
32
  end
@@ -26,62 +36,14 @@ module ArduinoCI
26
36
  # The technology that will be used to extract the download
27
37
  # (for logging purposes)
28
38
  # @return [string]
29
- def extracter
39
+ def self.extracter
30
40
  "tar"
31
41
  end
32
42
 
33
43
  # Extract the package_file to extracted_file
34
44
  # @return [bool] whether successful
35
- def extract
36
- system(extracter, "xf", package_file)
37
- end
38
-
39
- # The local file (dir) name of the extracted IDE package (zip/tar/etc)
40
- # @return [string]
41
- def extracted_file
42
- "arduino-#{@desired_ide_version}"
43
- end
44
-
45
- # The path to the directory of an existing installation, or nil
46
- # @return [string]
47
- def self.existing_installation
48
- exe = self.existing_executable
49
- return nil if exe.nil?
50
-
51
- File.dirname(exe) # it's not really this
52
- # but for this platform it doesn't really matter
53
- end
54
-
55
- # The executable Arduino file in an existing installation, or nil
56
- # @return [string]
57
- def self.existing_executable
58
- if USE_BUILDER
59
- # builder_name = "arduino-builder"
60
- # cli_place = Host.which(builder_name)
61
- # unless cli_place.nil?
62
- # ret = ArduinoCmdLinuxBuilder.new
63
- # ret.base_cmd = [cli_place]
64
- # return ret
65
- # end
66
- end
67
- Host.which("arduino")
68
- end
69
-
70
- # The executable Arduino file in a forced installation, or nil
71
- # @return [string]
72
- def self.force_installed_executable
73
- if USE_BUILDER
74
- # forced_builder = File.join(ArduinoCmdLinuxBuilder.force_install_location, builder_name)
75
- # if File.exist?(forced_builder)
76
- # ret = ArduinoCmdLinuxBuilder.new
77
- # ret.base_cmd = [forced_builder]
78
- # return ret
79
- # end
80
- end
81
- forced_arduino = File.join(self.force_install_location, "arduino")
82
- return forced_arduino if File.exist? forced_arduino
83
-
84
- nil
45
+ def self.extract(package_file)
46
+ system(extracter, "xf", package_file, extracted_file)
85
47
  end
86
48
 
87
49
  end
@@ -8,54 +8,42 @@ module ArduinoCI
8
8
  # The local filename of the desired IDE package (zip/tar/etc)
9
9
  # @return [string]
10
10
  def package_file
11
- "arduino-#{@desired_ide_version}-macosx.zip"
11
+ "arduino-cli_#{@desired_version}_macOS_64bit.tar.gz"
12
12
  end
13
13
 
14
14
  # The local file (dir) name of the extracted IDE package (zip/tar/etc)
15
15
  # @return [string]
16
- def extracted_file
17
- "Arduino.app"
16
+ def self.extracted_file
17
+ "arduino-cli"
18
18
  end
19
19
 
20
- # @return [String] The location where a forced install will go
21
- def self.force_install_location
22
- # include the .app extension
23
- File.join(ENV['HOME'], 'Arduino.app')
24
- end
25
-
26
- # An existing Arduino directory in one of the given directories, or nil
27
- # @param Array<string> a list of places to look
20
+ # The executable Arduino file in an existing installation, or nil
28
21
  # @return [string]
29
- def self.find_existing_arduino_dir(paths)
30
- paths.find(&File.method(:exist?))
22
+ def self.existing_executable
23
+ Host.which("arduino-cli")
31
24
  end
32
25
 
33
- # An existing Arduino file in one of the given directories, or nil
34
- # @param Array<string> a list of places to look for the executable
35
- # @return [string]
36
- def self.find_existing_arduino_exe(paths)
37
- paths.find do |path|
38
- exe = File.join(path, "MacOS", "Arduino")
39
- File.exist? exe
26
+ # Make any preparations or run any checks prior to making changes
27
+ # @return [string] Error message, or nil if success
28
+ def prepare
29
+ reqs = [self.class.extracter]
30
+ reqs.each do |req|
31
+ return "#{req} does not appear to be installed!" unless Host.which(req)
40
32
  end
33
+ nil
41
34
  end
42
35
 
43
- # The path to the directory of an existing installation, or nil
36
+ # The technology that will be used to extract the download
37
+ # (for logging purposes)
44
38
  # @return [string]
45
- def self.existing_installation
46
- self.find_existing_arduino_dir(["/Applications/Arduino.app"])
39
+ def self.extracter
40
+ "tar"
47
41
  end
48
42
 
49
- # The executable Arduino file in an existing installation, or nil
50
- # @return [string]
51
- def self.existing_executable
52
- self.find_existing_arduino_exe(["/Applications/Arduino.app"])
53
- end
54
-
55
- # The executable Arduino file in a forced installation, or nil
56
- # @return [string]
57
- def self.force_installed_executable
58
- self.find_existing_arduino_exe([self.force_install_location])
43
+ # Extract the package_file to extracted_file
44
+ # @return [bool] whether successful
45
+ def self.extract(package_file)
46
+ system(extracter, "xf", package_file, extracted_file)
59
47
  end
60
48
 
61
49
  end
@@ -10,19 +10,6 @@ module ArduinoCI
10
10
  # Manage the POSIX download & install of Arduino
11
11
  class ArduinoDownloaderWindows < ArduinoDownloader
12
12
 
13
- # Make any preparations or run any checks prior to making changes
14
- # @return [string] Error message, or nil if success
15
- def prepare
16
- nil
17
- end
18
-
19
- # The technology that will be used to complete the download
20
- # (for logging purposes)
21
- # @return [string]
22
- def downloader
23
- "open-uri"
24
- end
25
-
26
13
  # Download the package_url to package_file
27
14
  # @return [bool] whether successful
28
15
  def download
@@ -35,29 +22,28 @@ module ArduinoCI
35
22
  @output.puts "\nArduino force-install failed downloading #{package_url}: #{e}"
36
23
  end
37
24
 
38
- # Move the extracted package file from extracted_file to the force_install_location
39
- # @return [bool] whether successful
40
- def install
41
- # Move only the content of the directory
42
- FileUtils.mv extracted_file, self.class.force_install_location
43
- end
44
-
45
25
  # The local filename of the desired IDE package (zip/tar/etc)
46
26
  # @return [string]
47
27
  def package_file
48
- "#{extracted_file}-windows.zip"
28
+ "arduino-cli_#{@desired_version}_Windows_64bit.zip"
29
+ end
30
+
31
+ # The executable Arduino file in an existing installation, or nil
32
+ # @return [string]
33
+ def self.existing_executable
34
+ Host.which("arduino-cli")
49
35
  end
50
36
 
51
37
  # The technology that will be used to extract the download
52
38
  # (for logging purposes)
53
39
  # @return [string]
54
- def extracter
40
+ def self.extracter
55
41
  "Expand-Archive"
56
42
  end
57
43
 
58
44
  # Extract the package_file to extracted_file
59
45
  # @return [bool] whether successful
60
- def extract
46
+ def self.extract(package_file)
61
47
  Zip::File.open(package_file) do |zip|
62
48
  zip.each do |file|
63
49
  file.extract(file.name)
@@ -67,36 +53,8 @@ module ArduinoCI
67
53
 
68
54
  # The local file (dir) name of the extracted IDE package (zip/tar/etc)
69
55
  # @return [string]
70
- def extracted_file
71
- "arduino-#{@desired_ide_version}"
72
- end
73
-
74
- # The path to the directory of an existing installation, or nil
75
- # @return [string]
76
- def self.existing_installation
77
- exe = self.existing_executable
78
- return nil if exe.nil?
79
-
80
- File.dirname(exe)
81
- end
82
-
83
- # The executable Arduino file in an existing installation, or nil
84
- # @return [string]
85
- def self.existing_executable
86
- arduino_reg = 'SOFTWARE\WOW6432Node\Arduino'
87
- Win32::Registry::HKEY_LOCAL_MACHINE.open(arduino_reg).find do |reg|
88
- path = reg.read_s('Install_Dir')
89
- exe = File.join(path, "arduino_debug.exe")
90
- File.exist? exe
91
- end
92
- rescue
93
- nil
94
- end
95
-
96
- # The executable Arduino file in a forced installation, or nil
97
- # @return [string]
98
- def self.force_installed_executable
99
- File.join(self.force_install_location, "arduino_debug.exe")
56
+ def self.extracted_file
57
+ "arduino-cli.exe"
100
58
  end
101
59
 
102
60
  end