Class: Aspera::Environment
- Inherits:
-
Object
- Object
- Aspera::Environment
- Includes:
- Singleton
- Defined in:
- lib/aspera/environment.rb
Overview
detect OS, architecture, and specific stuff
Constant Summary collapse
- USER_INTERFACES =
%i[text graphical].freeze
- OS_WINDOWS =
:windows
- OS_MACOS =
:osx
- OS_LINUX =
:linux
- OS_AIX =
:aix
- OS_LIST =
[OS_WINDOWS, OS_MACOS, OS_LINUX, OS_AIX].freeze
- CPU_X86_64 =
:x86_64
- CPU_ARM64 =
:arm64
- CPU_PPC64 =
:ppc64
- CPU_PPC64LE =
:ppc64le
- CPU_S390 =
:s390
- CPU_LIST =
[CPU_X86_64, CPU_ARM64, CPU_PPC64, CPU_PPC64LE, CPU_S390].freeze
- BITS_PER_BYTE =
8
- MEBI =
1024 * 1024
- BYTES_PER_MEBIBIT =
MEBI / BITS_PER_BYTE
Instance Attribute Summary collapse
-
#url_method ⇒ Object
Returns the value of attribute url_method.
Class Method Summary collapse
-
.architecture ⇒ Object
normalized architecture name see constants: OS_* and CPU_*.
- .cpu ⇒ Object
-
.default_gui_mode ⇒ Object
:text or :graphical depending on the environment.
-
.empty_binding ⇒ Object
empty variable binding for secure eval.
-
.exe_file(name = '') ⇒ Object
executable file extension for current OS.
-
.fix_home ⇒ Object
on Windows, the env var %USERPROFILE% provides the path to user’s home more reliably than %HOMEDRIVE%%HOMEPATH% so, tell Ruby the right way.
- .log_spawn(env:, exec:, args:) ⇒ Object
-
.open_editor(file_path) ⇒ Object
open a file in an editor.
-
.open_uri_graphical(uri) ⇒ Object
open a URI in a graphical browser command must be non blocking.
- .os ⇒ Object
-
.restrict_file_access(path, mode: nil) ⇒ Object
restrict access to a file or folder to user only.
- .ruby_version ⇒ Object
-
.secure_capture(exec:, args: [], **opts) ⇒ Object
Stdout of executable or raise expcetion.
-
.secure_eval(code, file, line) ⇒ Object
secure execution of Ruby code.
-
.secure_spawn(exec:, args: [], env: []) ⇒ Object
start process in background, or raise exception caller can call Process.wait on returned value.
-
.terminal? ⇒ Boolean
True if we are in a terminal.
-
.write_file_restricted(path, force: false, mode: nil) ⇒ Object
Write content to a file, with restricted access.
Instance Method Summary collapse
-
#initialize ⇒ Environment
constructor
A new instance of Environment.
-
#open_uri(the_url) ⇒ Object
Allows a user to open a Url if method is “text”, then URL is displayed on terminal if method is “graphical”, then the URL will be opened with the default browser.
- #terminal_supports_unicode? ⇒ Boolean
Constructor Details
#initialize ⇒ Environment
Returns a new instance of Environment.
206 207 208 209 |
# File 'lib/aspera/environment.rb', line 206 def initialize @url_method = self.class.default_gui_mode @terminal_supports_unicode = nil end |
Instance Attribute Details
#url_method ⇒ Object
Returns the value of attribute url_method.
204 205 206 |
# File 'lib/aspera/environment.rb', line 204 def url_method @url_method end |
Class Method Details
.architecture ⇒ Object
normalized architecture name see constants: OS_* and CPU_*
70 71 72 |
# File 'lib/aspera/environment.rb', line 70 def architecture return "#{os}-#{cpu}" end |
.cpu ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/aspera/environment.rb', line 53 def cpu case RbConfig::CONFIG['host_cpu'] when /x86_64/, /x64/ return CPU_X86_64 when /powerpc/, /ppc64/ return CPU_PPC64LE if os.eql?(OS_LINUX) return CPU_PPC64 when /s390/ return CPU_S390 when /arm/, /aarch64/ return CPU_ARM64 else Aspera.error_unexpected_value(RbConfig::CONFIG['host_cpu']){'host_cpu'} end end |
.default_gui_mode ⇒ Object
Returns :text or :graphical depending on the environment.
173 174 175 176 177 178 179 |
# File 'lib/aspera/environment.rb', line 173 def default_gui_mode # assume not remotely connected on macos and windows return :graphical if [Environment::OS_WINDOWS, Environment::OS_MACOS].include?(Environment.os) # unix family return :graphical if ENV.key?('DISPLAY') && !ENV['DISPLAY'].empty? return :text end |
.empty_binding ⇒ Object
empty variable binding for secure eval
89 90 91 |
# File 'lib/aspera/environment.rb', line 89 def empty_binding return Kernel.binding end |
.exe_file(name = '') ⇒ Object
executable file extension for current OS
75 76 77 78 |
# File 'lib/aspera/environment.rb', line 75 def exe_file(name='') return "#{name}.exe" if os.eql?(OS_WINDOWS) return name end |
.fix_home ⇒ Object
on Windows, the env var %USERPROFILE% provides the path to user’s home more reliably than %HOMEDRIVE%%HOMEPATH% so, tell Ruby the right way
82 83 84 85 86 |
# File 'lib/aspera/environment.rb', line 82 def fix_home return unless os.eql?(OS_WINDOWS) && ENV.key?('USERPROFILE') && Dir.exist?(ENV.fetch('USERPROFILE', nil)) ENV['HOME'] = ENV.fetch('USERPROFILE', nil) Log.log.debug{"Windows: set HOME to USERPROFILE: #{Dir.home}"} end |
.log_spawn(env:, exec:, args:) ⇒ Object
98 99 100 101 102 103 104 105 |
# File 'lib/aspera/environment.rb', line 98 def log_spawn(env:, exec:, args:) [ 'execute:'.red, env.map{|k, v| "#{k}=#{Shellwords.shellescape(v)}"}, Shellwords.shellescape(exec), args.map{|a|Shellwords.shellescape(a)} ].flatten.join(' ') end |
.open_editor(file_path) ⇒ Object
open a file in an editor
194 195 196 197 198 199 200 201 202 |
# File 'lib/aspera/environment.rb', line 194 def open_editor(file_path) if ENV.key?('EDITOR') system(ENV['EDITOR'], file_path.to_s) elsif Environment.os.eql?(Environment::OS_WINDOWS) system('notepad.exe', %Q{"#{file_path}"}) else open_uri_graphical(file_path.to_s) end end |
.open_uri_graphical(uri) ⇒ Object
open a URI in a graphical browser command must be non blocking
183 184 185 186 187 188 189 190 191 |
# File 'lib/aspera/environment.rb', line 183 def open_uri_graphical(uri) case Environment.os when Environment::OS_MACOS then return system('open', uri.to_s) when Environment::OS_WINDOWS then return system('start', 'explorer', %Q{"#{uri}"}) when Environment::OS_LINUX then return system('xdg-open', uri.to_s) else raise "no graphical open method for #{Environment.os}" end end |
.os ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/aspera/environment.rb', line 39 def os case RbConfig::CONFIG['host_os'] when /mswin/, /msys/, /mingw/, /cygwin/, /bccwin/, /wince/, /emc/ return OS_WINDOWS when /darwin/, /mac os/ return OS_MACOS when /linux/ return OS_LINUX when /aix/ return OS_AIX else Aspera.error_unexpected_value(RbConfig::CONFIG['host_os']){'host_os'} end end |
.restrict_file_access(path, mode: nil) ⇒ Object
restrict access to a file or folder to user only
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/aspera/environment.rb', line 151 def restrict_file_access(path, mode: nil) if mode.nil? # or FileUtils ? if File.file?(path) mode = 0o600 elsif File.directory?(path) mode = 0o700 else Log.log.debug{"No restriction can be set for #{path}"} end end File.chmod(mode, path) unless mode.nil? rescue => e Log.log.warn(e.) end |
.ruby_version ⇒ Object
35 36 37 |
# File 'lib/aspera/environment.rb', line 35 def ruby_version return RbConfig::CONFIG['RUBY_PROGRAM_VERSION'] end |
.secure_capture(exec:, args: [], **opts) ⇒ Object
Returns stdout of executable or raise expcetion.
121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/aspera/environment.rb', line 121 def secure_capture(exec:, args: [], **opts) Aspera.assert_type(exec, String) Aspera.assert_type(args, Array) Aspera.assert_type(opts, Hash) Log.log.debug {log_spawn(env: {}, exec: exec, args: args)} stdout, stderr, status = Open3.capture3(exec, *args, **opts) Log.log.debug{"status=#{status}, stderr=#{stderr}"} Log.log.trace1{"stdout=#{stdout}"} raise "process failed: #{status.exitstatus} : #{stderr}" unless status.success? return stdout end |
.secure_eval(code, file, line) ⇒ Object
secure execution of Ruby code
94 95 96 |
# File 'lib/aspera/environment.rb', line 94 def secure_eval(code, file, line) Kernel.send('lave'.reverse, code, empty_binding, file, line) end |
.secure_spawn(exec:, args: [], env: []) ⇒ Object
start process in background, or raise exception caller can call Process.wait on returned value
109 110 111 112 113 114 115 |
# File 'lib/aspera/environment.rb', line 109 def secure_spawn(exec:, args: [], env: []) Log.log.debug {log_spawn(env: env, exec: exec, args: args)} # start ascp in separate process ascp_pid = Process.spawn(env, [exec, exec], *args, close_others: true) Log.log.debug{"pid: #{ascp_pid}"} return ascp_pid end |
.terminal? ⇒ Boolean
Returns true if we are in a terminal.
168 169 170 |
# File 'lib/aspera/environment.rb', line 168 def terminal? $stdout.tty? end |
.write_file_restricted(path, force: false, mode: nil) ⇒ Object
Write content to a file, with restricted access
138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/aspera/environment.rb', line 138 def write_file_restricted(path, force: false, mode: nil) Aspera.assert(block_given?, exception_class: Aspera::InternalError) if force || !File.exist?(path) # Windows may give error File.unlink(path) rescue nil # content provided by block File.write(path, yield) restrict_file_access(path, mode: mode) end return path end |
Instance Method Details
#open_uri(the_url) ⇒ Object
Allows a user to open a Url if method is “text”, then URL is displayed on terminal if method is “graphical”, then the URL will be opened with the default browser. this is non blocking
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/aspera/environment.rb', line 223 def open_uri(the_url) case @url_method when :graphical self.class.open_uri_graphical(the_url) when :text case the_url.to_s when /^http/ puts "USER ACTION: please enter this url in a browser:\n#{the_url.to_s.red}\n" else puts "USER ACTION: open this:\n#{the_url.to_s.red}\n" end else raise StandardError, "unsupported url open method: #{@url_method}" end end |
#terminal_supports_unicode? ⇒ Boolean
214 215 216 217 |
# File 'lib/aspera/environment.rb', line 214 def terminal_supports_unicode? @terminal_supports_unicode = self.class.terminal? && %w(LC_ALL LC_CTYPE LANG).any?{|var|ENV[var]&.include?('UTF-8')} if @terminal_supports_unicode.nil? return @terminal_supports_unicode end |