class ImageOptim::BinResolver

Handles resolving binaries and checking versions

If there is an environment variable XXX_BIN when resolving xxx, then a symlink to binary will be created in a temporary directory which will be added to PATH

Constants

VENDOR_PATH

Path to vendor at root of image_optim

Attributes

dir[R]

Directory for symlinks to bins if XXX_BIN was used

pack_path[R]

Path to pack from image_optim_pack if used

Public Class Methods

collect_errors(enumerable) { |item| ... } click to toggle source

Collect resolving errors when running block over items of enumerable

# File lib/image_optim/bin_resolver.rb, line 70
def self.collect_errors(enumerable)
  errors = []
  enumerable.each do |item|
    begin
      yield item
    rescue Error => e
      errors << e
    end
  end
  errors
end
new(image_optim) click to toggle source
# File lib/image_optim/bin_resolver.rb, line 21
def initialize(image_optim)
  @image_optim = image_optim
  @bins = {}
  @lock = Mutex.new
  init_pack
end

Public Instance Methods

env_path() click to toggle source

Prepand ‘dir` and append `VENDOR_PATH` to `PATH` from environment

# File lib/image_optim/bin_resolver.rb, line 60
def env_path
  [
    dir,
    pack_path,
    ENV['PATH'],
    VENDOR_PATH,
  ].compact.join(File::PATH_SEPARATOR)
end
resolve!(name) click to toggle source

Binary resolving: create symlink if there is XXX_BIN environment variable, build Bin with full path, check binary version Return Bin instance

# File lib/image_optim/bin_resolver.rb, line 31
def resolve!(name)
  name = name.to_sym

  resolving(name) do
    path = symlink_custom_bin!(name) || full_path(name)
    bin = Bin.new(name, path) if path

    if bin && @image_optim.verbose
      $stderr << "Resolved #{bin}\n"
    end

    @bins[name] = bin

    bin.check! if bin
  end

  if @bins[name]
    @bins[name].check_fail!
  else
    fail BinNotFound, "`#{name}` not found"
  end

  @bins[name]
end

Private Instance Methods

full_path(name) click to toggle source

Return full path to bin or null based on stackoverflow.com/a/5471032/96823

# File lib/image_optim/bin_resolver.rb, line 132
def full_path(name)
  # PATHEXT is needed only for windows
  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
  env_path.split(File::PATH_SEPARATOR).each do |dir|
    exts.each do |ext|
      path = File.expand_path("#{name}#{ext}", dir)
      return path if File.file?(path) && File.executable?(path)
    end
  end
  nil
end
init_pack() click to toggle source
# File lib/image_optim/bin_resolver.rb, line 84
def init_pack
  return unless @image_optim.pack

  @pack_path = if @image_optim.verbose
    Pack.path do |message|
      $stderr << "#{message}\n"
    end
  else
    Pack.path
  end
  return if @pack_path

  warn 'No pack for this OS and/or ARCH, check verbose output'
end
resolving(name) { || ... } click to toggle source

Double-checked locking

# File lib/image_optim/bin_resolver.rb, line 100
def resolving(name)
  return if @bins.include?(name)
  @lock.synchronize do
    yield unless @bins.include?(name)
  end
end