file-find 0.3.2-universal-java-1.5 → 0.3.3-universal-java-1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +11 -2
- data/README +1 -1
- data/test/test_file_find.rb +55 -39
- metadata +12 -9
- 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
@@ -5,17 +5,15 @@ homepage: http://www.rubyforge.org/projects/shards
|
|
5
5
|
executables: []
|
6
6
|
|
7
7
|
version: !ruby/object:Gem::Version
|
8
|
-
version: 0.3.
|
8
|
+
version: 0.3.3
|
9
9
|
post_install_message:
|
10
|
-
date: 2009-
|
10
|
+
date: 2009-08-03 06:00:00 +00:00
|
11
11
|
files:
|
12
|
-
- lib/file
|
13
|
-
- lib/file/find.rb
|
14
12
|
- test/test_file_find.rb
|
15
13
|
- README
|
16
14
|
- CHANGES
|
17
15
|
- MANIFEST
|
18
|
-
rubygems_version: 1.3.
|
16
|
+
rubygems_version: 1.3.3
|
19
17
|
rdoc_options: []
|
20
18
|
|
21
19
|
signing_key:
|
@@ -27,6 +25,8 @@ platform: universal-java-1.5
|
|
27
25
|
summary: A better way to find files
|
28
26
|
default_executable:
|
29
27
|
bindir: bin
|
28
|
+
licenses:
|
29
|
+
- Artistic 2.0
|
30
30
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
31
31
|
version:
|
32
32
|
requirements:
|
@@ -41,12 +41,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
41
41
|
version: "0"
|
42
42
|
require_paths:
|
43
43
|
- lib
|
44
|
-
specification_version:
|
44
|
+
specification_version: 3
|
45
45
|
test_files:
|
46
46
|
- test/test_file_find.rb
|
47
47
|
dependencies:
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
|
-
type: :
|
49
|
+
type: :development
|
50
50
|
name: test-unit
|
51
51
|
version_requirement:
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -54,8 +54,11 @@ dependencies:
|
|
54
54
|
requirements:
|
55
55
|
- - '>='
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
version: 2.0.
|
58
|
-
description:
|
57
|
+
version: 2.0.3
|
58
|
+
description: " The file-find library provides a better, more object oriented \
|
59
|
+
approach\n to finding files. It allows you to find files based on a variety \
|
60
|
+
of\n properties, such as access time, size, owner, etc. You can also limit\n\
|
61
|
+
\ directory depth.\n"
|
59
62
|
email: djberg96@gmail.com
|
60
63
|
authors:
|
61
64
|
- Daniel Berger
|
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
|