Module: Kuby::Utils::Which

Extended by:
Which
Included in:
Which
Defined in:
lib/kuby/utils/which.rb

Overview

This code was copied from the ptools gem, licensed under the Artistic v2 license: github.com/djberg96/ptools/blob/4ef26adc870cf02b8342df58da53c61bcd4af6c4/lib/ptools.rb

Only the #which function and dependent constants have been copied. None of the copied code has been modified.

Constant Summary collapse

MSWINDOWS =
false
WIN32EXTS =
'.{exe,com,bat}'.freeze

Instance Method Summary collapse

Instance Method Details

#which(program, path = ENV['PATH']) ⇒ Object

Raises:

  • (ArgumentError)


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/kuby/utils/which.rb', line 21

def which(program, path = ENV['PATH'])
  raise ArgumentError, 'path cannot be empty' if path.nil? || path.empty?

  # Bail out early if an absolute path is provided.
  if program =~ /^\/|^[a-z]:[\\\/]/i
    program += WIN32EXTS if MSWINDOWS && File.extname(program).empty?
    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::ALT_SEPARATOR, File::SEPARATOR)
      file += WIN32EXTS if File.extname(program).empty?
    end

    found = Dir[file].first

    # Convert all forward slashes to backslashes if supported
    if found && File.executable?(found) && !File.directory?(found)
      found.tr!(File::SEPARATOR, File::ALT_SEPARATOR) if File::ALT_SEPARATOR
      return found
    end
  end

  nil
end