class File

File class

Constants

MSWINDOWS
WIN32EXTS

Public Class Methods

which(program, path = ENV['PATH']) click to toggle source

Search program in search path

@param [String] program

The program to look for

@param [String] path

The search path

@return [String, NilClass]

If the program could be found in search path, the full path will be
returned otherwise `#which` returns nil.
# File lib/fedux_org_stdlib/core_ext/file/which.rb, line 33
def which(program, path = ENV['PATH'])
  fail ArgumentError, path if path.blank?

  return nil if program.blank?

  # Bail out early if an absolute path is provided.
  if program =~ %r{^/|^[a-z]:[/]}i
    program += WIN32EXTS if MSWINDOWS && File.extname(program).blank?
    found = Dir[program].first
    if found && File.executable?(found) && !File.directory?(found)
      return found
    else
      return nil
    end
  end

  # Iterate over each path glob the dir + program.
  path.split(File::PATH_SEPARATOR).each do |dir|
    dir = File.expand_path(dir)

    next unless File.exist?(dir) # In case of bogus second argument
    file = File.join(dir, program)

    # Dir[] doesn't handle backslashes properly, so convert them. Also, if
    # the program name doesn't have an extension, try them all.
    if MSWINDOWS
      file = file.tr('\\', '/')
      file += WIN32EXTS if File.extname(program).blank?
    end

    found = Dir[file].first

    next if !found || !File.executable?(found) || File.directory?(found)

    # Convert all forward slashes to backslashes if supported
    found.tr!(File::SEPARATOR, File::ALT_SEPARATOR) if File::ALT_SEPARATOR

    return found
  end

  nil
end