class Epuber::Compiler::FileFinders::Abstract

Attributes

ignored_patterns[RW]

@return [Array<String>]

source_path[R]

@return [String] path where should look for source files

Public Class Methods

group_filter_paths(paths, groups) click to toggle source

@param [Array<String>] paths list of file paths @param [Array<Symbol>] groups list of groups to filter file paths

@return [Array<String>] filtered list of file paths

# File lib/epuber/compiler/file_finders/abstract.rb, line 178
def self.group_filter_paths(paths, groups)
  # filter depend on group
  groups = Array(groups)

  if groups.empty?
    paths
  else
    valid_extensions = groups.map do |group|
      GROUP_EXTENSIONS.fetch(group) { raise ::StandardError, "Unknown file group #{group.inspect}" }
    end.flatten

    paths.select do |file_path|
      valid_extensions.include?(::File.extname(file_path))
    end
  end
end
new(source_path) click to toggle source

@param [String] source_path

# File lib/epuber/compiler/file_finders/abstract.rb, line 96
def initialize(source_path)
  @source_path = source_path.unicode_normalize.freeze
  @source_path_abs = ::File.expand_path(@source_path).unicode_normalize.freeze
  @ignored_patterns = []
end
relative_paths_from(paths, context_path) click to toggle source

@param [Array<String>] paths list of file paths @param [String] context_path

@return [Array<String>] mapped list of file paths

# File lib/epuber/compiler/file_finders/abstract.rb, line 200
def self.relative_paths_from(paths, context_path)
  context_pathname = Pathname.new(context_path)
  paths.map do |path|
    Pathname(path.unicode_normalize).relative_path_from(context_pathname).to_s
  end
end

Public Instance Methods

assert_one_file(files, pattern: nil, groups: nil, context_path: nil) click to toggle source

@param [Array<Symbol> | Symbol] groups

# File lib/epuber/compiler/file_finders/abstract.rb, line 105
def assert_one_file(files, pattern: nil, groups: nil, context_path: nil)
  raise FileNotFoundError.new(pattern, context_path) if files.empty?
  raise MultipleFilesFoundError.new(pattern, groups, context_path, files) if files.count >= 2
end
find_all(pattern, groups: nil, context_path: @source_path_abs) click to toggle source

Looks for all files from source_path recursively

@param [String] pattern pattern of the desired files @param [Array<Symbol>] groups list of group names, nil or empty array for all groups, for valid values see GROUP_EXTENSIONS @param [String] context_path path for root of searching, it is also defines start folder of relative path

@return [Array<String>] list of founded files

# File lib/epuber/compiler/file_finders/abstract.rb, line 169
def find_all(pattern, groups: nil, context_path: @source_path_abs)
  __find_files('**/' + pattern, groups, context_path)
end
find_file(pattern, groups: nil, context_path: nil, search_everywhere: true) click to toggle source

Method for finding file from context_path, if there is not matching file, it will continue to search from source_path and after that it tries to search recursively from source_path.

When it founds too many (more than two) it will raise MultipleFilesFoundError

@param [String] pattern pattern of the desired files @param [Array<Symbol> | Symbol] groups list of group names, nil or empty array for all groups, for valid values see GROUP_EXTENSIONS @param [String] context_path path for root of searching, it is also defines start folder of relative path

@return [Array<String>] list of founded files

# File lib/epuber/compiler/file_finders/abstract.rb, line 121
def find_file(pattern, groups: nil, context_path: nil, search_everywhere: true)
  files = find_files(pattern, groups: groups, context_path: context_path, search_everywhere: search_everywhere)
  assert_one_file(files, pattern: pattern, groups: groups, context_path: context_path)
  files.first
end
find_files(pattern, groups: nil, context_path: nil, search_everywhere: true) click to toggle source

Method for finding files from context_path, if there is not matching file, it will continue to search from source_path and after that it tries to search recursively from source_path.

@param [String] pattern pattern of the desired files @param [Array<Symbol>] groups list of group names, nil or empty array for all groups, for valid values see GROUP_EXTENSIONS @param [String] context_path path for root of searching, it is also defines start folder of relative path

@return [Array<String>] list of founded files

# File lib/epuber/compiler/file_finders/abstract.rb, line 136
def find_files(pattern, groups: nil, context_path: nil, search_everywhere: true)
  files = []
  searching_path = context_path

  unless searching_path.nil?
    searching_path = ::File.expand_path(context_path, @source_path_abs)

    unless searching_path.start_with?(@source_path_abs)
      raise "You can't search from folder (#{searching_path}) that is not sub folder of the source_path (#{source_path}) expanded to (#{@source_path_abs})."
    end

    files = __find_files(pattern, groups, searching_path)
  end

  if files.empty? && context_path != source_path
    files = __find_files(pattern, groups, @source_path_abs, searching_path || @source_path_abs)
  end

  if files.empty? && search_everywhere && !pattern.start_with?('**')
    files = __find_files('**/' + pattern, groups, @source_path_abs, searching_path || @source_path_abs)
  end

  files
end

Private Instance Methods

__core_file?(path) click to toggle source
# File lib/epuber/compiler/file_finders/abstract.rb, line 265
def __core_file?(path)
  raise 'Implement this in subclass'
end
__core_find_files(pattern, groups, context_path, orig_context_path = context_path) click to toggle source

Core method for finding files, it only search for files, filter by input groups and map the final paths to pretty relative paths from context_path

@param [String] pattern pattern of the desired files @param [Array<Symbol>] groups list of group names, nil or empty array for all groups, for valid values see GROUP_EXTENSIONS @param [String] context_path path for root of searching, it is also defines start folder of relative path @param [String] orig_context_path original context path, wo it will work nicely with iterative searching

@return [Array<String>] list of founded files

# File lib/epuber/compiler/file_finders/abstract.rb, line 239
def __core_find_files(pattern, groups, context_path, orig_context_path = context_path)
  context_path = __core_file?(context_path) ? File.dirname(context_path) : context_path
  orig_context_path = __core_file?(orig_context_path) ? File.dirname(orig_context_path) : orig_context_path

  full_pattern = File.expand_path(pattern, context_path)
  file_paths = __core_find_files_from_pattern(full_pattern).map(&:unicode_normalize)

  file_paths.reject! do |path|
    File.directory?(path)
  end

  # remove any files that should be ignored
  file_paths.reject! do |path|
    ignored_patterns.any? { |exclude_pattern| File.fnmatch(exclude_pattern, path) }
  end

  file_paths = self.class.group_filter_paths(file_paths, groups)

  # create relative path to context path
  self.class.relative_paths_from(file_paths, orig_context_path)
end
__core_find_files_from_pattern(pattern) click to toggle source
# File lib/epuber/compiler/file_finders/abstract.rb, line 261
def __core_find_files_from_pattern(pattern)
  raise 'Implement this in subclass'
end
__find_files(pattern, groups, context_path, orig_context_path = context_path) click to toggle source

Looks for files at given context path, if there is no file, it will try again with pattern for any extension

@param [String] pattern pattern of the desired files @param [Array<Symbol>] groups list of group names, nil or empty array for all groups, for valid values see GROUP_EXTENSIONS @param [String] context_path path for root of searching, it is also defines start folder of relative path @param [String] orig_context_path original context path, wo it will work nicely with iterative searching

@return [Array<String>] list of founded files

# File lib/epuber/compiler/file_finders/abstract.rb, line 218
def __find_files(pattern, groups, context_path, orig_context_path = context_path)
  # remove fragment from pattern
  pattern = pattern.sub(/#.*$/, '') if pattern.include?('#')

  files = __core_find_files(pattern, groups, context_path, orig_context_path)

  # try to find files with any extension
  files = __core_find_files(pattern + '.*', groups, context_path, orig_context_path) if files.empty?

  files
end