grepfruit 3.2.0 → 3.2.1

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: 505fa3f2e5b4b5ffc41a795f0305e6a37f913b7fe66036018d4f4438dc6c9b40
4
- data.tar.gz: 3f89449fd5ab9d2851aadac1ec432606aeaae73b4673bd0d4e62cd96b4bdc83f
3
+ metadata.gz: fe98ab0d2336cca1ac32274bd34aac1b21599fbf0754e3d282c85bb1f91062f3
4
+ data.tar.gz: db3c4492f5aa9d45131dff7c0342dd58e74c96b04bfacb538c6131e4ca2950ee
5
5
  SHA512:
6
- metadata.gz: 2e2ff1bdec53492186f6ff37670e82b62ee72ff84435c68167bd7ef7ae460ee23221dbc1d0682205207acc579660675ea4504b6722498e51520465fb9ac79cbe
7
- data.tar.gz: 4dac4064e07aafd907523d6223dfa789eae14428a5e92b4edcb82ef206391e179e469f76db56d972bbc01815be0c58f3c574353832eb45bfbb942d89b21a052e
6
+ metadata.gz: 30c29450c9e0535f2926de44a66adbcccf1021537c1d00ed3e4a9282cda2862c34f4235f1847740488c67dde79083e9b86b175a729cd8f5ee980cf2ee9a02e1c
7
+ data.tar.gz: cb46abd7db199d7305d4a1c5f67b9fa6153a422ff8219213b7ef30dc196632d1fcac78a2c6442602713b79df2bddf1c015eb692631468d1cb3a6e1a8b85c2b6c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## v3.2.1
2
+
3
+ - Skip unreadable files instead of crashing
4
+ - Minor internal optimizations
5
+
1
6
  ## v3.2.0
2
7
 
3
8
  - Added programmatic API for use in Ruby applications
data/README.md CHANGED
@@ -7,8 +7,8 @@
7
7
 
8
8
  Grepfruit is a tool for searching regex patterns in files, with a CLI designed for CI/CD pipelines and a programmatic API for Ruby applications.
9
9
 
10
- <img width="933" height="221" alt="Screenshot 2025-10-15 at 13 28 06" src="https://github.com/user-attachments/assets/cad09b17-9b79-4377-8cf9-365108a96a5a" />
11
- <img width="709" height="586" alt="Screenshot 2025-10-15 at 13 29 01" src="https://github.com/user-attachments/assets/36664522-1eee-40bf-8f58-a2503668e1a4" />
10
+ <img width="774" height="155" alt="Screenshot 2026-01-02 at 17 15 48" src="https://github.com/user-attachments/assets/550057e0-7783-4bd2-be9b-ce49f48bdc04" />
11
+ <img width="598" height="484" alt="Screenshot 2026-01-02 at 17 16 52" src="https://github.com/user-attachments/assets/6eff05af-b58d-4e28-a496-343e243b79a2" />
12
12
 
13
13
  ## Table of Contents
14
14
 
@@ -1,3 +1,5 @@
1
+ require "json"
2
+
1
3
  module Grepfruit
2
4
  module CliDecorator
3
5
  COLORS = { cyan: "\e[36m", red: "\e[31m", green: "\e[32m", reset: "\e[0m" }.freeze
@@ -31,8 +33,6 @@ module Grepfruit
31
33
  end
32
34
 
33
35
  def display_json_results(result_hash)
34
- require "json"
35
-
36
36
  result_hash[:search][:pattern] = result_hash[:search][:pattern].inspect
37
37
  result_hash[:search][:timestamp] = Time.now.strftime("%Y-%m-%dT%H:%M:%S%z")
38
38
 
@@ -13,8 +13,8 @@ module Grepfruit
13
13
  @regex = regex
14
14
  @exclusions = exclude
15
15
  @inclusions = include
16
- @excluded_lines, @excluded_paths = exclude.map { _1.split("/") }.partition { _1.last.include?(":") }
17
- @included_paths = include.map { _1.split("/") }
16
+ @excluded_lines, @excluded_paths = exclude.partition { _1.split("/").last.include?(":") }
17
+ @included_paths = include
18
18
  @truncate = truncate
19
19
  @search_hidden = search_hidden
20
20
  @jobs = jobs || Etc.nprocessors
@@ -92,14 +92,13 @@ module Grepfruit
92
92
  work = Ractor.receive
93
93
  break if work == :quit
94
94
 
95
- file_path, pattern, exc_lines, base_path, count = work
95
+ file_path, relative_path, pattern, exc_lines, count = work
96
96
  file_results, has_matches, match_count = [], false, 0
97
- relative_path = file_path.delete_prefix("#{base_path}/")
98
97
 
99
98
  File.foreach(file_path).with_index do |line, line_num|
100
99
  next unless line.valid_encoding? && line.match?(pattern)
101
100
 
102
- next if exc_lines.any? { "#{relative_path}:#{line_num + 1}".end_with?(_1.join("/")) }
101
+ next if exc_lines.any? { "#{relative_path}:#{line_num + 1}".end_with?(_1) }
103
102
 
104
103
  file_results << [relative_path, line_num + 1, line] unless count
105
104
  has_matches = true
@@ -112,10 +111,10 @@ module Grepfruit
112
111
  end
113
112
 
114
113
  def assign_file_to_worker(worker, port, file_enumerator, active_workers, results)
115
- file_path = get_next_file(file_enumerator)
114
+ file_path, rel_path = get_next_file(file_enumerator)
116
115
  return unless file_path
117
116
 
118
- RactorCompat.send_work(worker, [file_path, regex, excluded_lines, path, count])
117
+ RactorCompat.send_work(worker, [file_path, rel_path, regex, excluded_lines, count])
119
118
  active_workers[worker] = port
120
119
  results.total_files += 1
121
120
  end
@@ -133,26 +132,24 @@ module Grepfruit
133
132
  def create_file_enumerator
134
133
  Enumerator.new do |yielder|
135
134
  Find.find(path) do |file_path|
136
- Find.prune if excluded_path?(file_path)
135
+ rel_path = file_path.delete_prefix("#{path}/")
136
+ Find.prune if excluded_path?(file_path, rel_path)
137
137
 
138
- next unless File.file?(file_path)
138
+ next unless File.file?(file_path) && File.readable?(file_path)
139
139
 
140
- yielder << file_path
140
+ yielder << [file_path, rel_path]
141
141
  end
142
142
  end
143
143
  end
144
144
 
145
- def excluded_path?(file_path)
146
- rel_path = file_path.delete_prefix("#{path}/")
147
-
145
+ def excluded_path?(file_path, rel_path)
148
146
  (File.file?(file_path) && included_paths.any? && !matches_pattern?(included_paths, rel_path)) ||
149
147
  matches_pattern?(excluded_paths, rel_path) ||
150
148
  (!search_hidden && File.basename(file_path).start_with?("."))
151
149
  end
152
150
 
153
151
  def matches_pattern?(pattern_list, path)
154
- pattern_list.any? do |pattern_parts|
155
- pattern = pattern_parts.join("/")
152
+ pattern_list.any? do |pattern|
156
153
  File.fnmatch?(pattern, path, File::FNM_PATHNAME) || File.fnmatch?(pattern, File.basename(path))
157
154
  end
158
155
  end
@@ -1,3 +1,3 @@
1
1
  module Grepfruit
2
- VERSION = "3.2.0".freeze
2
+ VERSION = "3.2.1".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grepfruit
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 3.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - enjaku4