module FeduxOrgStdlib::Command::Which

Find path to executable

Public Instance Methods

which(cmd, options = {}) click to toggle source

Search for command @param [String] cmd

name of command or path to command (will be reduced to basename and then searched in PATH)

@param [Array,String] paths

a string containing paths separated by "File::PATH_SEPARATOR" or an array of paths

@param [Array,String] pathexts

a string containing pathexts separated by ";" or an array of pathexts

@return [String]

path to command
# File lib/fedux_org_stdlib/command/which.rb, line 21
def which(cmd, options = {})
  options = {
    paths:                         ENV['PATH'].split(File::PATH_SEPARATOR),
    pathexts:                      ENV['PATHEXT'].to_s.split(/;/),
    raise_error_on_not_executable: false,
    raise_error_on_not_found:      false
  }.merge options

  cmd = Pathname.new(cmd)

  paths                         = options[:paths]
  pathexts                      = options[:pathexts]
  raise_error_on_not_executable = options[:raise_error_on_not_executable]
  raise_error_on_not_found      = options[:raise_error_on_not_found]

  fail Exceptions::CommandNotFound if cmd.to_s.empty?
  return nil if cmd.to_s.empty?

  if cmd.absolute?
    return cmd.to_s if cmd.executable?
    fail Exceptions::CommandNotFound if raise_error_on_not_found && !cmd.exist?
    fail Exceptions::CommandNotExecutable if raise_error_on_not_executable && !cmd.executable?
    return nil
  end

  pathexts = [''] if pathexts.blank?

  Array(paths).each do |path|
    Array(pathexts).each do |ext|
      file = Pathname.new(File.join(path, "#{cmd}#{ext}"))
      return file.to_s if file.executable?
      fail Exceptions::CommandNotExecutable if raise_error_on_not_executable && !cmd.executable?
    end
  end
  fail Exceptions::CommandNotFound if raise_error_on_not_found
  nil
end