arduino_ci 0.1.10 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -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