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 185
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).downcase)
    end
  end
end
new(source_path) click to toggle source

@param [String] source_path

# File lib/epuber/compiler/file_finders/abstract.rb, line 99
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 207
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 107
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 176
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 124
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 140
        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 <<~ERROR
                You can't search from folder (#{searching_path}) that is not sub folder of the source_path (#{source_path}) expanded to (#{@source_path_abs}).
              ERROR
            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 275
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 249
def __core_find_files(pattern, groups, context_path, orig_context_path = context_path)
  context_path = File.dirname(context_path) if __core_file?(context_path)
  orig_context_path = File.dirname(orig_context_path) if __core_file?(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 271
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 226
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