Class: Clacky::Tools::Glob
Constant Summary collapse
- MAX_FILE_SIZE =
Maximum file size to search (1MB)
1_048_576
Instance Method Summary collapse
- #execute(pattern:, base_path: ".", limit: 10, working_dir: nil) ⇒ Object
- #format_call(args) ⇒ Object
- #format_result(result) ⇒ Object
Methods inherited from Base
#category, #description, #name, #parameters, #to_function_definition
Instance Method Details
#execute(pattern:, base_path: ".", limit: 10, working_dir: nil) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/clacky/tools/glob.rb', line 36 def execute(pattern:, base_path: ".", limit: 10, working_dir: nil) # Validate pattern if pattern.nil? || pattern.strip.empty? return { error: "Pattern cannot be empty" } end # Expand ~ in pattern only (pattern is relative to base_path, not working_dir) pattern = pattern.start_with?("~") ? File.(pattern) : pattern # Expand base_path fully (~ and relative paths resolved against working_dir) base_path = (base_path, working_dir: working_dir) # Validate base_path unless Dir.exist?(base_path) return { error: "Base path does not exist: #{base_path}" } end begin = base_path # Initialize gitignore parser gitignore_path = Clacky::Utils::FileIgnoreHelper.find_gitignore() gitignore = gitignore_path ? Clacky::GitignoreParser.new(gitignore_path) : nil # Track skipped files skipped = { binary: 0, too_large: 0, ignored: 0 } # Auto-expand bare patterns (no slash, no **) to recursive search. # e.g. "*install*" -> "**/*install*", "*.rb" -> "**/*.rb" # This avoids surprising empty results when files are in subdirectories. effective_pattern = if !File.absolute_path?(pattern) && !pattern.include?("/") && !pattern.start_with?("**") "**/#{pattern}" else pattern end # Build full pattern - handle absolute paths correctly full_pattern = if File.absolute_path?(effective_pattern) effective_pattern else File.join(base_path, effective_pattern) end # Always-ignored directory names that should never appear in results always_ignored_dirs = Clacky::Utils::FileIgnoreHelper::ALWAYS_IGNORED_DIRS all_matches = Dir.glob(full_pattern, File::FNM_DOTMATCH) .reject { |path| File.directory?(path) } .reject { |path| path.end_with?(".", "..") } .reject do |path| # Fast path: reject files inside always-ignored dirs by path component parts = path.split(File::SEPARATOR) parts.any? { |part| always_ignored_dirs.include?(part) } end # Filter out ignored, binary, and too large files matches = all_matches.select do |file| # Skip if file should be ignored (unless it's a config file) if Clacky::Utils::FileIgnoreHelper.should_ignore_file?(file, , gitignore) && !Clacky::Utils::FileIgnoreHelper.is_config_file?(file) skipped[:ignored] += 1 next false end # Skip binary files (but allow known document types like PDF/Office) if Clacky::Utils::FileProcessor.binary_file_path?(file) && !Clacky::Utils::FileProcessor.glob_allowed_binary?(file) skipped[:binary] += 1 next false end # Skip files that are too large if File.size(file) > MAX_FILE_SIZE skipped[:too_large] += 1 next false end true end # Sort by modification time (most recent first) matches = matches.sort_by { |path| -File.mtime(path).to_i } # Apply limit total_matches = matches.length matches = matches.take(limit) # Convert to absolute paths matches = matches.map { |path| File.(path) } { matches: matches, total_matches: total_matches, returned: matches.length, truncated: total_matches > limit, skipped_files: skipped, error: nil } rescue StandardError => e { error: "Failed to glob files: #{e.}" } end end |
#format_call(args) ⇒ Object
143 144 145 146 147 148 149 |
# File 'lib/clacky/tools/glob.rb', line 143 def format_call(args) pattern = args[:pattern] || args['pattern'] || '' base_path = args[:base_path] || args['base_path'] || '.' display_base = base_path == '.' ? '' : " in #{base_path}" "glob(\"#{pattern}\"#{display_base})" end |
#format_result(result) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/clacky/tools/glob.rb', line 151 def format_result(result) if result[:error] "[Error] #{result[:error]}" else count = result[:returned] || 0 total = result[:total_matches] || 0 truncated = result[:truncated] ? " (truncated)" : "" msg = "[OK] Found #{count}/#{total} files#{truncated}" # Add skipped files info if present if result[:skipped_files] skipped = result[:skipped_files] skipped_parts = [] skipped_parts << "#{skipped[:ignored]} ignored" if skipped[:ignored] > 0 skipped_parts << "#{skipped[:binary]} binary" if skipped[:binary] > 0 skipped_parts << "#{skipped[:too_large]} too large" if skipped[:too_large] > 0 msg += " (skipped: #{skipped_parts.join(', ')})" unless skipped_parts.empty? end msg end end |