Class: Fig::OperatingSystem
- Inherits:
-
Object
- Object
- Fig::OperatingSystem
- Defined in:
- lib/fig/operating_system.rb
Overview
Does things requiring real O/S interaction, primarilly taking care of file transfers and running external commands.
Constant Summary collapse
- WINDOWS_FILE_NAME_ILLEGAL_CHARACTERS =
%w[ \\ / : * ? " < > | ]- UNIX_FILE_NAME_ILLEGAL_CHARACTERS =
%w[ / ]
Class Method Summary collapse
- .file_name_illegal_characters ⇒ Object
- .get_environment_variables(initial_values = nil) ⇒ Object
- .macos? ⇒ Boolean
- .unix? ⇒ Boolean
- .windows? ⇒ Boolean
- .wrap_variable_name_with_shell_expansion(variable_name) ⇒ Object
Instance Method Summary collapse
- #copy(source, target, msg = nil) ⇒ Object
-
#create_archive(archive_name, paths_to_archive) ⇒ Object
Expects paths_to_archive as an Array of paths.
- #delete_and_recreate_directory(dir) ⇒ Object
-
#download(url, path, prompt_for_login) ⇒ Object
Returns whether the file was not downloaded because the file already exists and is already up-to-date.
- #download_and_unpack_archive(url, download_directory, unpack_directory) ⇒ Object
- #download_list(url) ⇒ Object
-
#download_resource(url, download_directory) ⇒ Object
Returns the basename and full path to the download.
-
#initialize(login) ⇒ OperatingSystem
constructor
A new instance of OperatingSystem.
- #list(dir) ⇒ Object
- #move_file(directory, from, to) ⇒ Object
-
#path_up_to_date?(url, path, prompt_for_login) ⇒ Boolean
Determine whether we need to update something.
- #plain_exec(command) ⇒ Object
-
#plain_or_shell_exec(command) ⇒ Object
sigh Apparently Ruby < v1.9.3 does some wacko thing with single argument exec that causes it to not invoke the shell, so we’ve got this mess.
- #shell_exec(command) ⇒ Object
-
#unpack_archive(directory, archive_path) ⇒ Object
This method can handle the following archive types: .tar.bz2 .tar.gz .tgz .zip.
- #upload(local_file, remote_file) ⇒ Object
- #write(path, content) ⇒ Object
Constructor Details
#initialize(login) ⇒ OperatingSystem
Returns a new instance of OperatingSystem.
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/fig/operating_system.rb', line 83 def initialize(login) @protocols = {} @protocols['file'] = Fig::Protocol::File.new @protocols['ftp'] = Fig::Protocol::FTP.new login @protocols['http'] = Fig::Protocol::HTTP.new @protocols['https'] = Fig::Protocol::HTTP.new @protocols['sftp'] = Fig::Protocol::SFTP.new @protocols['ssh'] = Fig::Protocol::SSH.new @protocols['art'] = @protocols['artifactory'] = Fig::Protocol::Artifactory.new end |
Class Method Details
.file_name_illegal_characters ⇒ Object
58 59 60 61 62 63 64 |
# File 'lib/fig/operating_system.rb', line 58 def file_name_illegal_characters() if windows? return WINDOWS_FILE_NAME_ILLEGAL_CHARACTERS end return UNIX_FILE_NAME_ILLEGAL_CHARACTERS end |
.get_environment_variables(initial_values = nil) ⇒ Object
74 75 76 77 78 79 80 |
# File 'lib/fig/operating_system.rb', line 74 def get_environment_variables(initial_values = nil) if windows? return Fig::EnvironmentVariables::CaseInsensitive.new(initial_values) end return Fig::EnvironmentVariables::CaseSensitive.new(initial_values) end |
.macos? ⇒ Boolean
46 47 48 49 50 51 52 |
# File 'lib/fig/operating_system.rb', line 46 def macos? return @is_macos if not @is_macos.nil? @is_macos = !! (RbConfig::CONFIG['host_os'] =~ /^darwin/) return @is_macos end |
.unix? ⇒ Boolean
54 55 56 |
# File 'lib/fig/operating_system.rb', line 54 def unix? ! Fig::.windows? end |
.windows? ⇒ Boolean
38 39 40 41 42 43 44 |
# File 'lib/fig/operating_system.rb', line 38 def windows? return @is_windows if not @is_windows.nil? @is_windows = !! (RbConfig::CONFIG['host_os'] =~ /mswin|mingw/) return @is_windows end |
.wrap_variable_name_with_shell_expansion(variable_name) ⇒ Object
66 67 68 69 70 71 72 |
# File 'lib/fig/operating_system.rb', line 66 def wrap_variable_name_with_shell_expansion(variable_name) if Fig::.windows? return "%#{variable_name}%" else return "$#{variable_name}" end end |
Instance Method Details
#copy(source, target, msg = nil) ⇒ Object
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/fig/operating_system.rb', line 195 def copy(source, target, msg = nil) if File.directory?(source) FileUtils.mkdir_p(target) Dir.foreach(source) do |child| if child != '.' and child != '..' copy(File.join(source, child), File.join(target, child), msg) end end else if ( ! File.exist?(target) \ || File.mtime(source) != File.mtime(target) \ || File.size(source) != File.size(target) ) Fig::Logging.info "#{msg} #{target}" if msg FileUtils.mkdir_p(File.dirname(target)) FileUtils.cp(source, target) File.utime(File.atime(source), File.mtime(source), target) end end end |
#create_archive(archive_name, paths_to_archive) ⇒ Object
Expects paths_to_archive as an Array of paths.
222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/fig/operating_system.rb', line 222 def create_archive(archive_name, paths_to_archive) existing_files = Set.new # TODO: Need to verify files_to_archive exists. Zlib::GzipWriter.open(archive_name) do |gz| Gem::Package::TarWriter.new(gz) do |writer| paths_to_archive.each do |path| add_path_to_archive(path, existing_files, writer) end end end end |
#delete_and_recreate_directory(dir) ⇒ Object
190 191 192 193 |
# File 'lib/fig/operating_system.rb', line 190 def delete_and_recreate_directory(dir) FileUtils.rm_rf(dir) FileUtils.mkdir_p(dir) end |
#download(url, path, prompt_for_login) ⇒ Object
Returns whether the file was not downloaded because the file already exists and is already up-to-date.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/fig/operating_system.rb', line 131 def download(url, path, prompt_for_login) Fig::VerboseLogging.time_operation("downloading #{File.basename(url)}") do protocol, uri = decode_protocol url FileUtils.mkdir_p(File.dirname path) result = protocol.download uri, path, prompt_for_login if File.exist?(path) size = File.size(path) log_asset_operation("downloaded", path, size) end result end end |
#download_and_unpack_archive(url, download_directory, unpack_directory) ⇒ Object
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/fig/operating_system.rb', line 159 def download_and_unpack_archive(url, download_directory, unpack_directory) log_asset_operation("downloading", url) basename, path = download_resource(url, download_directory) case path when /\.tar\.gz$/ unpack_archive(unpack_directory, path) when /\.tgz$/ unpack_archive(unpack_directory, path) when /\.tar\.bz2$/ unpack_archive(unpack_directory, path) when /\.zip$/ unpack_archive(unpack_directory, path) else Fig::Logging.fatal "Unknown archive type: #{basename}" raise Fig::NetworkError.new("Unknown archive type: #{basename}") end return end |
#download_list(url) ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/fig/operating_system.rb', line 102 def download_list(url) Fig::VerboseLogging.time_operation("listing packages from #{url}") do begin protocol, uri = decode_protocol url result = protocol.download_list uri log_repository_operation("listed", url, "#{result.size} entries") result rescue SocketError => error Fig::Logging.debug error. raise Fig::NetworkError.new "#{url}: #{error.message}" rescue Errno::ETIMEDOUT => error Fig::Logging.debug error. raise Fig::NetworkError.new "#{url}: #{error.message}" end end end |
#download_resource(url, download_directory) ⇒ Object
Returns the basename and full path to the download.
147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/fig/operating_system.rb', line 147 def download_resource(url, download_directory) log_asset_operation("downloading", url) FileUtils.mkdir_p(download_directory) basename = CGI.unescape Fig::URL.parse(url).path.split('/').last path = File.join(download_directory, basename) download(url, path, false) return basename, path end |
#list(dir) ⇒ Object
94 95 96 |
# File 'lib/fig/operating_system.rb', line 94 def list(dir) Dir.entries(dir) - ['.', '..'] end |
#move_file(directory, from, to) ⇒ Object
217 218 219 |
# File 'lib/fig/operating_system.rb', line 217 def move_file(directory, from, to) Dir.chdir(directory) { FileUtils.mv(from, to, :force => true) } end |
#path_up_to_date?(url, path, prompt_for_login) ⇒ Boolean
Determine whether we need to update something. Returns nil to indicate “don’t know”.
122 123 124 125 126 127 |
# File 'lib/fig/operating_system.rb', line 122 def path_up_to_date?(url, path, prompt_for_login) return false if ! File.exist? path protocol, uri = decode_protocol url return protocol.path_up_to_date? uri, path, prompt_for_login end |
#plain_exec(command) ⇒ Object
286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/fig/operating_system.rb', line 286 def plain_exec(command) # Kernel#exec won't run Kernel#at_exit handlers. Fig::AtExit.execute() if ENV['FIG_COVERAGE'] SimpleCov.at_exit.call end begin Kernel.exec(*command) rescue SystemCallError => exception raise Fig::UserInputError.new exception end end |
#plain_or_shell_exec(command) ⇒ Object
sigh Apparently Ruby < v1.9.3 does some wacko thing with single argument exec that causes it to not invoke the shell, so we’ve got this mess.
302 303 304 305 306 307 308 |
# File 'lib/fig/operating_system.rb', line 302 def plain_or_shell_exec(command) if command.size > 1 plain_exec(command) else shell_exec(command[0]) end end |
#shell_exec(command) ⇒ Object
278 279 280 281 282 283 284 |
# File 'lib/fig/operating_system.rb', line 278 def shell_exec(command) if Fig::.windows? plain_exec [ ENV['ComSpec'], '/c', command ] else plain_exec [ ENV['SHELL'] || '/bin/sh', '-c', command ] end end |
#unpack_archive(directory, archive_path) ⇒ Object
This method can handle the following archive types: .tar.bz2 .tar.gz .tgz .zip
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/fig/operating_system.rb', line 240 def unpack_archive(directory, archive_path) Fig::VerboseLogging.time_operation("extracting archive #{File.basename(archive_path)}") do FileUtils.mkdir_p directory archive_size = File.size(archive_path) if File.exist?(archive_path) log_asset_operation("extracting", archive_path, archive_size) Dir.chdir(directory) do if ! File.exist? archive_path raise Fig::RepositoryError.new "#{archive_path} does not exist." end running_on_windows = Fig::.windows? ::Archive.read_open_filename(archive_path) do |reader| while entry = reader.next_header if running_on_windows check_archive_entry_for_windows entry, archive_path end begin reader.extract(entry) rescue Archive::Error => exception # Nice how the error message doesn't include any information about # what was having the problem. = exception..sub(/^Extract archive failed: /, '') new_exception = Fig::RepositoryError.new( "Could not extract #{entry.pathname} from #{archive_path}: #{message}" ) new_exception.set_backtrace exception.backtrace raise new_exception end end end end end end |
#upload(local_file, remote_file) ⇒ Object
180 181 182 183 184 185 186 187 188 |
# File 'lib/fig/operating_system.rb', line 180 def upload(local_file, remote_file) Fig::Logging.debug "Uploading #{local_file} to #{remote_file}." protocol, uri = decode_protocol remote_file protocol.upload local_file, uri return end |
#write(path, content) ⇒ Object
98 99 100 |
# File 'lib/fig/operating_system.rb', line 98 def write(path, content) File.open(path, 'wb') { |f| f.binmode; f << content } end |