arduino_ci 0.1.10 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,116 +0,0 @@
1
- require "arduino_ci/host"
2
- require "arduino_ci/arduino_cmd_osx"
3
- require "arduino_ci/arduino_cmd_linux"
4
- require "arduino_ci/arduino_cmd_linux_builder"
5
- require "arduino_ci/arduino_downloader_linux"
6
- require "arduino_ci/arduino_downloader_osx"
7
-
8
- DESIRED_ARDUINO_IDE_VERSION = "1.8.5".freeze
9
-
10
- module ArduinoCI
11
-
12
- # Manage the OS-specific install location of Arduino
13
- class ArduinoInstallation
14
-
15
- class << self
16
-
17
- # attempt to find a workable Arduino executable across platforms
18
- #
19
- # Autolocation assumed to be an expensive operation
20
- # @return [ArduinoCI::ArduinoCmd] an instance of the command or nil if it can't be found
21
- def autolocate
22
- ret = nil
23
- case Host.os
24
- when :osx then
25
- ret = autolocate_osx
26
- when :linux then
27
- <<<<<<< HEAD
28
- loc = ArduinoDownloaderLinux.autolocation
29
- return nil if loc.nil?
30
- ret = ArduinoCmdLinux.new
31
- ret.base_cmd = [loc]
32
- =======
33
- loc = ArduinoDownloaderLinux.autolocated_executable
34
- return nil if loc.nil?
35
- ret = ArduinoCmdLinux.new
36
- ret.base_cmd = [loc]
37
- # when :windows then
38
- # ArduinoDownloaderWindows.autolocation
39
- # return nil if loc.nil?
40
- # ret = ArduinoCmdWindows.new
41
- # ret.base_cmd = [loc]
42
- >>>>>>> Refactor force_install code in preparation for windows CI
43
- end
44
- ret
45
- end
46
-
47
- # @return [ArduinoCI::ArduinoCmdOSX] an instance of the command or nil if it can't be found
48
- def autolocate_osx
49
- <<<<<<< HEAD
50
- osx_root = ArduinoDownloaderOSX.autolocation
51
- =======
52
- osx_root = ArduinoDownloaderOSX.autolocated_installation
53
- return nil if osx_root.nil?
54
- >>>>>>> Refactor force_install code in preparation for windows CI
55
- return nil unless File.exist? osx_root
56
-
57
- launchers = [
58
- # try a hack that skips splash screen
59
- # from https://github.com/arduino/Arduino/issues/1970#issuecomment-321975809
60
- [
61
- "java",
62
- "-cp", "#{osx_root}/Java/*",
63
- "-DAPP_DIR=#{osx_root}/Java",
64
- "-Dfile.encoding=UTF-8",
65
- "-Dapple.awt.UIElement=true",
66
- "-Xms128M",
67
- "-Xmx512M",
68
- "processing.app.Base",
69
- ],
70
- # failsafe way
71
- [File.join(osx_root, "MacOS", "Arduino")]
72
- ]
73
-
74
- # create return and find a command launcher that works
75
- ret = ArduinoCmdOSX.new
76
- launchers.each do |launcher|
77
- # test whether this method successfully launches the IDE
78
- # note that "successful launch" involves a command that will fail,
79
- # because that's faster than any command which succeeds. what we
80
- # don't want to see is a java error.
81
- args = launcher + ["--bogus-option"]
82
- result = Host.run_and_capture(*args)
83
- if result[:err].include? "Error: unknown option: --bogus-option"
84
- ret.base_cmd = launcher
85
- return ret
86
- end
87
- end
88
- nil
89
- end
90
-
91
- # Attempt to find a workable Arduino executable across platforms, and install it if we don't
92
- # @return [ArduinoCI::ArduinoCmd] an instance of a command
93
- def autolocate!
94
- candidate = autolocate
95
- return candidate unless candidate.nil?
96
-
97
- # force the install
98
- force_install
99
- autolocate
100
- end
101
-
102
- # Forcibly install Arduino from the web
103
- # @return [bool] Whether the command succeeded
104
- def force_install
105
- worker_class = case Host.os
106
- when :osx then ArduinoDownloaderOSX
107
- # when :windows then force_install_windows
108
- when :linux then ArduinoDownloaderLinux
109
- end
110
- worker = worker_class.new(DESIRED_ARDUINO_IDE_VERSION)
111
- worker.execute
112
- end
113
-
114
- end
115
- end
116
- end
@@ -1,192 +0,0 @@
1
- require 'arduino_ci/host'
2
- require 'singleton'
3
- require 'timeout'
4
-
5
- DESIRED_DISPLAY = ":1.0".freeze
6
-
7
- module ArduinoCI
8
-
9
- # When arduino commands run, they need a graphical display.
10
- # This class handles the setup of that display, if needed.
11
- class DisplayManager
12
- include Singleton
13
-
14
- # @return [bool] whether the display manager is currently active
15
- attr_reader :enabled
16
-
17
- # @return [bool] whether to log messages to the terminal
18
- attr_accessor :debug
19
-
20
- def initialize
21
- @existing = existing_display?
22
- @enabled = false
23
- @pid = nil
24
- @debug = false
25
-
26
- # pipes for input and output
27
- @xv_pipe_out_wr = nil
28
- @xv_pipe_err_wr = nil
29
- @xv_pipe_out = nil
30
- @xv_pipe_err = nil
31
- end
32
-
33
- # attempt to determine if the machine is running a graphical display (i.e. not Travis)
34
- # @return [bool] whether there is already a GUI that can accept windows
35
- def existing_display?
36
- return true if RUBY_PLATFORM.include? "darwin"
37
- return true if Host.os == :windows
38
- return false if ENV["DISPLAY"].nil?
39
- return true if ENV["DISPLAY"].include? ":"
40
- false
41
- end
42
-
43
- # check whether a process is alive
44
- # https://stackoverflow.com/a/32513298/2063546
45
- # @param pid [Int] the process ID
46
- # @return [bool]
47
- def alive?(pid)
48
- Process.kill(0, pid)
49
- true
50
- rescue
51
- false
52
- end
53
-
54
- # check whether an X server is taking connections
55
- # @param display [String] the display variable as it would be specified in the environment
56
- # @return [bool]
57
- def xserver_exist?(display)
58
- system({ "DISPLAY" => display }, "xdpyinfo", out: File::NULL, err: File::NULL)
59
- end
60
-
61
- # wait for the xvfb command to launch
62
- # @param display [String] the value of the DISPLAY env var
63
- # @param pid [Int] the process of Xvfb
64
- # @param timeout [Int] the timeout in seconds
65
- # @return [Bool] whether we detected a launch
66
- def xvfb_launched?(display, pid, timeout)
67
- Timeout.timeout(timeout) do
68
- loop do
69
- unless alive? pid
70
- puts "Xvfb process has died"
71
- return false
72
- end
73
- x = xserver_exist? display
74
- puts "xdpyinfo reports X server status as #{x}" if debug
75
- return true if x
76
- sleep(0.1)
77
- end
78
- end
79
- rescue Timeout::Error
80
- false
81
- end
82
-
83
- # enable a virtual display
84
- def enable
85
- if @existing
86
- puts "DisplayManager enable: no-op for what appears to be an existing display" if debug
87
- @enabled = true
88
- return
89
- end
90
-
91
- return unless @pid.nil? # TODO: disable first?
92
- @xv_pipe_out.close unless @xv_pipe_out.nil?
93
- @xv_pipe_err.close unless @xv_pipe_err.nil?
94
-
95
- # open Xvfb
96
- xvfb_cmd = [
97
- "Xvfb",
98
- "+extension", "RANDR",
99
- ":1",
100
- "-ac",
101
- "-screen", "0",
102
- "1280x1024x16",
103
- ]
104
- puts "Xvfb launching" if debug
105
-
106
- @xv_pipe_out, @xv_pipe_out_wr = IO.pipe
107
- @xv_pipe_err, @xv_pipe_err_wr = IO.pipe
108
- pipe = IO.popen(xvfb_cmd, stdout: @xv_pipe_out_wr, err: @xv_pipe_err_wr)
109
- @pid = pipe.pid
110
- @enabled = xvfb_launched?(DESIRED_DISPLAY, @pid, 30)
111
- end
112
-
113
- # disable the virtual display
114
- def disable
115
- if @existing
116
- puts "DisplayManager disable: no-op for what appears to be an existing display" if debug
117
- return @enabled = false
118
- end
119
-
120
- return @enabled = false if @pid.nil?
121
-
122
- # https://www.whatastruggle.com/timeout-a-subprocess-in-ruby
123
- begin
124
- Timeout.timeout(30) do
125
- Process.kill("TERM", @pid)
126
- puts "Xvfb TERMed" if debug
127
- end
128
- rescue Timeout::Error
129
- Process.kill(9, @pid)
130
- puts "Xvfb KILLed" if debug
131
- ensure
132
- Process.wait @pid
133
- @enabled = false
134
- @pid = nil
135
-
136
- @xv_pipe_out_wr.close
137
- @xv_pipe_err_wr.close
138
- end
139
- end
140
-
141
- # Enable a virtual display for the duration of the given block
142
- # @yield [environment] The code to execute within the display environment
143
- # @yieldparam [Hash] the environment variables relating to the display
144
- def with_display
145
- was_enabled = @enabled
146
- enable unless was_enabled
147
- begin
148
- yield environment
149
- ensure
150
- disable unless was_enabled
151
- end
152
- end
153
-
154
- def wrap_run(work_fn, *args, **kwargs)
155
- ret = nil
156
- # do some work to extract & merge environment variables if they exist
157
- has_env = !args.empty? && args[0].class == Hash
158
- with_display do |env_vars|
159
- env_vars = {} if env_vars.nil?
160
- env_vars.merge!(args[0]) if has_env
161
- actual_args = has_env ? args[1..-1] : args # need to shift over if we extracted args
162
- full_cmd = env_vars.empty? ? actual_args : [env_vars] + actual_args
163
- ret = work_fn.call(*full_cmd, **kwargs)
164
- end
165
- ret
166
- end
167
-
168
- # run a command in a display, outputting to stdout
169
- # @return [bool]
170
- def run_and_output(*args, **kwargs)
171
- wrap_run((proc { |*a, **k| Host.run_and_output(*a, **k) }), *args, **kwargs)
172
- end
173
-
174
- # run a command in a display, capturing output
175
- # @return [bool]
176
- def run_and_capture(*args, **kwargs)
177
- wrap_run((proc { |*a, **k| Host.run_and_capture(*a, **k) }), *args, **kwargs)
178
- end
179
-
180
- # @return [Hash] the environment variables for the display
181
- def environment
182
- return nil unless @existing || @enabled
183
- return { "EXISTING_DISPLAY" => "YES" } if @existing
184
- { "DISPLAY" => DESIRED_DISPLAY }
185
- end
186
-
187
- # On finalize, ensure child process is ended
188
- def self.finalize
189
- disable
190
- end
191
- end
192
- end