file-find 0.3.2 → 0.3.3
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.
- data/CHANGES +11 -2
- data/README +1 -1
- data/test/test_file_find.rb +55 -39
- metadata +8 -10
- data/lib/file/find.rb +0 -487
data/CHANGES
CHANGED
@@ -1,8 +1,17 @@
|
|
1
|
-
== 0.3.
|
1
|
+
== 0.3.3 - 3-Aug-2009
|
2
|
+
* Now compatible with Ruby 1.9.x.
|
3
|
+
* Added support for the :links option
|
4
|
+
* Updated the :mount accessor to work properly if the value is changed
|
5
|
+
after the File::Find object is initially created.
|
6
|
+
* Eliminated some 'shadowed variable' warnings in Ruby 1.9.x.
|
7
|
+
* Added a fuller description to the gemspec.
|
8
|
+
* Minor test refactoring.
|
9
|
+
|
10
|
+
== 0.3.2 - 20-Feb-2009
|
2
11
|
* Added support for the :mount option.
|
3
12
|
* Added some basic tests for the :mount option.
|
4
13
|
|
5
|
-
== 0.3.1 - 9-Jan-
|
14
|
+
== 0.3.1 - 9-Jan-2009
|
6
15
|
* Now defaults to using Etc instead of Sys::Admin for implementations
|
7
16
|
that don't support building C extensions, e.g. JRuby.
|
8
17
|
* Updated the test suite to work with JRuby.
|
data/README
CHANGED
data/test/test_file_find.rb
CHANGED
@@ -23,7 +23,7 @@ include FileUtils
|
|
23
23
|
|
24
24
|
class TC_File_Find < Test::Unit::TestCase
|
25
25
|
def self.startup
|
26
|
-
Dir.chdir(
|
26
|
+
Dir.chdir(File.dirname(File.expand_path(__FILE__)))
|
27
27
|
|
28
28
|
@@windows = CONFIG['host_os'] =~ /windows|mswin/i
|
29
29
|
@@jruby = RUBY_PLATFORM.match('java')
|
@@ -40,35 +40,35 @@ class TC_File_Find < Test::Unit::TestCase
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def setup
|
43
|
-
@
|
44
|
-
@
|
45
|
-
@
|
46
|
-
@
|
47
|
-
@
|
48
|
-
@
|
49
|
-
|
50
|
-
File.open(@
|
51
|
-
File.open(@
|
52
|
-
File.open(@
|
53
|
-
File.open(@
|
43
|
+
@file_rb = 'test1.rb'
|
44
|
+
@file_txt1 = 'test1.txt'
|
45
|
+
@file_txt2 = 'foo.txt'
|
46
|
+
@file_doc = 'foo.doc'
|
47
|
+
@directory1 = 'dir1'
|
48
|
+
@directory2 = 'dir2'
|
49
|
+
|
50
|
+
File.open(@file_rb, 'w'){}
|
51
|
+
File.open(@file_txt1, 'w'){}
|
52
|
+
File.open(@file_txt2, 'w'){}
|
53
|
+
File.open(@file_doc, 'w'){}
|
54
54
|
|
55
55
|
unless @@windows
|
56
56
|
@link1 = 'link1'
|
57
|
-
File.symlink(@
|
57
|
+
File.symlink(@file_rb, @link1)
|
58
58
|
end
|
59
59
|
|
60
|
-
Dir.mkdir(@
|
61
|
-
Dir.mkdir(@
|
60
|
+
Dir.mkdir(@directory1) unless File.exists?(@directory1)
|
61
|
+
Dir.mkdir(@directory2) unless File.exists?(@directory2)
|
62
62
|
|
63
|
-
File.open(File.join(@
|
64
|
-
File.open(File.join(@
|
63
|
+
File.open(File.join(@directory1, 'bar.txt'), 'w'){}
|
64
|
+
File.open(File.join(@directory2, 'baz.txt'), 'w'){}
|
65
65
|
|
66
66
|
@rule1 = File::Find.new(:name => '*.txt')
|
67
67
|
@rule2 = File::Find.new
|
68
68
|
end
|
69
69
|
|
70
70
|
def test_version
|
71
|
-
assert_equal('0.3.
|
71
|
+
assert_equal('0.3.3', File::Find::VERSION)
|
72
72
|
end
|
73
73
|
|
74
74
|
def test_path
|
@@ -137,11 +137,11 @@ class TC_File_Find < Test::Unit::TestCase
|
|
137
137
|
omit_if(@@windows && @@jruby, "Skipping file test on JRuby/Windows")
|
138
138
|
|
139
139
|
rule = File::Find.new(:name => "*.doc", :writable? => true)
|
140
|
-
File.chmod(0644, @
|
140
|
+
File.chmod(0644, @file_doc)
|
141
141
|
|
142
|
-
assert_equal([@
|
142
|
+
assert_equal([@file_doc], rule.find.map{ |f| File.basename(f) })
|
143
143
|
|
144
|
-
File.chmod(0444, @
|
144
|
+
File.chmod(0444, @file_doc)
|
145
145
|
|
146
146
|
assert_equal([], rule.find)
|
147
147
|
end
|
@@ -183,13 +183,13 @@ class TC_File_Find < Test::Unit::TestCase
|
|
183
183
|
def test_group_with_numeric_id
|
184
184
|
omit_if(@@windows, 'group test skipped on MS Windows')
|
185
185
|
@rule1 = File::Find.new(:name => '*.doc', :group => @@loguser.gid)
|
186
|
-
assert_equal([File.expand_path(@
|
186
|
+
assert_equal([File.expand_path(@file_doc)], @rule1.find)
|
187
187
|
end
|
188
188
|
|
189
189
|
def test_group_with_string
|
190
190
|
omit_if(@@windows, 'group test skipped on MS Windows')
|
191
191
|
@rule1 = File::Find.new(:name => '*.doc', :group => @@logroup.name)
|
192
|
-
assert_equal([File.expand_path(@
|
192
|
+
assert_equal([File.expand_path(@file_doc)], @rule1.find)
|
193
193
|
end
|
194
194
|
|
195
195
|
def test_group_with_bad_id
|
@@ -212,6 +212,22 @@ class TC_File_Find < Test::Unit::TestCase
|
|
212
212
|
assert_true(@rule1.follow)
|
213
213
|
end
|
214
214
|
|
215
|
+
def test_links_basic
|
216
|
+
assert_respond_to(@rule1, :links)
|
217
|
+
assert_respond_to(@rule1, :links=)
|
218
|
+
assert_nil(@rule1.links)
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_links
|
222
|
+
omit_if(@@windows, 'links test skipped on MS Windows')
|
223
|
+
|
224
|
+
@rule1 = File::Find.new(:name => '*.rb', :links => 2)
|
225
|
+
@rule2 = File::Find.new(:name => '*.doc', :links => 1)
|
226
|
+
|
227
|
+
assert_equal([], @rule1.find)
|
228
|
+
assert_equal([File.expand_path(@file_doc)], @rule2.find)
|
229
|
+
end
|
230
|
+
|
215
231
|
def test_maxdepth_basic
|
216
232
|
assert_respond_to(@rule1, :maxdepth)
|
217
233
|
assert_respond_to(@rule1, :maxdepth=)
|
@@ -333,8 +349,8 @@ class TC_File_Find < Test::Unit::TestCase
|
|
333
349
|
|
334
350
|
def test_perm
|
335
351
|
omit_if(@@windows, 'perm test skipped on MS Windows')
|
336
|
-
File.chmod(0664, @
|
337
|
-
File.chmod(0644, @
|
352
|
+
File.chmod(0664, @file_rb)
|
353
|
+
File.chmod(0644, @file_txt1)
|
338
354
|
results = File::Find.new(:name => "test1*", :perm => 664).find
|
339
355
|
|
340
356
|
assert_equal(1, results.length)
|
@@ -344,8 +360,8 @@ class TC_File_Find < Test::Unit::TestCase
|
|
344
360
|
def test_perm_with_symbolic_permissions
|
345
361
|
omit_if(@@windows, 'symbolic perm test skipped on MS Windows')
|
346
362
|
|
347
|
-
File.chmod(0664, @
|
348
|
-
File.chmod(0644, @
|
363
|
+
File.chmod(0664, @file_rb) # test1.rb
|
364
|
+
File.chmod(0644, @file_txt1) # test1.txt
|
349
365
|
results1 = File::Find.new(:name => "test1*", :perm => "g=rw").find
|
350
366
|
results2 = File::Find.new(:name => "test1*", :perm => "u=rw").find
|
351
367
|
|
@@ -381,13 +397,13 @@ class TC_File_Find < Test::Unit::TestCase
|
|
381
397
|
def test_user_with_numeric_id
|
382
398
|
omit_if(@@windows, 'user test skipped on MS Windows')
|
383
399
|
@rule1 = File::Find.new(:name => '*.doc', :user => @@loguser.uid)
|
384
|
-
assert_equal([File.expand_path(@
|
400
|
+
assert_equal([File.expand_path(@file_doc)], @rule1.find)
|
385
401
|
end
|
386
402
|
|
387
403
|
def test_user_with_string
|
388
404
|
omit_if(@@windows, 'user test skipped on MS Windows')
|
389
405
|
@rule1 = File::Find.new(:name => '*.doc', :user => @@loguser.name)
|
390
|
-
assert_equal([File.expand_path(@
|
406
|
+
assert_equal([File.expand_path(@file_doc)], @rule1.find)
|
391
407
|
end
|
392
408
|
|
393
409
|
def test_user_with_bad_id
|
@@ -409,12 +425,12 @@ class TC_File_Find < Test::Unit::TestCase
|
|
409
425
|
end
|
410
426
|
|
411
427
|
def teardown
|
412
|
-
rm_rf(@
|
413
|
-
rm_rf(@
|
414
|
-
rm_rf(@
|
415
|
-
rm_rf(@
|
416
|
-
rm_rf(@
|
417
|
-
rm_rf(@
|
428
|
+
rm_rf(@file_rb)
|
429
|
+
rm_rf(@file_txt1)
|
430
|
+
rm_rf(@file_txt2)
|
431
|
+
rm_rf(@file_doc)
|
432
|
+
rm_rf(@directory1)
|
433
|
+
rm_rf(@directory2)
|
418
434
|
rm_rf(@link1) unless @@windows
|
419
435
|
rm_rf('a')
|
420
436
|
rm_rf('a1')
|
@@ -422,10 +438,10 @@ class TC_File_Find < Test::Unit::TestCase
|
|
422
438
|
|
423
439
|
@rule1 = nil
|
424
440
|
@rule2 = nil
|
425
|
-
@
|
426
|
-
@
|
427
|
-
@
|
428
|
-
@
|
441
|
+
@file_rb = nil
|
442
|
+
@file_txt1 = nil
|
443
|
+
@file_txt2 = nil
|
444
|
+
@file_doc = nil
|
429
445
|
end
|
430
446
|
|
431
447
|
def self.shutdown
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: file-find
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Berger
|
@@ -9,18 +9,18 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-08-03 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: test-unit
|
17
|
-
type: :
|
17
|
+
type: :development
|
18
18
|
version_requirement:
|
19
19
|
version_requirements: !ruby/object:Gem::Requirement
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 2.0.
|
23
|
+
version: 2.0.3
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: sys-admin
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 1.4.4
|
34
34
|
version:
|
35
|
-
description:
|
35
|
+
description: " The file-find library provides a better, more object oriented approach\n to finding files. It allows you to find files based on a variety of\n properties, such as access time, size, owner, etc. You can also limit\n directory depth.\n"
|
36
36
|
email: djberg96@gmail.com
|
37
37
|
executables: []
|
38
38
|
|
@@ -43,16 +43,14 @@ extra_rdoc_files:
|
|
43
43
|
- CHANGES
|
44
44
|
- MANIFEST
|
45
45
|
files:
|
46
|
-
- lib/file
|
47
|
-
- lib/file/find.rb
|
48
46
|
- test/test_file_find.rb
|
49
47
|
- README
|
50
48
|
- CHANGES
|
51
49
|
- MANIFEST
|
52
50
|
has_rdoc: true
|
53
51
|
homepage: http://www.rubyforge.org/projects/shards
|
54
|
-
licenses:
|
55
|
-
|
52
|
+
licenses:
|
53
|
+
- Artistic 2.0
|
56
54
|
post_install_message:
|
57
55
|
rdoc_options: []
|
58
56
|
|
@@ -73,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
71
|
requirements: []
|
74
72
|
|
75
73
|
rubyforge_project: shards
|
76
|
-
rubygems_version: 1.3.
|
74
|
+
rubygems_version: 1.3.5
|
77
75
|
signing_key:
|
78
76
|
specification_version: 3
|
79
77
|
summary: A better way to find files
|
data/lib/file/find.rb
DELETED
@@ -1,487 +0,0 @@
|
|
1
|
-
require 'date'
|
2
|
-
require 'rbconfig'
|
3
|
-
|
4
|
-
# For alternate implementations of Ruby, such as JRuby, that cannot
|
5
|
-
# build C extensions fall back to the Etc module.
|
6
|
-
begin
|
7
|
-
require 'sys/admin'
|
8
|
-
rescue LoadError
|
9
|
-
require 'etc'
|
10
|
-
end
|
11
|
-
|
12
|
-
class File::Find
|
13
|
-
# The version of this library
|
14
|
-
VERSION = '0.3.2'
|
15
|
-
|
16
|
-
# :stopdoc:
|
17
|
-
VALID_OPTIONS = %w/
|
18
|
-
atime
|
19
|
-
ctime
|
20
|
-
follow
|
21
|
-
ftype
|
22
|
-
inum
|
23
|
-
group
|
24
|
-
maxdepth
|
25
|
-
mindepth
|
26
|
-
mount
|
27
|
-
mtime
|
28
|
-
name
|
29
|
-
pattern
|
30
|
-
path
|
31
|
-
perm
|
32
|
-
prune
|
33
|
-
size
|
34
|
-
user
|
35
|
-
/
|
36
|
-
# :startdoc:
|
37
|
-
|
38
|
-
# The starting path(s) for the search. The default is the current directory.
|
39
|
-
# This can be a single path or an array of paths.
|
40
|
-
#
|
41
|
-
attr_accessor :path
|
42
|
-
|
43
|
-
# The list of options passed to the constructor and/or used by the
|
44
|
-
# File::Find#find method.
|
45
|
-
#
|
46
|
-
attr_accessor :options
|
47
|
-
|
48
|
-
# Limits searches by file access time, where the value you supply is the
|
49
|
-
# number of days back from the time that the File::Find#find method was
|
50
|
-
# called.
|
51
|
-
#
|
52
|
-
attr_accessor :atime
|
53
|
-
|
54
|
-
# Limits searches by file change time, where the value you supply is the
|
55
|
-
# number of days back from the time that the File::Find#find method was
|
56
|
-
# called.
|
57
|
-
#
|
58
|
-
attr_accessor :ctime
|
59
|
-
|
60
|
-
# Limits searches to files that belong to a specific group, where the
|
61
|
-
# group can be either a group name or ID.
|
62
|
-
#
|
63
|
-
# Not currently supported on MS Windows.
|
64
|
-
#
|
65
|
-
attr_accessor :group
|
66
|
-
|
67
|
-
# An array of two element arrays for storing FileTest methods and their
|
68
|
-
# boolean value.
|
69
|
-
#
|
70
|
-
attr_accessor :filetest
|
71
|
-
|
72
|
-
# Controls the behavior of how symlinks are followed. If set to true (the
|
73
|
-
# default), then follows the file pointed to. If false, it considers the
|
74
|
-
# symlink itself.
|
75
|
-
#
|
76
|
-
attr_accessor :follow
|
77
|
-
|
78
|
-
# Limits searches to specific types of files. The possible values here are
|
79
|
-
# those returned by the File.ftype method.
|
80
|
-
#
|
81
|
-
attr_accessor :ftype
|
82
|
-
|
83
|
-
# Limits search to a file with a specific inode number. Ignored on MS
|
84
|
-
# Windows.
|
85
|
-
#
|
86
|
-
attr_accessor :inum
|
87
|
-
|
88
|
-
# Limits search to a maximum depth into the tree relative to the starting
|
89
|
-
# search directory.
|
90
|
-
#
|
91
|
-
attr_accessor :maxdepth
|
92
|
-
|
93
|
-
# Limits searches to a minimum depth into the tree relative to the starting
|
94
|
-
# search directory.
|
95
|
-
#
|
96
|
-
attr_accessor :mindepth
|
97
|
-
|
98
|
-
# Limits searches to the same filesystem as the specified directory. For
|
99
|
-
# Windows users, this refers to the volume.
|
100
|
-
#
|
101
|
-
attr_accessor :mount
|
102
|
-
|
103
|
-
# Limits searches by file modification time, where the value you supply is
|
104
|
-
# the number of days back from the time that the File::Find#find method was
|
105
|
-
# called.
|
106
|
-
#
|
107
|
-
attr_accessor :mtime
|
108
|
-
|
109
|
-
# 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.
|
111
|
-
#
|
112
|
-
attr_accessor :name
|
113
|
-
|
114
|
-
# Limits searches to files which have permissions that match the octal
|
115
|
-
# value that you provide. For purposes of this comparison, only the user,
|
116
|
-
# group, and world settings are used. Do not use a leading 0 in the values
|
117
|
-
# that you supply, e.g. use 755 not 0755.
|
118
|
-
#
|
119
|
-
# You may optionally use symbolic permissions, e.g. "g+rw", "u=rwx", etc.
|
120
|
-
#
|
121
|
-
# Not currently supported on MS Windows.
|
122
|
-
#
|
123
|
-
attr_accessor :perm
|
124
|
-
|
125
|
-
# Skips files or directories that match the string provided as an argument.
|
126
|
-
#
|
127
|
-
attr_accessor :prune
|
128
|
-
|
129
|
-
# If the value passed is an integer, this option limits searches to files
|
130
|
-
# that match the size, in bytes, exactly. If a string is passed, you can
|
131
|
-
# use the standard comparable operators to match files, e.g. ">= 200" would
|
132
|
-
# limit searches to files greater than or equal to 200 bytes.
|
133
|
-
#
|
134
|
-
attr_accessor :size
|
135
|
-
|
136
|
-
# Limits searches to files that belong to a specific user, where the user
|
137
|
-
# can be either a user name or an ID.
|
138
|
-
#
|
139
|
-
# Not currently supported on MS Windows.
|
140
|
-
#
|
141
|
-
attr_accessor :user
|
142
|
-
|
143
|
-
# The file that matched previously in the current search.
|
144
|
-
#
|
145
|
-
attr_reader :previous
|
146
|
-
|
147
|
-
alias pattern name
|
148
|
-
alias pattern= name=
|
149
|
-
|
150
|
-
# Creates and returns a new File::Find object. The options set for this
|
151
|
-
# object serve as the rules for determining what files the File::Find#find
|
152
|
-
# method will search for.
|
153
|
-
#
|
154
|
-
# In addition to the standard list of valid options, you may also use
|
155
|
-
# FileTest methods as options, setting their value to true or false.
|
156
|
-
#
|
157
|
-
# Example:
|
158
|
-
#
|
159
|
-
# rule = File::Find.new(
|
160
|
-
# :name => "*.rb",
|
161
|
-
# :follow => false,
|
162
|
-
# :path => ['/usr/local/lib', '/opt/local/lib'],
|
163
|
-
# :readable? => true
|
164
|
-
# )
|
165
|
-
#
|
166
|
-
def initialize(options = {})
|
167
|
-
@options = options
|
168
|
-
|
169
|
-
@atime = nil
|
170
|
-
@ctime = nil
|
171
|
-
@ftype = nil
|
172
|
-
@group = nil
|
173
|
-
@follow = true
|
174
|
-
@inum = nil
|
175
|
-
@mount = nil
|
176
|
-
@mtime = nil
|
177
|
-
@perm = nil
|
178
|
-
@prune = nil
|
179
|
-
@size = nil
|
180
|
-
@user = nil
|
181
|
-
|
182
|
-
@previous = nil
|
183
|
-
@maxdepth = nil
|
184
|
-
@mindepth = nil
|
185
|
-
@filetest = []
|
186
|
-
|
187
|
-
validate_and_set_options(options) unless options.empty?
|
188
|
-
|
189
|
-
@filesystem = File.stat(@mount).dev if @mount
|
190
|
-
|
191
|
-
@path ||= Dir.pwd
|
192
|
-
@name ||= '*'
|
193
|
-
end
|
194
|
-
|
195
|
-
# Executes the find based on the rules you set for the File::Find object.
|
196
|
-
# In block form, yields each file in turn that matches the specified rules.
|
197
|
-
# In non-block form it will return an array of matches instead.
|
198
|
-
#
|
199
|
-
# Example:
|
200
|
-
#
|
201
|
-
# rule = File::Find.new(
|
202
|
-
# :name => "*.rb",
|
203
|
-
# :follow => false,
|
204
|
-
# :path => ['/usr/local/lib', '/opt/local/lib']
|
205
|
-
# )
|
206
|
-
#
|
207
|
-
# rule.find{ |f|
|
208
|
-
# puts f
|
209
|
-
# }
|
210
|
-
#
|
211
|
-
def find
|
212
|
-
results = [] unless block_given?
|
213
|
-
paths = @path.to_a
|
214
|
-
|
215
|
-
if @prune
|
216
|
-
prune_regex = Regexp.new(@prune)
|
217
|
-
else
|
218
|
-
prune_regex = nil
|
219
|
-
end
|
220
|
-
|
221
|
-
paths.each{ |path|
|
222
|
-
begin
|
223
|
-
Dir.foreach(path){ |file|
|
224
|
-
next if file == '.'
|
225
|
-
next if file == '..'
|
226
|
-
|
227
|
-
if prune_regex
|
228
|
-
next if prune_regex.match(file)
|
229
|
-
end
|
230
|
-
|
231
|
-
orig = file.dup
|
232
|
-
file = File.join(path, file)
|
233
|
-
|
234
|
-
stat_method = @follow ? :lstat : :stat
|
235
|
-
|
236
|
-
# Skip files we cannot access, stale links, etc.
|
237
|
-
begin
|
238
|
-
stat_info = File.send(stat_method, file)
|
239
|
-
rescue Errno::ENOENT, Errno::EACCES
|
240
|
-
next
|
241
|
-
rescue Errno::ELOOP
|
242
|
-
stat_method = :lstat # Handle recursive symlinks
|
243
|
-
retry if stat_method.to_s != 'lstat'
|
244
|
-
end
|
245
|
-
|
246
|
-
glob = File.join(File.dirname(file), @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 @maxdepth || @mindepth
|
259
|
-
file_depth = file.split(File::SEPARATOR).length
|
260
|
-
path_depth = @path.split(File::SEPARATOR).length
|
261
|
-
depth = file_depth - path_depth
|
262
|
-
|
263
|
-
if @maxdepth && (depth > @maxdepth)
|
264
|
-
if File.directory?(file)
|
265
|
-
unless paths.include?(file) && depth > @maxdepth
|
266
|
-
paths << file
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
next
|
271
|
-
end
|
272
|
-
|
273
|
-
if @mindepth && (depth < @mindepth)
|
274
|
-
if File.directory?(file)
|
275
|
-
unless paths.include?(file) && depth < @mindepth
|
276
|
-
paths << file
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
next
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
# Add directories back onto the list of paths to search unless
|
285
|
-
# they've already been added
|
286
|
-
#
|
287
|
-
if stat_info.directory?
|
288
|
-
paths << file unless paths.include?(file)
|
289
|
-
end
|
290
|
-
|
291
|
-
next unless Dir[glob].include?(file)
|
292
|
-
|
293
|
-
unless @filetest.empty?
|
294
|
-
file_test = true
|
295
|
-
|
296
|
-
@filetest.each{ |array|
|
297
|
-
meth = array[0]
|
298
|
-
bool = array[1]
|
299
|
-
|
300
|
-
unless File.send(meth, file) == bool
|
301
|
-
file_test = false
|
302
|
-
break
|
303
|
-
end
|
304
|
-
}
|
305
|
-
|
306
|
-
next unless file_test
|
307
|
-
end
|
308
|
-
|
309
|
-
if @atime || @ctime || @mtime
|
310
|
-
date1 = Date.parse(Time.now.to_s)
|
311
|
-
|
312
|
-
if @atime
|
313
|
-
date2 = Date.parse(stat_info.atime.to_s)
|
314
|
-
next unless (date1 - date2).numerator == @atime
|
315
|
-
end
|
316
|
-
|
317
|
-
if @ctime
|
318
|
-
date2 = Date.parse(stat_info.ctime.to_s)
|
319
|
-
next unless (date1 - date2).numerator == @ctime
|
320
|
-
end
|
321
|
-
|
322
|
-
if @mtime
|
323
|
-
date2 = Date.parse(stat_info.mtime.to_s)
|
324
|
-
next unless (date1 - date2).numerator == @mtime
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
if @ftype
|
329
|
-
next unless File.ftype(file) == @ftype
|
330
|
-
end
|
331
|
-
|
332
|
-
if @group
|
333
|
-
if @group.is_a?(String)
|
334
|
-
next unless get_group(stat_info.gid).name == @group
|
335
|
-
else
|
336
|
-
next unless stat_info.gid == @group
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
unless Config::CONFIG['host_os'] =~ /windows|mswin/i
|
341
|
-
if @inum
|
342
|
-
next unless stat_info.ino == @inum
|
343
|
-
end
|
344
|
-
end
|
345
|
-
|
346
|
-
# This currently doesn't work on MS Windows, even in limited
|
347
|
-
# fashion for 0666 and 0664, because File.stat.mode doesn't
|
348
|
-
# return the proper value.
|
349
|
-
#
|
350
|
-
if @perm
|
351
|
-
if @perm.is_a?(String)
|
352
|
-
octal_perm = sym2oct(@perm)
|
353
|
-
next unless stat_info.mode & octal_perm == octal_perm
|
354
|
-
else
|
355
|
-
next unless sprintf("%o", stat_info.mode & 07777) == @perm.to_s
|
356
|
-
end
|
357
|
-
end
|
358
|
-
|
359
|
-
# Allow plain numbers, or strings for comparison operators.
|
360
|
-
if @size
|
361
|
-
if @size.is_a?(String)
|
362
|
-
regex = /^([><=]+)\s*?(\d+)$/
|
363
|
-
match = regex.match(@size)
|
364
|
-
|
365
|
-
if match.nil? || match.captures.include?(nil)
|
366
|
-
raise ArgumentError, "invalid size string: '#{@size}'"
|
367
|
-
end
|
368
|
-
|
369
|
-
operator = match.captures.first.strip
|
370
|
-
number = match.captures.last.strip.to_i
|
371
|
-
|
372
|
-
next unless stat_info.size.send(operator, number)
|
373
|
-
else
|
374
|
-
next unless stat_info.size == @size
|
375
|
-
end
|
376
|
-
end
|
377
|
-
|
378
|
-
if @user
|
379
|
-
if @user.is_a?(String)
|
380
|
-
next unless get_user(stat_info.uid).name == @user
|
381
|
-
else
|
382
|
-
next unless stat_info.uid == @user
|
383
|
-
end
|
384
|
-
end
|
385
|
-
|
386
|
-
if block_given?
|
387
|
-
yield file
|
388
|
-
else
|
389
|
-
results << file
|
390
|
-
end
|
391
|
-
|
392
|
-
@previous = file unless @previous == file
|
393
|
-
}
|
394
|
-
rescue Errno::EACCES
|
395
|
-
next # Skip inaccessible directories
|
396
|
-
end
|
397
|
-
}
|
398
|
-
|
399
|
-
block_given? ? nil : results
|
400
|
-
end
|
401
|
-
|
402
|
-
private
|
403
|
-
|
404
|
-
# This validates that the keys are valid. If they are, it sets the value
|
405
|
-
# of that key's corresponding method to the given value. If a key ends
|
406
|
-
# with a '?', it's validated as a File method.
|
407
|
-
#
|
408
|
-
def validate_and_set_options(options)
|
409
|
-
options.each do |key, value|
|
410
|
-
key = key.to_s.downcase
|
411
|
-
|
412
|
-
if key[-1].chr == '?'
|
413
|
-
sym = key.to_sym
|
414
|
-
|
415
|
-
unless File.respond_to?(sym)
|
416
|
-
raise ArgumentError, "invalid option '#{key}'"
|
417
|
-
end
|
418
|
-
|
419
|
-
@filetest << [sym, value]
|
420
|
-
else
|
421
|
-
unless VALID_OPTIONS.include?(key)
|
422
|
-
raise ArgumentError, "invalid option '#{key}'"
|
423
|
-
end
|
424
|
-
|
425
|
-
send("#{key}=", value)
|
426
|
-
end
|
427
|
-
end
|
428
|
-
end
|
429
|
-
|
430
|
-
# Converts a symoblic permissions mode into its octal equivalent.
|
431
|
-
#--
|
432
|
-
# Taken almost entirely from ruby-talk: 96956 (Hal Fulton).
|
433
|
-
#
|
434
|
-
def sym2oct(str)
|
435
|
-
left = {'u' => 0700, 'g' => 0070, 'o' => 0007, 'a' => 0777}
|
436
|
-
right = {'r' => 0444, 'w' => 0222, 'x' => 0111}
|
437
|
-
regex = /([ugoa]+)([+-=])([rwx]+)/
|
438
|
-
|
439
|
-
cmds = str.split(',')
|
440
|
-
|
441
|
-
perm = 0
|
442
|
-
|
443
|
-
cmds.each do |cmd|
|
444
|
-
match = cmd.match(regex)
|
445
|
-
raise "Invalid symbolic permissions: '#{str}'" if match.nil?
|
446
|
-
|
447
|
-
junk, who, what, how = match.to_a
|
448
|
-
|
449
|
-
who = who.split(//).inject(num=0) { |num,b| num |= left[b]; num }
|
450
|
-
how = how.split(//).inject(num=0) { |num,b| num |= right[b]; num }
|
451
|
-
mask = who & how
|
452
|
-
|
453
|
-
case what
|
454
|
-
when '+'
|
455
|
-
perm = perm | mask
|
456
|
-
when '-'
|
457
|
-
perm = perm & ~mask
|
458
|
-
when '='
|
459
|
-
perm = mask
|
460
|
-
end
|
461
|
-
end
|
462
|
-
|
463
|
-
perm
|
464
|
-
end
|
465
|
-
|
466
|
-
# Returns the group object based on the group id. Implemented for the
|
467
|
-
# sake of platforms that cannot build extensions, such as JRuby.
|
468
|
-
#
|
469
|
-
def get_group(gid)
|
470
|
-
if defined? Sys::Admin
|
471
|
-
Sys::Admin.get_group(gid)
|
472
|
-
else
|
473
|
-
Etc.getgrgid(gid)
|
474
|
-
end
|
475
|
-
end
|
476
|
-
|
477
|
-
# Returns the user object based on the group id. Implemented for the
|
478
|
-
# sake of platforms that cannot build extensions, such as JRuby.
|
479
|
-
#
|
480
|
-
def get_user(uid)
|
481
|
-
if defined? Sys::Admin
|
482
|
-
Sys::Admin.get_user(uid)
|
483
|
-
else
|
484
|
-
Etc.getpwuid(uid)
|
485
|
-
end
|
486
|
-
end
|
487
|
-
end
|