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
142
|
# File 'lib/clacky/tools/glob.rb', line 36
def execute(pattern:, base_path: ".", limit: 10, working_dir: nil)
if pattern.nil? || pattern.strip.empty?
return { error: "Pattern cannot be empty" }
end
pattern = pattern.start_with?("~") ? File.expand_path(pattern) : pattern
base_path = expand_path(base_path, working_dir: working_dir)
unless Dir.exist?(base_path)
return { error: "Base path does not exist: #{base_path}" }
end
begin
expanded_path = base_path
gitignore_path = Clacky::Utils::FileIgnoreHelper.find_gitignore(expanded_path)
gitignore = gitignore_path ? Clacky::GitignoreParser.new(gitignore_path) : nil
skipped = {
binary: 0,
too_large: 0,
ignored: 0
}
effective_pattern = if !File.absolute_path?(pattern) &&
!pattern.include?("/") &&
!pattern.start_with?("**")
"**/#{pattern}"
else
pattern
end
full_pattern = if File.absolute_path?(effective_pattern)
effective_pattern
else
File.join(base_path, effective_pattern)
end
always_ignored_dirs = Clacky::Utils::FileIgnoreHelper::ALWAYS_IGNORED_DIRS
all_matches = Dir.glob(full_pattern, File::FNM_DOTMATCH)
.map { |p| p.encoding == Encoding::UTF_8 && p.valid_encoding? ? p : p.encode("UTF-8", invalid: :replace, undef: :replace, replace: "\u{FFFD}") }
.reject { |path| File.directory?(path) }
.reject { |path| path.end_with?(".", "..") }
.reject do |path|
parts = path.split(File::SEPARATOR)
parts.any? { |part| always_ignored_dirs.include?(part) }
end
matches = all_matches.select do |file|
if Clacky::Utils::FileIgnoreHelper.should_ignore_file?(file, expanded_path, gitignore) &&
!Clacky::Utils::FileIgnoreHelper.is_config_file?(file)
skipped[:ignored] += 1
next false
end
if Clacky::Utils::FileProcessor.binary_file_path?(file) &&
!Clacky::Utils::FileProcessor.glob_allowed_binary?(file)
skipped[:binary] += 1
next false
end
if File.size(file) > MAX_FILE_SIZE
skipped[:too_large] += 1
next false
end
true
end
matches = matches.sort_by { |path| -File.mtime(path).to_i }
total_matches = matches.length
matches = matches.take(limit)
matches = matches.map { |path| File.expand_path(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.message}" }
end
end
|