module ChefUtils::DSL::Which
Public Instance Methods
Lookup all the instances of an an executable that can be found through the systems search PATH. Allows specifying an array of executables to look for. All the instances of the first executable that is found will be returned first. The extra_path will override any default extra_paths which are added (allowing the user to pass an empty array to remove them).
When passed a block the block will be called with the full pathname of any executables which are found, and the block should return truthy or falsey values to further filter the executable based on arbitrary criteria.
This helper can be used in target mode in chef or with train using the appropriate wiring externally.
@example Find all the python executables, searching through the system PATH plus additionally
the "/usr/libexec" directory, which have the dnf libraries installed and available. cmds = where("platform-python", "python", "python3", "python2", "python2.7", extra_path: "/usr/libexec") do |f| shell_out("#{f} -c 'import dnf'").exitstatus == 0 end
@param [Array<String>] list of commands to search for @param [String,Array<String>] array of extra paths to search through @return [String] the first match
# File lib/chef-utils/dsl/which.rb, line 79 def where(*cmds, extra_path: nil, &block) extra_path ||= __extra_path paths = __env_path.split(File::PATH_SEPARATOR) + Array(extra_path) paths.uniq! exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [] exts.unshift("") cmds.map do |cmd| paths.map do |path| exts.map do |ext| filename = File.join(path, "#{cmd}#{ext}") filename if __valid_executable?(filename, &block) end.compact end end.flatten end
Lookup an executable through the systems search PATH. Allows specifying an array of executables to look for. The first executable that is found, along any path entry, will be the preferred one and returned first. The extra_path will override any default extra_paths which are added (allowing the user to pass an empty array to remove them).
When passed a block the block will be called with the full pathname of any executables which are found, and the block should return truthy or falsey values to further filter the executable based on arbitrary criteria.
This is syntactic sugar for `where(…).first`
This helper can be used in target mode in chef or with train using the appropriate wiring externally.
@example Find the most appropriate python executable, searching through the system PATH
plus additionally the "/usr/libexec" directory, which has the dnf libraries installed and available. cmd = which("platform-python", "python", "python3", "python2", "python2.7", extra_path: "/usr/libexec") do |f| shell_out("#{f} -c 'import dnf'").exitstatus == 0 end
@param [Array<String>] list of commands to search for @param [String,Array<String>] array of extra paths to search through @return [String] the first match
# File lib/chef-utils/dsl/which.rb, line 52 def which(*cmds, extra_path: nil, &block) where(*cmds, extra_path: extra_path, &block).first || false end
Private Instance Methods
This is for injecting common extra_paths into the search PATH. The chef-client codebase overrides this into its own custom mixin to ensure that /usr/sbin, /sbin, etc are in the search PATH for chef-client.
@api private
# File lib/chef-utils/dsl/which.rb, line 101 def __extra_path nil end
Windows
compatible and train/target-mode-enhanced helper to determine if an executable is valid.
@api private
# File lib/chef-utils/dsl/which.rb, line 108 def __valid_executable?(filename, &block) is_executable = if __transport_connection __transport_connection.file(filename).stat[:mode] & 1 && !__transport_connection.file(filename).directory? else File.executable?(filename) && !File.directory?(filename) end return false unless is_executable block ? yield(filename) : true end