grepfruit 4.0.0 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5756a4241133424de6c099a46fcd450f8144cbbbf72951af6312ceffedc565a3
4
- data.tar.gz: 9e248f116cf6a8d1742a63a33b1330c7008fd03cc9c11c393cbf4e2bebbb8734
3
+ metadata.gz: a1e692e9c73cb5e153c74e9f9dad30665f77eae2c1d12335b9cda68eb19cc27e
4
+ data.tar.gz: be22dc571889bcd9e59378e8896949dfd792d966e2bb01d65ad3c4fec70329a6
5
5
  SHA512:
6
- metadata.gz: d41210632eb24008ac4f14742aed37e44da75f19540b8d26c973a1bda8d473b3d6648a4fe37691423c87c3e7ba1fa03e60530d19109e8cc0fd6108809ebc101e
7
- data.tar.gz: 9b787719f4bb9d63fe2641f5b15a4214a7dd95921df63a4f010ce59dce71f87c17e62a2fd888dbc2d5c3206c303d98e5497a6b838fac4e8396b6ca5809989f89
6
+ metadata.gz: fb52ee14db47e883bedbfe53ab17aea9b032b87f6749910a6af441cda3fe9b413ba9e11d5baa8d6ff8b3f8271b76da61d45f4ea9db6aa67a4714124bea9c96dd
7
+ data.tar.gz: 64052138a5df15c7e3ad5f9f6e2227d60016e9cfa6539e2a7b09c5166af8924d07eb03943af522fb2daa63baafb3fe5120aad0f315161c07ba7f93e0b02e63d1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## v4.0.2
2
+
3
+ - Fixed searches silently checking no files when the search path itself was hidden or matched an exclusion
4
+ - Fixed a crash backtrace being printed after the error message when the search path does not exist
5
+ - Fixed the whole search crashing when a file is deleted or becomes unreadable mid-search
6
+
7
+ ## v4.0.1
8
+
9
+ - Restored accidentally removed CLI progress indicator
10
+
1
11
  ## v4.0.0
2
12
 
3
13
  - Match results now always contain absolute file paths
data/README.md CHANGED
@@ -219,24 +219,26 @@ Grepfruit returns meaningful exit codes for CI/CD integration:
219
219
  ## Getting Help and Contributing
220
220
 
221
221
  ### Getting Help
222
+
222
223
  Have a question or need assistance? Open a discussion in the [discussions section](https://github.com/enjaku4/grepfruit/discussions) for:
224
+
223
225
  - Usage questions
224
226
  - Implementation guidance
225
- - Feature suggestions
227
+ - Open-ended ideas or suggestions
228
+
229
+ ### Issues
230
+
231
+ [Issues](https://github.com/enjaku4/grepfruit/issues) track bugs, planned features, and other work. When reporting a bug, please include:
226
232
 
227
- ### Reporting Issues
228
- Found a bug? Please [create an issue](https://github.com/enjaku4/grepfruit/issues) with:
229
233
  - A clear description of the problem
230
234
  - Steps to reproduce the issue
231
235
  - Your environment details (Ruby version, OS, etc.)
232
236
 
233
237
  ### Contributing Code
234
- Ready to contribute? You can:
235
- - Fix bugs by submitting pull requests
236
- - Improve documentation
237
- - Add new features (please discuss first in the [discussions section](https://github.com/enjaku4/grepfruit/discussions))
238
238
 
239
- Before contributing, please read the [contributing guidelines](https://github.com/enjaku4/grepfruit/blob/master/CONTRIBUTING.md)
239
+ Any open issue is free to pick up or discuss. Check the [project board](https://github.com/users/enjaku4/projects/12) or [issues tab](https://github.com/enjaku4/grepfruit/issues).
240
+
241
+ Before contributing, please read the [contributing guidelines](https://github.com/enjaku4/grepfruit/blob/master/CONTRIBUTING.md).
240
242
 
241
243
  ## License
242
244
 
data/exe/grepfruit CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  RubyVM::YJIT.enable if defined?(RubyVM::YJIT) && RubyVM::YJIT.respond_to?(:enable)
4
4
 
5
+ Warning[:experimental] = false
6
+
5
7
  $LOAD_PATH.unshift("#{__dir__}/../lib")
6
8
 
7
9
  require "grepfruit"
@@ -11,11 +11,18 @@ module Grepfruit
11
11
  def red(text) = colorize(text, :red)
12
12
  def cyan(text) = colorize(text, :cyan)
13
13
 
14
+ def print_file_progress_dot(has_matches)
15
+ print(has_matches ? red(".") : green("."))
16
+ end
17
+
14
18
  def number_of_files(num) = "#{num} file#{'s' if num != 1}"
15
19
  def number_of_matches(num) = "#{num} match#{'es' if num != 1}"
16
20
 
17
21
  def display_results(results)
18
- puts "" if results.total_files.positive?
22
+ if results.total_files.positive?
23
+ puts
24
+ puts
25
+ end
19
26
 
20
27
  if results.match_count.zero?
21
28
  puts "#{number_of_files(results.total_files)} checked, #{green('no matches found')}"
@@ -5,9 +5,15 @@ module Grepfruit
5
5
  include Grepfruit::CliDecorator
6
6
 
7
7
  def execute
8
- puts "Error: Path '#{path}' does not exist." and exit 1 unless File.exist?(path)
8
+ unless File.exist?(path)
9
+ puts "Error: Path '#{path}' does not exist."
10
+ exit 1
11
+ end
9
12
 
10
- puts "Searching for #{regex.inspect} in #{path.inspect}..." unless json
13
+ unless json
14
+ puts "Searching for #{regex.inspect} in #{path.inspect}..."
15
+ puts
16
+ end
11
17
 
12
18
  results = execute_search
13
19
 
@@ -19,5 +25,13 @@ module Grepfruit
19
25
 
20
26
  exit(results.match_count.positive? ? 1 : 0)
21
27
  end
28
+
29
+ private
30
+
31
+ def emit_file_progress(has_matches)
32
+ return if json
33
+
34
+ print_file_progress_dot(has_matches)
35
+ end
22
36
  end
23
37
  end
@@ -2,8 +2,6 @@ require "find"
2
2
  require "etc"
3
3
  require_relative "ractor_compat"
4
4
 
5
- Warning[:experimental] = false
6
-
7
5
  module Grepfruit
8
6
  class Search
9
7
  attr_reader :path, :regex, :exclusions, :inclusions, :excluded_paths, :excluded_lines, :truncate, :search_hidden, :jobs, :json, :count
@@ -65,7 +63,9 @@ module Grepfruit
65
63
  ready_worker, worker_result = RactorCompat.select_ready(active_workers)
66
64
  port = active_workers.delete(ready_worker)
67
65
 
68
- results.increment_files_with_matches if process_worker_result(worker_result, results)
66
+ has_matches = process_worker_result(worker_result, results)
67
+ results.increment_files_with_matches if has_matches
68
+ emit_file_progress(has_matches)
69
69
  assign_file_to_worker(ready_worker, port, file_enumerator, active_workers, results)
70
70
  end
71
71
 
@@ -85,6 +85,8 @@ module Grepfruit
85
85
  true
86
86
  end
87
87
 
88
+ def emit_file_progress(_has_matches); end
89
+
88
90
  def create_persistent_worker
89
91
  RactorCompat.create_worker do |port|
90
92
  loop do
@@ -94,14 +96,18 @@ module Grepfruit
94
96
  file_path, pattern, exc_lines, count = work
95
97
  file_results, has_matches, match_count = [], false, 0
96
98
 
97
- File.foreach(file_path).with_index do |line, line_num|
98
- next unless line.valid_encoding? && line.match?(pattern)
99
+ begin
100
+ File.foreach(file_path).with_index do |line, line_num|
101
+ next unless line.valid_encoding? && line.match?(pattern)
99
102
 
100
- next if exc_lines.any? { "#{file_path}:#{line_num + 1}".end_with?(_1) }
103
+ next if exc_lines.any? { "#{file_path}:#{line_num + 1}".end_with?(_1) }
101
104
 
102
- file_results << [file_path, line_num + 1, line] unless count
103
- has_matches = true
104
- match_count += 1
105
+ file_results << [file_path, line_num + 1, line] unless count
106
+ has_matches = true
107
+ match_count += 1
108
+ end
109
+ rescue Errno::ENOENT, Errno::EACCES, Errno::EISDIR
110
+ file_results, has_matches, match_count = [], false, 0
105
111
  end
106
112
 
107
113
  RactorCompat.yield_result(port, [file_results, has_matches, match_count])
@@ -133,7 +139,7 @@ module Grepfruit
133
139
  Find.find(path) do |file_path|
134
140
  is_file = File.file?(file_path)
135
141
 
136
- Find.prune if excluded_path?(is_file, file_path, file_path.delete_prefix("#{path}/"))
142
+ Find.prune if file_path != path && excluded_path?(is_file, file_path, file_path.delete_prefix("#{path}/"))
137
143
 
138
144
  next unless is_file && File.readable?(file_path)
139
145
 
@@ -1,3 +1,3 @@
1
1
  module Grepfruit
2
- VERSION = "4.0.0".freeze
2
+ VERSION = "4.0.2".freeze
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grepfruit
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - enjaku4
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2026-04-01 00:00:00.000000000 Z
10
+ date: 2026-07-19 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: dry-cli
@@ -74,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  requirements: []
77
- rubygems_version: 4.0.8
77
+ rubygems_version: 4.0.3
78
78
  specification_version: 4
79
79
  summary: Tool for searching regex patterns in files
80
80
  test_files: []