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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f6a005f38ff57e7ecba774576e6d8d8c005a386b50ec65197c4047cdd156d876
4
- data.tar.gz: 50c000e4e15dd13bdab23fc396d0062ccc5392efd808036cc3df0a512f6ced50
3
+ metadata.gz: 0febb67274c45e862fa242e53bda0d97895817bf6ff98fd055f769afaa5d0e60
4
+ data.tar.gz: 20a42458a0f3b70e7bdffc6afd446be9b70e7417197ebbd3e4c9c1302d473559
5
5
  SHA512:
6
- metadata.gz: '09d5c030c2312a89f03c21a69578ab08d437890151f943f37ebcf27cd62d51fb42694f833605207afbf8c2e6aeb2a7d852f9373a6bc251b5336d0933b6a0f082'
7
- data.tar.gz: c2c7b029ba2fdf2ea2760e84ee5600ef5fa1670922d01924773688854edb9a7e2eee6b32581c25861ff5095c984c53ec86ffa54e7f4b71a3fda73d7dca732a26
6
+ metadata.gz: 51cabd736d8aeb6c35cd1e7bb38de0ee4ccd96a79ccbe0b9a08a657e69d0d9250afc1e7680986721de5cd33f20ff459bd3afbff9e47c0960d4b47b666a02bc00
7
+ data.tar.gz: 6ec15535aa08d5f78f81decbf7678f0c05f6ebd8978b5bb3eaef83c3fa315ed6414d696458008d1d2832bb3413747a0a21a0882f56019602064f859a8a82d0d4
checksums.yaml.gz.sig CHANGED
@@ -1,2 +1,3 @@
1
- �U�w�!W�A����� �I�K�(�kG�/�5С��[4yeW��}��,Va�a=�@�0�����\�yU%,��$��f_HA��c�ʣ��u� nu7��.��M���4{�@��{ed/�3��D�r�iq�b�f�X+�����^�� �����e���e���,��'�a�c��yU�a�(�g�e���2#���!B�d�F��vr�����Fod�~�˜��܇C ,�DJjAW�]��,w�|�s�ֶHf'����+x�_ݼX���Ҷ��h�
2
- )fY_C 4��#a���a'|%*�CiimuƄhz
1
+ ����8�۵��
2
+ x'�^g ��V�t/��oT���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' do
2
- gemspec
3
- end
1
+ source 'https://rubygems.org'
2
+ gemspec
data/MANIFEST.md CHANGED
@@ -8,4 +8,4 @@
8
8
  * certs/djberg96_pub.pem
9
9
  * lib/file-find.rb
10
10
  * lib/file/find.rb
11
- * test/test_file_find.rb
11
+ * spec/file_find_spec.rb
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Ruby](https://github.com/djberg96/file-find/actions/workflows/ruby.yml/badge.svg)](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-2021, Daniel J. Berger, All Rights Reserved
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 = eval(IO.read('file-find.gemspec'))
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, true)
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.0'
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' => '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/master/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'
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', '~> 1.3')
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.0'.freeze
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 Dir.glob are legal here. The default is '*', i.e. everything.
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.is_a?(String) ? [@path] : @path # Ruby 1.9.x compatibility
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
- paths.each{ |path|
224
+ # rubocop:disable Metrics/BlockLength
225
+ until queue.empty?
226
+ path = queue.shift
220
227
  begin
221
- Dir.foreach(path){ |file|
228
+ Dir.foreach(path) do |file|
222
229
  next if file == '.'
223
230
  next if file == '..'
224
231
 
225
- if prune_regex
226
- next if prune_regex.match(file)
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
- # We need to escape any brackets in the directory name, unless already escaped.
245
- temp = File.dirname(file).gsub(/(?<!\\)([\[\]])/, '\\\\\1')
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{ |e| e.size.zero? }.length
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 && (depth > @maxdepth)
270
- if File.directory?(file)
271
- unless paths.include?(file) && depth > @maxdepth
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 && (depth < @mindepth)
280
- if File.directory?(file)
281
- unless paths.include?(file) && depth < @mindepth
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
- paths << file unless paths.include?(file)
280
+ if stat_info.directory? && !paths.include?(file)
281
+ queue << file
295
282
  end
296
283
 
297
- next unless Dir[glob].include?(file)
298
-
299
- unless @filetest.empty?
300
- file_test = true
284
+ next unless File.fnmatch?(@name, File.basename(file))
301
285
 
302
- @filetest.each{ |array|
303
- meth = array[0]
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
- date1 = Date.parse(Time.now.to_s)
317
-
318
- if @atime
319
- date2 = Date.parse(stat_info.atime.to_s)
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 unless stat_info.ino == @inum
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 sprintf("%o", stat_info.mode & 07777) == sprintf("%o", @perm)
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..-1]
441
+ who, what, how = match.to_a[1..]
480
442
 
481
- who = who.split(//).inject(0){ |num,b| num |= left[b]; num }
482
- how = how.split(//).inject(0){ |num,b| num |= right[b]; num }
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 = perm | mask
449
+ perm |= mask
488
450
  when '-'
489
- perm = perm & ~mask
451
+ perm &= ~mask
490
452
  when '='
491
453
  perm = mask
492
454
  end
data/lib/file-find.rb CHANGED
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'file/find'