file-find 0.5.0 → 0.5.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 +4 -4
- checksums.yaml.gz.sig +3 -2
- data/CHANGES.md +16 -0
- data/Gemfile +2 -3
- data/MANIFEST.md +1 -1
- data/README.md +14 -1
- data/Rakefile +12 -3
- data/file-find.gemspec +14 -8
- data/lib/file/find.rb +46 -84
- data/lib/file-find.rb +2 -0
- data/spec/file_find_spec.rb +191 -163
- data.tar.gz.sig +0 -0
- metadata +56 -18
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0febb67274c45e862fa242e53bda0d97895817bf6ff98fd055f769afaa5d0e60
|
|
4
|
+
data.tar.gz: 20a42458a0f3b70e7bdffc6afd446be9b70e7417197ebbd3e4c9c1302d473559
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 51cabd736d8aeb6c35cd1e7bb38de0ee4ccd96a79ccbe0b9a08a657e69d0d9250afc1e7680986721de5cd33f20ff459bd3afbff9e47c0960d4b47b666a02bc00
|
|
7
|
+
data.tar.gz: 6ec15535aa08d5f78f81decbf7678f0c05f6ebd8978b5bb3eaef83c3fa315ed6414d696458008d1d2832bb3413747a0a21a0882f56019602064f859a8a82d0d4
|
checksums.yaml.gz.sig
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
����8�۵��
|
|
2
|
+
x�'�^g���V�t/��o�T���6�H�AềQ\.��ح�ڴ��M�4`9�D�cY�q���4�a�Aaʝ64S3"�r�l��얜�Oz���M�c���P�q�M�L/I�k��� �N������b����nO���!�{���ԗ�l�T���%�MT����麅�L�lv���ŷ�_���4�/�w�H������qi���Ju�4jL��i�
|
|
3
|
+
�g��_�e�r�ӳ���ӑn�@����'P���KV�V�oL�K�n��ն+���
|
data/CHANGES.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
## 0.5.2 - 22-Nov-2025
|
|
2
|
+
* Use fnmatch instead of some overworked checks for Windows paths using glob.
|
|
3
|
+
* Minor refactoring improvements for atime/ctime/mtime checks.
|
|
4
|
+
* Minor refactoring improvement for ftype check.
|
|
5
|
+
* Minor refactoring improvement for filetest check.
|
|
6
|
+
* Added MacOS and FreeBSD to the test matrix.
|
|
7
|
+
* The specs now run in documentation mode by default.
|
|
8
|
+
|
|
9
|
+
## 0.5.1 - 17-Jun-2025
|
|
10
|
+
* Updated, fixed or skipped some specs on Windows.
|
|
11
|
+
* Some rubocop cleanup and minor refactors.
|
|
12
|
+
* Added a github workflow matrix to the repo.
|
|
13
|
+
* Added a rubocop config to the repo.
|
|
14
|
+
* Minor tweaks to the Rakefile.
|
|
15
|
+
* Added more information to the README.
|
|
16
|
+
|
|
1
17
|
## 0.5.0 - 19-Jan-2021
|
|
2
18
|
* Switched from test-unit to rspec, with an added development
|
|
3
19
|
dependency on the fakefs gem.
|
data/Gemfile
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
source 'https://rubygems.org'
|
|
2
|
-
|
|
3
|
-
end
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
gemspec
|
data/MANIFEST.md
CHANGED
data/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
[](https://github.com/djberg96/file-find/actions/workflows/ruby.yml)
|
|
2
|
+
|
|
1
3
|
## Description
|
|
2
4
|
|
|
3
5
|
This is a drop-in replacement for the find module currently in the standard
|
|
@@ -7,6 +9,14 @@ library. It is modeled on a typical 'find' command found on most Unix systems.
|
|
|
7
9
|
|
|
8
10
|
`gem install file-find`
|
|
9
11
|
|
|
12
|
+
## Specs
|
|
13
|
+
|
|
14
|
+
Although this gem will work with Ruby 2.x or 3.x, you will need Ruby 3.x to
|
|
15
|
+
run the specs locally because of development dependencies.
|
|
16
|
+
|
|
17
|
+
## Adding the trusted cert
|
|
18
|
+
`gem cert --add <(curl -Ls https://raw.githubusercontent.com/djberg96/file-find/main/certs/djberg96_pub.pem)`
|
|
19
|
+
|
|
10
20
|
## Synopsis
|
|
11
21
|
```ruby
|
|
12
22
|
require 'file/find' # 'file-find' also works
|
|
@@ -82,6 +92,9 @@ The `:perm` option is limited to 0644 and 0444 on MS Windows.
|
|
|
82
92
|
The `:user`, `:group`, and `:inum` options require the win32-file gem to work
|
|
83
93
|
properly on MS Windows. However, win32-file is not officially a dependency.
|
|
84
94
|
|
|
95
|
+
Some specs on Windows are marked pending for now because there's some issue
|
|
96
|
+
interacting with the FakeFS gem on Windows.
|
|
97
|
+
|
|
85
98
|
## Bugs
|
|
86
99
|
|
|
87
100
|
None that I'm aware of beyond the ones mentioned in the Known Issues. Please
|
|
@@ -102,7 +115,7 @@ Apache-2.0
|
|
|
102
115
|
|
|
103
116
|
## Copyright
|
|
104
117
|
|
|
105
|
-
(C) 2007-
|
|
118
|
+
(C) 2007-2025, Daniel J. Berger, All Rights Reserved
|
|
106
119
|
|
|
107
120
|
## Author
|
|
108
121
|
|
data/Rakefile
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
require 'rake'
|
|
2
2
|
require 'rake/clean'
|
|
3
3
|
require 'rspec/core/rake_task'
|
|
4
|
+
require 'rubocop/rake_task'
|
|
4
5
|
|
|
5
|
-
CLEAN.include("**/*.gem", "**/*.rbc", "**/link*")
|
|
6
|
+
CLEAN.include("**/*.gem", "**/*.rbc", "**/link*", "*.lock")
|
|
6
7
|
|
|
7
8
|
namespace :gem do
|
|
8
9
|
desc 'Create the file-find gem'
|
|
9
10
|
task :create => [:clean] do
|
|
10
11
|
require 'rubygems/package'
|
|
11
|
-
spec =
|
|
12
|
+
spec = Gem::Specification.load('file-find.gemspec')
|
|
12
13
|
spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
|
|
13
|
-
Gem::Package.build(spec
|
|
14
|
+
Gem::Package.build(spec)
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
desc "Install the file-find gem"
|
|
@@ -21,8 +22,16 @@ namespace :gem do
|
|
|
21
22
|
end
|
|
22
23
|
end
|
|
23
24
|
|
|
25
|
+
RuboCop::RakeTask.new
|
|
26
|
+
|
|
24
27
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
|
25
28
|
t.pattern = ['spec/file_find_spec.rb']
|
|
29
|
+
t.rspec_opts = '-f documentation'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Clean up afterwards
|
|
33
|
+
Rake::Task[:spec].enhance do
|
|
34
|
+
Rake::Task[:clean].invoke
|
|
26
35
|
end
|
|
27
36
|
|
|
28
37
|
task :default => :spec
|
data/file-find.gemspec
CHANGED
|
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |spec|
|
|
4
4
|
spec.name = 'file-find'
|
|
5
|
-
spec.version = '0.5.
|
|
5
|
+
spec.version = '0.5.2'
|
|
6
6
|
spec.author = 'Daniel Berger'
|
|
7
7
|
spec.license = 'Apache-2.0'
|
|
8
8
|
spec.summary = 'A better way to find files'
|
|
@@ -13,18 +13,24 @@ Gem::Specification.new do |spec|
|
|
|
13
13
|
spec.cert_chain = Dir['certs/*']
|
|
14
14
|
|
|
15
15
|
spec.metadata = {
|
|
16
|
-
'homepage_uri'
|
|
17
|
-
'bug_tracker_uri'
|
|
18
|
-
'changelog_uri'
|
|
19
|
-
'documentation_uri'
|
|
20
|
-
'source_code_uri'
|
|
21
|
-
'wiki_uri'
|
|
16
|
+
'homepage_uri' => 'https://github.com/djberg96/file-find',
|
|
17
|
+
'bug_tracker_uri' => 'https://github.com/djberg96/file-find/issues',
|
|
18
|
+
'changelog_uri' => 'https://github.com/djberg96/file-find/blob/main/CHANGES.md',
|
|
19
|
+
'documentation_uri' => 'https://github.com/djberg96/file-find/wiki',
|
|
20
|
+
'source_code_uri' => 'https://github.com/djberg96/file-find',
|
|
21
|
+
'wiki_uri' => 'https://github.com/djberg96/file-find/wiki',
|
|
22
|
+
'rubygems_mfa_required' => 'true',
|
|
23
|
+
'github_repo' => 'https://github.com/djberg96/file-find',
|
|
24
|
+
'funding_uri' => 'https://github.com/sponsors/djberg96'
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
spec.add_dependency('sys-admin', '~> 1.7')
|
|
25
28
|
spec.add_development_dependency('rspec', '~> 3.9')
|
|
26
|
-
spec.add_development_dependency('fakefs', '~>
|
|
29
|
+
spec.add_development_dependency('fakefs', '~> 3.0')
|
|
27
30
|
spec.add_development_dependency('rake')
|
|
31
|
+
spec.add_development_dependency('rubocop')
|
|
32
|
+
spec.add_development_dependency('rubocop-rspec')
|
|
33
|
+
spec.add_development_dependency('sys-uname')
|
|
28
34
|
|
|
29
35
|
spec.description = <<-EOF
|
|
30
36
|
The file-find library provides a better, more object oriented approach
|
data/lib/file/find.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'date'
|
|
2
4
|
require 'sys/admin'
|
|
3
5
|
|
|
@@ -7,9 +9,11 @@ rescue LoadError
|
|
|
7
9
|
# Do nothing, not required, just nicer.
|
|
8
10
|
end
|
|
9
11
|
|
|
12
|
+
# The File::Find class encapsulates 'rules' that you create and use to find
|
|
13
|
+
# files on your filesystem.
|
|
10
14
|
class File::Find
|
|
11
15
|
# The version of the file-find library
|
|
12
|
-
VERSION = '0.5.
|
|
16
|
+
VERSION = '0.5.2'
|
|
13
17
|
|
|
14
18
|
# :stopdoc:
|
|
15
19
|
VALID_OPTIONS = %w[
|
|
@@ -31,7 +35,7 @@ class File::Find
|
|
|
31
35
|
prune
|
|
32
36
|
size
|
|
33
37
|
user
|
|
34
|
-
]
|
|
38
|
+
].freeze
|
|
35
39
|
# :startdoc:
|
|
36
40
|
|
|
37
41
|
# The starting path(s) for the search. The default is the current directory.
|
|
@@ -107,7 +111,7 @@ class File::Find
|
|
|
107
111
|
attr_accessor :mtime
|
|
108
112
|
|
|
109
113
|
# The name pattern used to limit file searches. The patterns that are legal
|
|
110
|
-
# for
|
|
114
|
+
# for File.fnmatch are legal here. The default is '*', i.e. everything.
|
|
111
115
|
#
|
|
112
116
|
attr_accessor :name
|
|
113
117
|
|
|
@@ -208,7 +212,8 @@ class File::Find
|
|
|
208
212
|
#
|
|
209
213
|
def find
|
|
210
214
|
results = [] unless block_given?
|
|
211
|
-
paths = @path
|
|
215
|
+
paths = Array(@path)
|
|
216
|
+
queue = paths.dup
|
|
212
217
|
|
|
213
218
|
if @prune
|
|
214
219
|
prune_regex = Regexp.new(@prune)
|
|
@@ -216,19 +221,22 @@ class File::Find
|
|
|
216
221
|
prune_regex = nil
|
|
217
222
|
end
|
|
218
223
|
|
|
219
|
-
|
|
224
|
+
# rubocop:disable Metrics/BlockLength
|
|
225
|
+
until queue.empty?
|
|
226
|
+
path = queue.shift
|
|
220
227
|
begin
|
|
221
|
-
Dir.foreach(path)
|
|
228
|
+
Dir.foreach(path) do |file|
|
|
222
229
|
next if file == '.'
|
|
223
230
|
next if file == '..'
|
|
224
231
|
|
|
225
|
-
if prune_regex
|
|
226
|
-
next
|
|
232
|
+
if prune_regex && prune_regex.match(file)
|
|
233
|
+
next
|
|
227
234
|
end
|
|
228
235
|
|
|
229
236
|
file = File.join(path, file)
|
|
230
237
|
|
|
231
238
|
stat_method = @follow ? :stat : :lstat
|
|
239
|
+
|
|
232
240
|
# Skip files we cannot access, stale links, etc.
|
|
233
241
|
begin
|
|
234
242
|
stat_info = File.send(stat_method, file)
|
|
@@ -241,48 +249,27 @@ class File::Find
|
|
|
241
249
|
end
|
|
242
250
|
end
|
|
243
251
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
glob = File.join(temp, @name)
|
|
247
|
-
|
|
248
|
-
# Dir[] doesn't like backslashes
|
|
249
|
-
if File::ALT_SEPARATOR
|
|
250
|
-
file.tr!(File::ALT_SEPARATOR, File::SEPARATOR)
|
|
251
|
-
glob.tr!(File::ALT_SEPARATOR, File::SEPARATOR)
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
if @mount
|
|
255
|
-
next unless stat_info.dev == @filesystem
|
|
256
|
-
end
|
|
257
|
-
|
|
258
|
-
if @links
|
|
259
|
-
next unless stat_info.nlink == @links
|
|
260
|
-
end
|
|
252
|
+
next if @mount && stat_info.dev != @filesystem
|
|
253
|
+
next if @links && stat_info.nlink != @links
|
|
261
254
|
|
|
262
255
|
if @maxdepth || @mindepth
|
|
263
|
-
file_depth = file.split(File::SEPARATOR).reject
|
|
256
|
+
file_depth = file.split(File::SEPARATOR).reject(&:empty?).length
|
|
264
257
|
current_base_path = [@path].flatten.find{ |tpath| file.include?(tpath) }
|
|
265
258
|
path_depth = current_base_path.split(File::SEPARATOR).length
|
|
266
259
|
|
|
267
260
|
depth = file_depth - path_depth
|
|
268
261
|
|
|
269
|
-
if @maxdepth &&
|
|
270
|
-
if
|
|
271
|
-
|
|
272
|
-
paths << file
|
|
273
|
-
end
|
|
262
|
+
if @maxdepth && depth > @maxdepth
|
|
263
|
+
if stat_info.directory? && !paths.include?(file)
|
|
264
|
+
queue << file
|
|
274
265
|
end
|
|
275
|
-
|
|
276
266
|
next
|
|
277
267
|
end
|
|
278
268
|
|
|
279
|
-
if @mindepth &&
|
|
280
|
-
if
|
|
281
|
-
|
|
282
|
-
paths << file
|
|
283
|
-
end
|
|
269
|
+
if @mindepth && depth < @mindepth
|
|
270
|
+
if stat_info.directory? && !paths.include?(file)
|
|
271
|
+
queue << file
|
|
284
272
|
end
|
|
285
|
-
|
|
286
273
|
next
|
|
287
274
|
end
|
|
288
275
|
end
|
|
@@ -290,50 +277,24 @@ class File::Find
|
|
|
290
277
|
# Add directories back onto the list of paths to search unless
|
|
291
278
|
# they've already been added
|
|
292
279
|
#
|
|
293
|
-
if stat_info.directory?
|
|
294
|
-
|
|
280
|
+
if stat_info.directory? && !paths.include?(file)
|
|
281
|
+
queue << file
|
|
295
282
|
end
|
|
296
283
|
|
|
297
|
-
next unless
|
|
298
|
-
|
|
299
|
-
unless @filetest.empty?
|
|
300
|
-
file_test = true
|
|
284
|
+
next unless File.fnmatch?(@name, File.basename(file))
|
|
301
285
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
bool = array[1]
|
|
305
|
-
|
|
306
|
-
unless File.send(meth, file) == bool
|
|
307
|
-
file_test = false
|
|
308
|
-
break
|
|
309
|
-
end
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
next unless file_test
|
|
286
|
+
if !@filetest.empty? && !@filetest.all? { |meth, bool| File.send(meth, file) == bool }
|
|
287
|
+
next
|
|
313
288
|
end
|
|
314
289
|
|
|
315
290
|
if @atime || @ctime || @mtime
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
if @
|
|
319
|
-
|
|
320
|
-
next unless (date1 - date2).numerator == @atime
|
|
321
|
-
end
|
|
322
|
-
|
|
323
|
-
if @ctime
|
|
324
|
-
date2 = Date.parse(stat_info.ctime.to_s)
|
|
325
|
-
next unless (date1 - date2).numerator == @ctime
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
if @mtime
|
|
329
|
-
date2 = Date.parse(stat_info.mtime.to_s)
|
|
330
|
-
next unless (date1 - date2).numerator == @mtime
|
|
331
|
-
end
|
|
291
|
+
now = Date.today
|
|
292
|
+
next if @atime && (now - stat_info.atime.to_date).to_i != @atime
|
|
293
|
+
next if @ctime && (now - stat_info.ctime.to_date).to_i != @ctime
|
|
294
|
+
next if @mtime && (now - stat_info.mtime.to_date).to_i != @mtime
|
|
332
295
|
end
|
|
333
296
|
|
|
334
|
-
if @ftype
|
|
335
|
-
next unless File.ftype(file) == @ftype
|
|
336
|
-
end
|
|
297
|
+
next if @ftype && stat_info.ftype != @ftype
|
|
337
298
|
|
|
338
299
|
if @group
|
|
339
300
|
if @group.is_a?(String)
|
|
@@ -355,8 +316,8 @@ class File::Find
|
|
|
355
316
|
end
|
|
356
317
|
end
|
|
357
318
|
|
|
358
|
-
if @inum
|
|
359
|
-
next
|
|
319
|
+
if @inum && stat_info.ino != @inum
|
|
320
|
+
next
|
|
360
321
|
end
|
|
361
322
|
|
|
362
323
|
# Note that only 0644 and 0444 are supported on MS Windows.
|
|
@@ -365,7 +326,7 @@ class File::Find
|
|
|
365
326
|
octal_perm = sym2oct(@perm)
|
|
366
327
|
next unless stat_info.mode & octal_perm == octal_perm
|
|
367
328
|
else
|
|
368
|
-
next unless
|
|
329
|
+
next unless format('%o', stat_info.mode & 07777) == format('%o', @perm)
|
|
369
330
|
end
|
|
370
331
|
end
|
|
371
332
|
|
|
@@ -415,11 +376,12 @@ class File::Find
|
|
|
415
376
|
end
|
|
416
377
|
|
|
417
378
|
@previous = file unless @previous == file
|
|
418
|
-
|
|
379
|
+
end
|
|
419
380
|
rescue Errno::EACCES
|
|
420
381
|
next # Skip inaccessible directories
|
|
421
382
|
end
|
|
422
|
-
|
|
383
|
+
end
|
|
384
|
+
# rubocop:enable Metrics/BlockLength
|
|
423
385
|
|
|
424
386
|
block_given? ? nil : results
|
|
425
387
|
end
|
|
@@ -476,17 +438,17 @@ class File::Find
|
|
|
476
438
|
match = cmd.match(regex)
|
|
477
439
|
raise "Invalid symbolic permissions: '#{str}'" if match.nil?
|
|
478
440
|
|
|
479
|
-
who, what, how = match.to_a[1
|
|
441
|
+
who, what, how = match.to_a[1..]
|
|
480
442
|
|
|
481
|
-
who = who.
|
|
482
|
-
how = how.
|
|
443
|
+
who = who.chars.inject(0){ |num, b| num | left[b] }
|
|
444
|
+
how = how.chars.inject(0){ |num, b| num | right[b] }
|
|
483
445
|
mask = who & how
|
|
484
446
|
|
|
485
447
|
case what
|
|
486
448
|
when '+'
|
|
487
|
-
perm
|
|
449
|
+
perm |= mask
|
|
488
450
|
when '-'
|
|
489
|
-
perm
|
|
451
|
+
perm &= ~mask
|
|
490
452
|
when '='
|
|
491
453
|
perm = mask
|
|
492
454
|
end
|
data/lib/file-find.rb
CHANGED