Class: Utils::Finder

Inherits:
Object show all
Includes:
Term::ANSIColor, Files, Patterns
Defined in:
lib/utils/finder.rb,
lib/utils/finder.rb

Overview

A class for finding and searching files with configurable patterns and filters.

This class provides functionality for traversing file systems to locate files based on various criteria including file extensions, directory pruning, and pattern matching. It supports both indexed and direct search approaches to optimize performance when dealing with large codebases or frequently accessed file sets.

Examples:

finder = Utils::Finder.new(args: { l: true }, roots: ['.'])
finder.search

Defined Under Namespace

Modules: Files

Constant Summary

Constants included from XDG

XDG::XDG_CACHE_HOME, XDG::XDG_CONFIG_HOME, XDG::XDG_DATA_HOME, XDG::XDG_STATE_HOME

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Files

#current_paths

Methods included from Patterns

#choose

Constructor Details

#initialize(opts = {}) ⇒ Utils::Finder

Initializes a new Finder instance with the specified options.

Configures the finder to search either specific files or directories based on the provided arguments. Handles command-line argument parsing and pattern configuration for search operations.

Examples:

Basic usage with root directories

finder = Utils::Finder.new(args: { l: true }, roots: ['.'])

Usage with specific files

finder = Utils::Finder.new(args: { l: true }, files: ['file1.rb', 'file2.rb'])

Options Hash (opts):

  • :args (Hash)

    Command-line arguments hash

  • :roots (Array<String>)

    Root directories to search

  • :files (Array<String>)

    Specific files to process

  • :config (Utils::ConfigFile) — default: Utils::ConfigFile.new

    Configuration object

  • :pattern (Hash)

    Pattern-related options

  • :pattern (String)

    :cset Character set for pattern matching

  • :pattern (Boolean)

    :icase Case insensitive matching

Raises:

  • (ArgumentError)

    When both :roots and :files are specified



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/utils/finder.rb', line 52

def initialize(opts = {})
  @args  = opts[:args] || {}
  if opts[:files]
    opts[:roots] and raise ArgumentError, "Require :roots xor :files argument"
    @files = opts[:files]
  else
    @roots = discover_roots(opts[:roots])
  end
  @config = opts[:config] || Utils::ConfigFile.new
  if @args[?l] || @args[?L]
    @pattern = nil
  else
    pattern_opts = opts.subhash(:pattern) | {
      :cset  => @args[?a],
      :icase => @args[?i] != ?n,
    }
    @pattern = choose(@args[?p], pattern_opts)
  end
  @paths  = []
  reset_index
end

Instance Attribute Details

#outputObject (readonly)

The output reader method provides access to the output value.



87
88
89
# File 'lib/utils/finder.rb', line 87

def output
  @output
end

#pathsArray<String> (readonly)

The paths reader method provides access to the array of file paths that have been processed or collected.

This method returns the internal array containing the file paths, allowing external code to read the current set of paths without modifying the original collection.



82
83
84
# File 'lib/utils/finder.rb', line 82

def paths
  @paths
end

Instance Method Details

#build_pathsArray<String>

The build_paths method constructs a list of file system paths by traversing the configured root directories.

This method iterates through the specified root directories and collects all file system entries, applying filtering logic to exclude certain directories and files based on configuration settings. It handles both regular files and directories, ensuring that directory entries are properly marked with a trailing slash for distinction. The resulting paths are deduplicated before being returned.

marked by a trailing slash



101
102
103
104
105
# File 'lib/utils/finder.rb', line 101

def build_paths
  paths = Set[]
  each_path { |path| paths << path }
  paths.sort
end

#searchUtils::Finder

The search method executes a file search operation using pre-loaded paths and configured patterns

This method leverages previously loaded file paths and applies the configured search patterns to filter and process the files. It serves as the main entry point for performing search operations within the configured file system scope.



169
170
171
# File 'lib/utils/finder.rb', line 169

def search
  search_paths current_paths
end

#search_paths(paths) ⇒ Utils::Finder

The search_paths method processes and filters a collection of file paths based on specified criteria.

This method takes an array of paths and applies filtering based on file extensions and patterns. It handles both fuzzy and regular expression pattern matching, and returns formatted results with optional sorting and limiting of results.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/utils/finder.rb', line 118

def search_paths(paths)
  suffixes = Array(@args[?I])
  suffixes.full? do |s|
    paths.select! { |path| s.include?(File.extname(path)[1..-1]) }
  end
  paths = paths.map do |path|
    if @pattern.nil?
      [ [ path.count(?/), path ], path, path ]
    elsif match = @pattern.match(path)
      if FuzzyPattern === @pattern
        current = 0
        marked_path = ''
        score, e = path.size, nil
        for i in 1...match.size
          match[i] or next
          b = match.begin(i)
          e ||= b
          marked_path << path[current...b]
          marked_path << red(path[b, 1])
          score += (b - e) * (path.size - b)
          e = match.end(i)
          current = b + 1
        end
        marked_path << match.post_match
        [ score, path, marked_path ]
      else
        marked_path = path[0...match.begin(0)] <<
          red(path[match.begin(0)...match.end(0)]) <<
          path[match.end(0)..-1]
        [ 0, path, marked_path ]
      end
    end
  end
  paths.compact!
  @paths, @output = paths.sort.transpose.values_at(-2, -1)
  if n = @args[?n]&.to_i
    @paths = @paths&.first(n) || []
    @output = @output&.first(n) || []
  end
  self
end