module Omnibus::Util

Constants

SHELLOUT_OPTIONS

The default shellout options.

@return [Hash]

Public Class Methods

included(base) click to toggle source
# File lib/omnibus/util.rb, line 21
def self.included(base)
  # This module requires logging is also available
  base.send(:include, Logging)
end

Public Instance Methods

compiler_safe_path(*pieces) click to toggle source

Convert the given path to be appropriate for usage with the given compiler

@param [String, Array<String>] pieces

the pieces of the path to join and fix

@return [String]

the path with applied changes
# File lib/omnibus/util.rb, line 198
def compiler_safe_path(*pieces)
  path = File.join(*pieces)
  path = path.sub(%r{^([A-Za-z]):/}, "/\\1/") if ENV["MSYSTEM"]
  path
end
copy_file(source, destination) click to toggle source

Copy the source file to the destination.

@param [String] source @param [String] destination

@return [String]

the destination path
# File lib/omnibus/util.rb, line 245
def copy_file(source, destination)
  log.debug(log_key) { "Copying `#{source}' to `#{destination}'" }
  FileUtils.cp(source, destination)
  destination
end
create_directory(*paths) click to toggle source

Create a directory at the given path.

@param [String, Array<String>] paths

the path or list of paths to join to create

@return [String]

the path to the created directory
# File lib/omnibus/util.rb, line 213
def create_directory(*paths)
  path = File.join(*paths)
  log.debug(log_key) { "Creating directory `#{path}'" }
  FileUtils.mkdir_p(path)
  path
end
create_file(*paths) { || ... } click to toggle source

Create a file at the given path. If a block is given, the contents of the block are written to the file. If the block is not given, the file is simply “touched”.

@param [String, Array<String>] paths

the path or list of paths to join to create

@return [String]

the path to the created file
# File lib/omnibus/util.rb, line 278
def create_file(*paths, &block)
  path = File.join(*paths)
  log.debug(log_key) { "Creating file `#{path}'" }

  FileUtils.mkdir_p(File.dirname(path))

  if block
    File.open(path, "wb") { |f| f.write(yield) }
  else
    FileUtils.touch(path)
  end

  path
end
path_key() click to toggle source

The proper platform-specific “$PATH” key.

@return [String]

# File lib/omnibus/util.rb, line 42
def path_key
  # The ruby devkit needs ENV['Path'] set instead of ENV['PATH'] because
  # $WINDOWSRAGE, and if you don't set that your native gem compiles
  # will fail because the magic fixup it does to add the mingw compiler
  # stuff won't work.
  #
  # Turns out there is other build environments that only set ENV['PATH'] and if we
  # modify ENV['Path'] then it ignores that.  So, we scan ENV and returns the first
  # one that we find.
  #
  if windows?
    result = ENV.keys.grep(/\Apath\Z/i)
    case result.length
    when 0
      raise "The current omnibus environment has no PATH"
    when 1
      result.first
    else
      raise "The current omnibus environment has multiple PATH/Path variables."
    end
  else
    "PATH"
  end
end
remove_directory(*paths) click to toggle source

Remove the directory at the given path.

@param [String, Array<String>] paths

the path or list of paths to join to delete

@return [String]

the path to the removed directory
# File lib/omnibus/util.rb, line 229
def remove_directory(*paths)
  path = File.join(*paths)
  log.debug(log_key) { "Remove directory `#{path}'" }
  FileUtils.rm_rf(path)
  path
end
remove_file(*paths) click to toggle source

Remove the file at the given path.

@param [String, Array<String>] paths

the path or list of paths to join to delete

@return [String]

the path to the removed file
# File lib/omnibus/util.rb, line 260
def remove_file(*paths)
  path = File.join(*paths)
  log.debug(log_key) { "Removing file `#{path}'" }
  FileUtils.rm_f(path)
  path
end
retry_block(logstr, retried_exceptions = [], retries = Omnibus::Config.fetcher_retries) { || ... } click to toggle source

Retry the given block if a retriable exception is raised. Returns the value of the block call if successful.

@param [String] logstr

Description of the action being retried. Used in log output.

@param [Array<Exception>] retried_exceptions

List of exceptions to retry.  Any other exceptions are raisesd.

@param [Integer] retries

Number of times to retry the given block.
# File lib/omnibus/util.rb, line 157
def retry_block(logstr, retried_exceptions = [], retries = Omnibus::Config.fetcher_retries, &block)
  yield
rescue Exception => e
  raise e unless retried_exceptions.any? { |eclass| e.is_a?(eclass) }

  if retries != 0
    log.info(log_key) { "Retrying failed #{logstr} due to #{e} (#{retries} retries left)..." }
    retries -= 1
    retry
  else
    log.error(log_key) { "#{logstr} failed - #{e.class}!" }
    raise
  end
end
shellout(*args) click to toggle source

Shells out and runs command.

@overload shellout(command, options = {})

@param command [String]
@param options [Hash] the options passed to the initializer of the
  +Mixlib::ShellOut+ instance.

@overload shellout(command_fragments, options = {})

@param command [Array<String>] command argv as individual strings
@param options [Hash] the options passed to the initializer of the
  +Mixlib::ShellOut+ instance.

@return [Mixlib::ShellOut] the underlying Mixlib::ShellOut instance

which has +stdout+, +stderr+, +status+, and +exitstatus+
populated with results of the command.
# File lib/omnibus/util.rb, line 82
def shellout(*args)
  options = args.last.is_a?(Hash) ? args.pop : {}
  options = SHELLOUT_OPTIONS.merge(options)

  command_string = args.join(" ")
  in_msys = options.delete(:in_msys_bash) && ENV["MSYSTEM"]
  # Mixlib will handle escaping characters for cmd but our command might
  # contain '. For now, assume that won't happen because I don't know
  # whether this command is going to be played via cmd or through
  # ProcessCreate.
  command_string = "bash -c \'#{command_string}\'" if in_msys

  # Grab the log_level
  log_level = options.delete(:log_level)

  # Set the live stream if one was not given
  options[:live_stream] ||= log.live_stream(:internal)

  # Since Mixlib::ShellOut supports :environment and :env, we want to
  # standardize here
  if options[:env]
    options[:environment] = options.fetch(:environment, {}).merge(options[:env])
  end

  # Log any environment options given
  unless options[:environment].empty?
    log.public_send(log_level, log_key) { "Environment:" }
    options[:environment].sort.each do |key, value|
      log.public_send(log_level, log_key) { "  #{key}=#{value.inspect}" }
    end
  end

  # Log the actual command
  log.public_send(log_level, log_key) { "$ #{command_string}" }

  cmd = Mixlib::ShellOut.new(command_string, options)
  cmd.environment["HOME"] = "/tmp" unless ENV["HOME"]
  cmd.run_command
  cmd
end
shellout!(*args) click to toggle source

Similar to shellout method except it raises an exception if the command fails.

@see shellout

@raise [CommandFailed]

if +exitstatus+ is not in the list of +valid_exit_codes+

@raise [CommandTimeout]

if execution time exceeds +timeout+
# File lib/omnibus/util.rb, line 134
def shellout!(*args)
  cmd = shellout(*args)
  cmd.error!
  cmd
rescue Mixlib::ShellOut::ShellCommandFailed
  raise CommandFailed.new(cmd)
rescue Mixlib::ShellOut::CommandTimeout
  raise CommandTimeout.new(cmd)
end
windows_safe_path(*pieces) click to toggle source

Convert the given path to be appropiate for shelling out on Windows.

@param [String, Array<String>] pieces

the pieces of the path to join and fix

@return [String]

the path with applied changes
# File lib/omnibus/util.rb, line 180
def windows_safe_path(*pieces)
  path = File.join(*pieces)

  if File::ALT_SEPARATOR
    path.gsub(File::SEPARATOR, File::ALT_SEPARATOR)
  else
    path
  end
end