Class: DirectorySearcher

Inherits:
Object show all
Defined in:
lib/directory_searcher.rb

Overview

Class DirectorySearcher This class provides methods to search for a specified pattern in directory names, file names, and contents of files within given paths.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pattern, paths, include_subdirectories: true, filename_glob: '*.[Mm][Dd]') ⇒ DirectorySearcher

Constructor

Parameters:

  • pattern (Regexp)

    The regular expression pattern to search for.

  • paths (Array<String>)

    List of directories to search in.

  • include_subdirectories (Boolean) (defaults to: true)

    Whether to search in subdirectories.

  • filename_glob (String, nil) (defaults to: '*.[Mm][Dd]')

    Glob pattern for file names.



104
105
106
107
108
109
# File 'lib/directory_searcher.rb', line 104

def initialize(pattern, paths, include_subdirectories: true, filename_glob: '*.[Mm][Dd]') #'*.md'
  @pattern = pattern
  @paths = paths
  @include_subdirectories = include_subdirectories
  @filename_glob = filename_glob
end

Instance Attribute Details

#filename_globObject (readonly)

Returns the value of attribute filename_glob.



97
98
99
# File 'lib/directory_searcher.rb', line 97

def filename_glob
  @filename_glob
end

#include_subdirectoriesObject (readonly)

Returns the value of attribute include_subdirectories.



97
98
99
# File 'lib/directory_searcher.rb', line 97

def include_subdirectories
  @include_subdirectories
end

#pathsObject (readonly)

Returns the value of attribute paths.



97
98
99
# File 'lib/directory_searcher.rb', line 97

def paths
  @paths
end

#patternObject (readonly)

Returns the value of attribute pattern.



97
98
99
# File 'lib/directory_searcher.rb', line 97

def pattern
  @pattern
end

Instance Method Details

#search_in_directory_namesArray<String>

Searches for the pattern in directory names.

Returns:

  • (Array<String>)

    List of matching directory names.



113
114
115
116
117
118
119
120
121
122
# File 'lib/directory_searcher.rb', line 113

def search_in_directory_names
  match_dirs = []
  @paths.each do |path|
    Find.find(path) do |p|
      # Find.prune unless @include_subdirectories || path == p
      match_dirs << p if File.directory?(p) && p.match?(@pattern)
    end
  end
  match_dirs
end

#search_in_file_contentsHash

Searches for the pattern in the contents of the files and returns matches along with their file paths and line numbers.

Returns:

  • (Hash)

    A hash where each key is a file path and each value is an array of hashes with :line_number and :line keys.



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/directory_searcher.rb', line 150

def search_in_file_contents
  match_details = {}

  @paths.each do |path|
    Find.find(path) do |p|
      Find.prune unless @include_subdirectories || path == p
      next unless File.file?(p)

      next if @filename_glob && !File.fnmatch(@filename_glob, File.basename(p))

      begin
        File.foreach(p).with_index(1) do |line, line_num| # Index starts from 1 for line numbers
          line_utf8 = line.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')
          if line_utf8.match?(@pattern)
            match_details[p] ||= []
            # match_details[p] << { number: line_num, line: line_utf8.chomp }
            match_details[p] << IndexedLine.new(line_num, line_utf8.chomp)
          end
        end
      rescue EncodingError
        # Optionally log the file with encoding issues
        # puts "Encoding error in file: #{p}"
      end
    end
  end

  match_details
end

#search_in_file_namesArray<String>

Searches for the pattern in file names.

Returns:



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/directory_searcher.rb', line 126

def search_in_file_names
  match_files = []
  @paths.each do |path|
    Find.find(path) do |p|
      # Find.prune unless @include_subdirectories || path == p
      next unless File.file?(p)

      file_name = File.basename(p)
      next if @filename_glob && !File.fnmatch(@filename_glob, file_name)

      begin
        match_files << p if file_name.encode('UTF-8', invalid: :replace, undef: :replace,
                                                      replace: '').match?(@pattern)
      rescue EncodingError
        # Optionally log the file with encoding issues
        # puts "Encoding error in file: #{p}"
      end
    end
  end
  match_files
end