Module: TTY::Which

Defined in:
lib/tty/which.rb,
lib/tty/which/version.rb

Overview

A class responsible for finding an executable in the PATH

Constant Summary collapse

VERSION =
"0.4.2"

Class Method Summary collapse

Class Method Details

.executable_file?(filename, dir = nil) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Determines if filename is an executable file

Examples:

Basic usage

executable_file?('/usr/bin/less') # => true

Executable in directory

executable_file?('less', '/usr/bin') # => true
executable_file?('less', '/usr') # => false

Parameters:

  • filename (String)

    the path to file

  • dir (String) (defaults to: nil)

    the directory within which to search for filename

Returns:

  • (Boolean)

126
127
128
129
130
# File 'lib/tty/which.rb', line 126

def executable_file?(filename, dir = nil)
  path = ::File.join(dir, filename) if dir
  path ||= filename
  ::File.file?(path) && ::File.executable?(path)
end

.exist?(cmd, paths: search_paths) ⇒ Boolean

Check if executable exists in the path

Parameters:

  • command (String)

    the executable to check

  • paths (String) (defaults to: search_paths)

    paths to check

Returns:

  • (Boolean)

62
63
64
# File 'lib/tty/which.rb', line 62

def exist?(cmd, paths: search_paths)
  !which(cmd, paths: paths).nil?
end

.extensions(path_ext = ENV['PATHEXT']) ⇒ Array[String]

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

All possible file extensions

Examples:

extensions('.exe;cmd;.bat')
# => ['.exe','.bat']

Parameters:

  • path_ext (String) (defaults to: ENV['PATHEXT'])

    a string of semicolon separated filename extensions

Returns:

  • (Array[String])

    an array with valid file extensions


103
104
105
106
# File 'lib/tty/which.rb', line 103

def extensions(path_ext = ENV['PATHEXT'])
  return [''] unless path_ext
  path_ext.split(::File::PATH_SEPARATOR).select { |part| part.include?('.') }
end

.file_with_exec_ext?(filename) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if command itself has executable extension

Examples:

file_with_exec_ext?("file.bat")
# => true

Parameters:

  • filename (String)

    the path to executable file

Returns:

  • (Boolean)

145
146
147
148
149
# File 'lib/tty/which.rb', line 145

def file_with_exec_ext?(filename)
  extension = ::File.extname(filename)
  return false if extension.empty?
  extensions.any? { |ext| extension.casecmp(ext).zero? }
end

.file_with_path?(cmd) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if executable file is part of absolute/relative path

Parameters:

  • cmd (String)

    the executable to check

Returns:

  • (Boolean)

160
161
162
# File 'lib/tty/which.rb', line 160

def file_with_path?(cmd)
  ::File.expand_path(cmd) == cmd
end

.search_paths(path = ENV['PATH']) ⇒ Array[String]

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Find default system paths

Examples:

search_paths("/usr/local/bin:/bin")
# => ['/bin']

Parameters:

  • path (String) (defaults to: ENV['PATH'])

    the path to search through

Returns:

  • (Array[String])

    the array of paths to search


80
81
82
83
84
85
86
87
# File 'lib/tty/which.rb', line 80

def search_paths(path = ENV['PATH'])
  paths = if path && !path.empty?
            path.split(::File::PATH_SEPARATOR)
          else
            %w(/usr/local/bin /usr/ucb /usr/bin /bin)
          end
  paths.select(&Dir.method(:exist?))
end

.which(cmd, paths: search_paths) ⇒ String?

Find an executable in a platform independent way

Examples:

which('ruby')                 # => '/usr/local/bin/ruby'
which('/usr/local/bin/ruby')  # => '/usr/local/bin/ruby'
which('foo')                  # => nil
which('ruby', paths: ['/usr/locale/bin', '/usr/bin', '/bin'])

Parameters:

  • command (String)

    the command to search for

  • paths (Array[String]) (defaults to: search_paths)

    the paths to look through

Returns:

  • (String, nil)

    the absolute path to executable if found, `nil` otherwise


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/tty/which.rb', line 27

def which(cmd, paths: search_paths)
  if file_with_path?(cmd)
    return cmd if executable_file?(cmd)
    extensions.each do |ext|
      exe = ::File.join(cmd, ext)
      return ::File.absolute_path(exe) if executable_file?(exe)
    end
    return nil
  end

  paths.each do |path|
    if file_with_exec_ext?(cmd)
      exe = ::File.join(path, cmd)
      return ::File.absolute_path(exe) if executable_file?(exe)
    end
    extensions.each do |ext|
      exe = ::File.join(path, "#{cmd}#{ext}")
      return ::File.absolute_path(exe) if executable_file?(exe)
    end
  end
  nil
end