# encoding: utf-8 require 'fedux_org_stdlib/require_files' require_library %w(pathname active_support/core_ext/object/blank) module FeduxOrgStdlib module Command # Find path to executable module Which # 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 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 end end end