Class: ArduinoCI::Host
- Inherits:
-
Object
- Object
- ArduinoCI::Host
- Defined in:
- lib/arduino_ci/host.rb
Overview
Tools for interacting with the host machine
Constant Summary collapse
- WINDOWS_VARIANT_REGEX =
TODO: this came from stackoverflow.com/a/22716582/2063546
and I'm not sure if it can be replaced by self.os == :windows
/mswin32|cygwin|mingw|bccwin/.freeze
- DIR_SYMLINK_REGEX =
e.g. 11/27/2020 01:02 AM <SYMLINKD> ExcludeSomething [C:projectsarduino-ciSampleProjectsExcludeSomething]
%r{\d+/\d+/\d+\s+[^<]+<SYMLINKD?>\s+(.*) \[([^\]]+)\]}.freeze
Class Method Summary collapse
-
.merge_capture_results(*args) ⇒ Hash
Merge multiple capture results into one aggregate value.
-
.needs_symlink_hack? ⇒ bool
Whether this OS requires a hack for symlinks.
-
.os ⇒ Object
return [Symbol] the operating system of the host.
-
.pathname_to_windows(path) ⇒ String
Hack for “realpath” which on windows joins paths with slashes instead of backslashes.
-
.readlink(path) ⇒ Pathname
Cross-platform “read link” function.
-
.run_and_capture(*args, **kwargs) ⇒ Hash
Execute a shell command and capture stdout, stderr, and status.
-
.run_and_output(*args, **kwargs) ⇒ Object
Execute a shell command.
-
.symlink(old_path, new_path) ⇒ Object
Cross-platform symlinking if on windows, call mklink, else self.symlink.
-
.symlink?(path) ⇒ bool
Cross-platform is-this-a-symlink function.
-
.which(cmd) ⇒ Pathname
Cross-platform way of finding an executable in the $PATH.
-
.windows_to_pathname(str) ⇒ Pathname
Hack for “realpath” which on windows joins paths with slashes instead of backslashes.
Class Method Details
.merge_capture_results(*args) ⇒ Hash
Merge multiple capture results into one aggregate value
47 48 49 50 51 52 53 |
# File 'lib/arduino_ci/host.rb', line 47 def self.merge_capture_results(*args) { out: args.map { |a| a[:out] }.join, err: args.map { |a| a[:err] }.join, success: args.all? { |a| a[:success] } } end |
.needs_symlink_hack? ⇒ bool
Whether this OS requires a hack for symlinks
104 105 106 |
# File 'lib/arduino_ci/host.rb', line 104 def self.needs_symlink_hack? RUBY_PLATFORM =~ WINDOWS_VARIANT_REGEX end |
.os ⇒ Object
return [Symbol] the operating system of the host
63 64 65 66 67 |
# File 'lib/arduino_ci/host.rb', line 63 def self.os return :osx if OS.osx? return :linux if OS.linux? return :windows if OS.windows? end |
.pathname_to_windows(path) ⇒ String
Hack for “realpath” which on windows joins paths with slashes instead of backslashes
91 92 93 |
# File 'lib/arduino_ci/host.rb', line 91 def self.pathname_to_windows(path) path.to_s.tr("/", "\\") end |
.readlink(path) ⇒ Pathname
Cross-platform “read link” function
120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/arduino_ci/host.rb', line 120 def self.readlink(path) return path.readlink unless needs_symlink_hack? the_dir = pathname_to_windows(path.parent) the_file = path.basename.to_s stdout, _stderr, _exitstatus = Open3.capture3('cmd.exe', "/c dir /al #{the_dir}") symlinks = stdout.lines.map { |l| DIR_SYMLINK_REGEX.match(l.scrub) }.compact our_link = symlinks.find { |m| m[1] == the_file } return nil if our_link.nil? windows_to_pathname(our_link[2]) end |
.run_and_capture(*args, **kwargs) ⇒ Hash
Execute a shell command and capture stdout, stderr, and status
38 39 40 41 |
# File 'lib/arduino_ci/host.rb', line 38 def self.run_and_capture(*args, **kwargs) stdout, stderr, status = Open3.capture3(*args, **kwargs) { out: stdout, err: stderr, success: status.exitstatus.zero? } end |
.run_and_output(*args, **kwargs) ⇒ Object
Execute a shell command
58 59 60 |
# File 'lib/arduino_ci/host.rb', line 58 def self.run_and_output(*args, **kwargs) system(*args, **kwargs) end |
.symlink(old_path, new_path) ⇒ Object
Cross-platform symlinking if on windows, call mklink, else self.symlink
73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/arduino_ci/host.rb', line 73 def self.symlink(old_path, new_path) # we would prefer `new_path.make_symlink(old_path)` but "symlink function is unimplemented on this machine" with windows return new_path.make_symlink(old_path) unless needs_symlink_hack? # via https://stackoverflow.com/a/22716582/2063546 # windows mklink syntax is reverse of unix ln -s # windows mklink is built into cmd.exe # vulnerable to command injection, but okay because this is a hack to make a cli tool work. orp = pathname_to_windows(old_path.realpath) np = pathname_to_windows(new_path) _stdout, _stderr, exitstatus = Open3.capture3('cmd.exe', "/C mklink /D #{np} #{orp}") exitstatus.success? end |
.symlink?(path) ⇒ bool
Cross-platform is-this-a-symlink function
111 112 113 114 115 |
# File 'lib/arduino_ci/host.rb', line 111 def self.symlink?(path) return path.symlink? unless needs_symlink_hack? !readlink(path).nil? end |
.which(cmd) ⇒ Pathname
Cross-platform way of finding an executable in the $PATH. via stackoverflow.com/a/5471032/2063546
which('ruby') #=> /usr/bin/ruby
21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/arduino_ci/host.rb', line 21 def self.which(cmd) exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] ENV['PATH'].split(File::PATH_SEPARATOR).each do |string_path| path = OS.windows? ? windows_to_pathname(string_path) : Pathname.new(string_path) exts.each do |ext| exe = path.join("#{cmd}#{ext}") return exe if exe.executable? && !exe.directory? end end nil end |
.windows_to_pathname(str) ⇒ Pathname
Hack for “realpath” which on windows joins paths with slashes instead of backslashes
98 99 100 |
# File 'lib/arduino_ci/host.rb', line 98 def self.windows_to_pathname(str) Pathname.new(str.tr("\\", "/")) end |