class Omnitest::Psychic::FileFinder

Attributes

ignored_patterns[R]
search_path[R]

Public Class Methods

new(search_path, ignored_patterns) click to toggle source
# File lib/omnitest/psychic/file_finder.rb, line 6
def initialize(search_path, ignored_patterns)
  @search_path = search_path
  @ignored_patterns = ignored_patterns || read_gitignore(search_path)
end

Private Class Methods

find_file_by_alias(file_alias, search_path, ignored_patterns = nil, &block) click to toggle source
# File lib/omnitest/psychic/file_finder.rb, line 64
def self.find_file_by_alias(file_alias, search_path, ignored_patterns = nil, &block)
  FileFinder.new(search_path, ignored_patterns).find_file(file_alias, &block)
end

Public Instance Methods

find_file(name) { |files| ... } click to toggle source

Finds a file by loosely matching the file name to a scenario name

# File lib/omnitest/psychic/file_finder.rb, line 12
def find_file(name)
  return name if File.exist? File.expand_path(name, search_path)

  # Filter out ignored files
  files = potential_files(name).select do |f|
    !ignored?(f)
  end

  if block_given?
    file = yield files
  else
    # Select the shortest path, likely the best match
    file = files.min_by(&:length)
  end

  fail Errno::ENOENT, "No file was found for #{name} within #{search_path}" if file.nil?
  Omnitest::Core::FileSystem.relativize(file, search_path)
end
potential_files(name) click to toggle source
# File lib/omnitest/psychic/file_finder.rb, line 31
def potential_files(name)
  slugified_name = Omnitest::Core::FileSystem.slugify(name)
  glob_string = "#{search_path}/**/*#{slugified_name}*.*"
  potential_files = Dir.glob(glob_string, File::FNM_CASEFOLD)
  potential_files.concat Dir.glob(glob_string.gsub('_', '-'), File::FNM_CASEFOLD)
  potential_files.concat Dir.glob(glob_string.gsub('_', ''), File::FNM_CASEFOLD)
end

Private Instance Methods

ignored?(target_file) click to toggle source

@api private

# File lib/omnitest/psychic/file_finder.rb, line 50
def ignored?(target_file)
  # Trying to match the git ignore rules but there's some discrepencies.
  ignored_patterns.split.find do |pattern|
    # if git ignores a folder, we should ignore all files it contains
    pattern = "#{pattern}**" if pattern[-1] == '/'
    started_with_slash = pattern.start_with? '/'

    pattern.gsub!(%r{\A/}, '') # remove leading slashes since we're searching from root
    file = Omnitest::Core::FileSystem.relativize(target_file, search_path)
    ignored = file.fnmatch? pattern
    ignored || (file.fnmatch? "**/#{pattern}" unless started_with_slash)
  end
end
read_gitignore(dir) click to toggle source

@api private

# File lib/omnitest/psychic/file_finder.rb, line 42
def read_gitignore(dir)
  gitignore_file = "#{dir}/.gitignore"
  File.read(gitignore_file)
rescue
  ''
end