file-find 0.3.1-universal-java-1.5

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.
Files changed (6) hide show
  1. data/CHANGES +53 -0
  2. data/MANIFEST +7 -0
  3. data/README +111 -0
  4. data/lib/file/find.rb +474 -0
  5. data/test/test_file_find.rb +431 -0
  6. metadata +69 -0
data/CHANGES ADDED
@@ -0,0 +1,53 @@
1
+ == 0.3.1 - 9-Jan-2008
2
+ * Now defaults to using Etc instead of Sys::Admin for implementations
3
+ that don't support building C extensions, e.g. JRuby.
4
+ * Updated the test suite to work with JRuby.
5
+ * Minor optimizations for symbolic perms and atime/ctime/mtime checks.
6
+ Thanks go in part to Ryan Davis' flay library.
7
+
8
+ == 0.3.0 - 30-Dec-2008
9
+ * Added support for FileTest operations. All options passed to the constructor
10
+ that end with '?' are now validated and treated as FileTest operations.
11
+
12
+ == 0.2.5 - 29-Dec-2008
13
+ * Added maxdepth and mindepth support.
14
+ * Added a 'clean' rake task to cleanup any test-unit results files.
15
+
16
+ == 0.2.4 - 10-Dec-2008
17
+ * Added support for symbolic permissions. Thanks go to Bill Kleb for the
18
+ suggestion and to Hal Fulton for providing the solution.
19
+
20
+ == 0.2.3 - 25-Nov-2008
21
+ * Added mtime support. My previous concerns, which I believe stemmed from
22
+ the find(2) man page on Solaris 10 with regards to atime checks modifying
23
+ the mtime, appear have been unfounded.
24
+
25
+ == 0.2.2 - 19-Nov-2008
26
+ * The :user and :group options now accept a name or a numeric id. Thanks go
27
+ to Bill Kleb for the suggestion.
28
+ * Fixed yet another path bug for MS Windows.
29
+ * Updated platform check to use CONFIG instead of RUBY_PLATFORM, because the
30
+ latter does not work as I intended with other implementations, e.g. JRuby.
31
+ * Added sys-admin and test-unit as prerequisites.
32
+ * Added tests for the :user and :group options.
33
+
34
+ == 0.2.1 - 4-Oct-2007
35
+ * Added the File::Find#previous method, which lets you see the previous
36
+ match, if any.
37
+ * Path name bug fix for MS Windows.
38
+ * Test suite bug fixes for MS Windows (perm test now skipped).
39
+ * Inaccessible directories are now skipped instead of raising an error.
40
+
41
+ == 0.2.0 - 26-Apr-2007
42
+ * Fixed a bug where it was not traversing subdirectories.
43
+ * Added support for the perm and prune options.
44
+
45
+ == 0.1.1 - 25-Apr-2007
46
+ * The default for name is now '*', i.e. everything.
47
+ * Fixed a bug where directories were not matched. Thanks go to Leslie Viljoen
48
+ for the spot.
49
+ * The size option now accepts strings with comparable operators. For example,
50
+ you can now look for files greater than 400 bytes with the string "> 400".
51
+
52
+ == 0.1.0 - 24-Apr-2007
53
+ * Initial release
data/MANIFEST ADDED
@@ -0,0 +1,7 @@
1
+ * CHANGES
2
+ * MANIFEST
3
+ * Rakefile
4
+ * README
5
+ * file-find.gemspec
6
+ * lib/file/find.rb
7
+ * test/test_file_find.rb
data/README ADDED
@@ -0,0 +1,111 @@
1
+ = Description
2
+ This is a drop-in replacement for the find module currently in the standard
3
+ library. It is modeled on a typical 'find' command found on most Unix systems.
4
+
5
+ = Synopsis
6
+ rule = File::Find.new(
7
+ :pattern => "*.rb",
8
+ :follow => false,
9
+ :path => ['/usr/local/lib', '/opt/local/lib']
10
+ )
11
+
12
+ rule.find{ |f|
13
+ puts f
14
+ }
15
+
16
+ = Installation
17
+ * rake test (optional)
18
+ * rake install (non-gem) -OR- rake install_gem (gem)
19
+
20
+ = Rationale
21
+ The current find module in the standard library is inadequate. It is, quite
22
+ frankly, not much more than a plain Dir.glob call. This library provides an
23
+ interface based on options typically available on your command line 'find'
24
+ command, thus allowing you much greater control over how you find your files.
25
+
26
+ I am aware of the find2 library by Motoyuki Kasahara, but it supports very
27
+ few options, hasn't been updated in over six years and isn't packaged properly.
28
+
29
+ = Options
30
+ * atime
31
+ * ctime
32
+ * follow
33
+ * ftype
34
+ * inum (except Windows)
35
+ * group (name or id)
36
+ * maxdepth
37
+ * mindepth
38
+ * mtime
39
+ * name (or 'pattern')
40
+ * path
41
+ * perm (except Windows)
42
+ * prune
43
+ * size
44
+ * user (name or id)
45
+
46
+ In addition to the above options, FileTest methods such as 'readable?' and
47
+ 'writable?' may be used as keys, with true or false for their values.
48
+
49
+ See the RDoc documentation for more details about these options.
50
+
51
+ = Future Plans
52
+ More options will be added as time permits, and requests will definitely be
53
+ considered. Please log any feature requests on the project page at
54
+ http://www.rubyforge.org/projects/shards.
55
+
56
+ Some specific things I plan on adding:
57
+
58
+ * exec
59
+ * links
60
+ * support for :user and :group on MS Windows
61
+
62
+ = Options I won't support
63
+ Generally speaking, anything that would require mucking around with C code
64
+ or is just too difficult to implement in a cross platform manner will not be
65
+ supported. These include the following options:
66
+
67
+ * acl/xattr - Way too difficult to implement in a cross platform manner, and
68
+ a rarely used option in practice.
69
+
70
+ * cpio/ncpio - I will not shell out to this or any other 3rd party application.
71
+
72
+ * ls/print - Use Ruby's builtin printing methods to print as you see fit.
73
+
74
+ * ok - This is not interactive software.
75
+
76
+ = Options I may or may not support
77
+
78
+ * local/mount/xdev - This will probably not be added until I'm satisfied with
79
+ the sys-filesystem library. As of sys-filesystem 0.1.x, I'm not.
80
+
81
+ = Known Issues
82
+ The 'perm' option does not work on MS Windows, even for its limited subset of
83
+ permissions, i.e. 664 and 666. This is arguably a bug in Ruby's
84
+ File::Stat.mode method on MS Windows.
85
+
86
+ The 'user' and 'group' options are not currently supported on MS Windows.
87
+ This can be supported, but will require changes in the win32-file and
88
+ win32-file-stat libraries (which would then become dependencies).
89
+
90
+ There are 3 test failures with JRuby, all related to the 'perm' option. I
91
+ have not been able to reduce them to a simple test case and discern the
92
+ exact cause of the failures, though I suspect a bug in the JRuby
93
+ implementation of File.chmod.
94
+
95
+ = Bugs
96
+ None that I'm aware of. Please log any bug reports on the project page at
97
+ http://www.rubyforge.org/projects/shards.
98
+
99
+ = Acknowledgements
100
+ * Richard Clamp's File::Find::Rule Perl module for additional ideas and
101
+ inspiration.
102
+ * Bill Kleb for ideas regarding name, group and perm enhancements.
103
+
104
+ = License
105
+ Ruby's
106
+
107
+ = Copyright
108
+ (C) 2007-2008, Daniel J. Berger, All Rights Reserved
109
+
110
+ = Author
111
+ Daniel J. Berger
data/lib/file/find.rb ADDED
@@ -0,0 +1,474 @@
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.1'
15
+
16
+ # :stopdoc:
17
+ VALID_OPTIONS = %w/
18
+ atime
19
+ ctime
20
+ follow
21
+ ftype
22
+ inum
23
+ group
24
+ maxdepth
25
+ mindepth
26
+ mtime
27
+ name
28
+ pattern
29
+ path
30
+ perm
31
+ prune
32
+ size
33
+ user
34
+ /
35
+ # :startdoc:
36
+
37
+ # The starting path(s) for the search. The default is the current directory.
38
+ # This can be a single path or an array of paths.
39
+ #
40
+ attr_accessor :path
41
+
42
+ # The list of options passed to the constructor and/or used by the
43
+ # File::Find#find method.
44
+ #
45
+ attr_accessor :options
46
+
47
+ # Limits searches by file access time, where the value you supply is the
48
+ # number of days back from the time that the File::Find#find method was
49
+ # called.
50
+ #
51
+ attr_accessor :atime
52
+
53
+ # Limits searches by file change time, where the value you supply is the
54
+ # number of days back from the time that the File::Find#find method was
55
+ # called.
56
+ #
57
+ attr_accessor :ctime
58
+
59
+ # Limits searches to files that belong to a specific group, where the
60
+ # group can be either a group name or ID.
61
+ #
62
+ # Not currently supported on MS Windows.
63
+ #
64
+ attr_accessor :group
65
+
66
+ # An array of two element arrays for storing FileTest methods and their
67
+ # boolean value.
68
+ #
69
+ attr_accessor :filetest
70
+
71
+ # Controls the behavior of how symlinks are followed. If set to true (the
72
+ # default), then follows the file pointed to. If false, it considers the
73
+ # symlink itself.
74
+ #
75
+ attr_accessor :follow
76
+
77
+ # Limits searches to specific types of files. The possible values here are
78
+ # those returned by the File.ftype method.
79
+ #
80
+ attr_accessor :ftype
81
+
82
+ # Limits search to a file with a specific inode number. Ignored on MS
83
+ # Windows.
84
+ #
85
+ attr_accessor :inum
86
+
87
+ # Limits search to a maximum depth into the tree relative to the starting
88
+ # search directory.
89
+ #
90
+ attr_accessor :maxdepth
91
+
92
+ # Limits search to a minimum depth into the tree relative to the starting
93
+ # search directory.
94
+ #
95
+ attr_accessor :mindepth
96
+
97
+ # Limits searches by file modification time, where the value you supply is
98
+ # the number of days back from the time that the File::Find#find method was
99
+ # called.
100
+ #
101
+ attr_accessor :mtime
102
+
103
+ # The name pattern used to limit file searches. The patterns that are legal
104
+ # for Dir.glob are legal here. The default is '*', i.e. everything.
105
+ #
106
+ attr_accessor :name
107
+
108
+ # Limits searches to files which have permissions that match the octal
109
+ # value that you provide. For purposes of this comparison, only the user,
110
+ # group, and world settings are used. Do not use a leading 0 in the values
111
+ # that you supply, e.g. use 755 not 0755.
112
+ #
113
+ # You may optionally use symbolic permissions, e.g. "g+rw", "u=rwx", etc.
114
+ #
115
+ # Not currently supported on MS Windows.
116
+ #
117
+ attr_accessor :perm
118
+
119
+ # Skips files or directories that match the string provided as an argument.
120
+ #
121
+ attr_accessor :prune
122
+
123
+ # If the value passed is an integer, this option limits searches to files
124
+ # that match the size, in bytes, exactly. If a string is passed, you can
125
+ # use the standard comparable operators to match files, e.g. ">= 200" would
126
+ # limit searches to files greater than or equal to 200 bytes.
127
+ #
128
+ attr_accessor :size
129
+
130
+ # Limits searches to files that belong to a specific user, where the user
131
+ # can be either a user name or an ID.
132
+ #
133
+ # Not currently supported on MS Windows.
134
+ #
135
+ attr_accessor :user
136
+
137
+ # The file that matched previously in the current search.
138
+ #
139
+ attr_reader :previous
140
+
141
+ alias pattern name
142
+ alias pattern= name=
143
+
144
+ # Creates and returns a new File::Find object. The options set for this
145
+ # object serve as the rules for determining what files the File::Find#find
146
+ # method will search for.
147
+ #
148
+ # In addition to the standard list of valid options, you may also use
149
+ # FileTest methods as options, setting their value to true or false.
150
+ #
151
+ # Example:
152
+ #
153
+ # rule = File::Find.new(
154
+ # :name => "*.rb",
155
+ # :follow => false,
156
+ # :path => ['/usr/local/lib', '/opt/local/lib'],
157
+ # :readable? => true
158
+ # )
159
+ #
160
+ def initialize(options = {})
161
+ @options = options
162
+
163
+ @atime = nil
164
+ @ctime = nil
165
+ @ftype = nil
166
+ @group = nil
167
+ @follow = true
168
+ @inum = nil
169
+ @mtime = nil
170
+ @perm = nil
171
+ @prune = nil
172
+ @size = nil
173
+ @user = nil
174
+
175
+ @previous = nil
176
+ @maxdepth = nil
177
+ @mindepth = nil
178
+ @filetest = []
179
+
180
+ validate_and_set_options(options) unless options.empty?
181
+
182
+ @path ||= Dir.pwd
183
+ @name ||= '*'
184
+ end
185
+
186
+ # Executes the find based on the rules you set for the File::Find object.
187
+ # In block form, yields each file in turn that matches the specified rules.
188
+ # In non-block form it will return an array of matches instead.
189
+ #
190
+ # Example:
191
+ #
192
+ # rule = File::Find.new(
193
+ # :name => "*.rb",
194
+ # :follow => false,
195
+ # :path => ['/usr/local/lib', '/opt/local/lib']
196
+ # )
197
+ #
198
+ # rule.find{ |f|
199
+ # puts f
200
+ # }
201
+ #
202
+ def find
203
+ results = [] unless block_given?
204
+ paths = @path.to_a
205
+
206
+ if @prune
207
+ prune_regex = Regexp.new(@prune)
208
+ else
209
+ prune_regex = nil
210
+ end
211
+
212
+ paths.each{ |path|
213
+ begin
214
+ Dir.foreach(path){ |file|
215
+ next if file == '.'
216
+ next if file == '..'
217
+
218
+ if prune_regex
219
+ next if prune_regex.match(file)
220
+ end
221
+
222
+ orig = file.dup
223
+ file = File.join(path, file)
224
+
225
+ stat_method = @follow ? :lstat : :stat
226
+
227
+ # Skip files we cannot access, stale links, etc.
228
+ begin
229
+ stat_info = File.send(stat_method, file)
230
+ rescue Errno::ENOENT, Errno::EACCES
231
+ next
232
+ rescue Errno::ELOOP
233
+ stat_method = :lstat # Handle recursive symlinks
234
+ retry if stat_method.to_s != 'lstat'
235
+ end
236
+
237
+ glob = File.join(File.dirname(file), @name)
238
+
239
+ # Dir[] doesn't like backslashes
240
+ if File::ALT_SEPARATOR
241
+ file.tr!(File::ALT_SEPARATOR, File::SEPARATOR)
242
+ glob.tr!(File::ALT_SEPARATOR, File::SEPARATOR)
243
+ end
244
+
245
+ if @maxdepth || @mindepth
246
+ file_depth = file.split(File::SEPARATOR).length
247
+ path_depth = @path.split(File::SEPARATOR).length
248
+ depth = file_depth - path_depth
249
+
250
+ if @maxdepth && (depth > @maxdepth)
251
+ if File.directory?(file)
252
+ unless paths.include?(file) && depth > @maxdepth
253
+ paths << file
254
+ end
255
+ end
256
+
257
+ next
258
+ end
259
+
260
+ if @mindepth && (depth < @mindepth)
261
+ if File.directory?(file)
262
+ unless paths.include?(file) && depth < @mindepth
263
+ paths << file
264
+ end
265
+ end
266
+
267
+ next
268
+ end
269
+ end
270
+
271
+ # Add directories back onto the list of paths to search unless
272
+ # they've already been added
273
+ #
274
+ if stat_info.directory?
275
+ paths << file unless paths.include?(file)
276
+ end
277
+
278
+ next unless Dir[glob].include?(file)
279
+
280
+ unless @filetest.empty?
281
+ file_test = true
282
+
283
+ @filetest.each{ |array|
284
+ meth = array[0]
285
+ bool = array[1]
286
+
287
+ unless File.send(meth, file) == bool
288
+ file_test = false
289
+ break
290
+ end
291
+ }
292
+
293
+ next unless file_test
294
+ end
295
+
296
+ if @atime || @ctime || @mtime
297
+ date1 = Date.parse(Time.now.to_s)
298
+
299
+ if @atime
300
+ date2 = Date.parse(stat_info.atime.to_s)
301
+ next unless (date1 - date2).numerator == @atime
302
+ end
303
+
304
+ if @ctime
305
+ date2 = Date.parse(stat_info.ctime.to_s)
306
+ next unless (date1 - date2).numerator == @ctime
307
+ end
308
+
309
+ if @mtime
310
+ date2 = Date.parse(stat_info.mtime.to_s)
311
+ next unless (date1 - date2).numerator == @mtime
312
+ end
313
+ end
314
+
315
+ if @ftype
316
+ next unless File.ftype(file) == @ftype
317
+ end
318
+
319
+ if @group
320
+ if @group.is_a?(String)
321
+ next unless get_group(stat_info.gid).name == @group
322
+ else
323
+ next unless stat_info.gid == @group
324
+ end
325
+ end
326
+
327
+ unless Config::CONFIG['host_os'] =~ /windows|mswin/i
328
+ if @inum
329
+ next unless stat_info.ino == @inum
330
+ end
331
+ end
332
+
333
+ # This currently doesn't work on MS Windows, even in limited
334
+ # fashion for 0666 and 0664, because File.stat.mode doesn't
335
+ # return the proper value.
336
+ #
337
+ if @perm
338
+ if @perm.is_a?(String)
339
+ octal_perm = sym2oct(@perm)
340
+ next unless stat_info.mode & octal_perm == octal_perm
341
+ else
342
+ next unless sprintf("%o", stat_info.mode & 07777) == @perm.to_s
343
+ end
344
+ end
345
+
346
+ # Allow plain numbers, or strings for comparison operators.
347
+ if @size
348
+ if @size.is_a?(String)
349
+ regex = /^([><=]+)\s*?(\d+)$/
350
+ match = regex.match(@size)
351
+
352
+ if match.nil? || match.captures.include?(nil)
353
+ raise ArgumentError, "invalid size string: '#{@size}'"
354
+ end
355
+
356
+ operator = match.captures.first.strip
357
+ number = match.captures.last.strip.to_i
358
+
359
+ next unless stat_info.size.send(operator, number)
360
+ else
361
+ next unless stat_info.size == @size
362
+ end
363
+ end
364
+
365
+ if @user
366
+ if @user.is_a?(String)
367
+ next unless get_user(stat_info.uid).name == @user
368
+ else
369
+ next unless stat_info.uid == @user
370
+ end
371
+ end
372
+
373
+ if block_given?
374
+ yield file
375
+ else
376
+ results << file
377
+ end
378
+
379
+ @previous = file unless @previous == file
380
+ }
381
+ rescue Errno::EACCES
382
+ next # Skip inaccessible directories
383
+ end
384
+ }
385
+
386
+ block_given? ? nil : results
387
+ end
388
+
389
+ private
390
+
391
+ # This validates that the keys are valid. If they are, it sets the value
392
+ # of that key's corresponding method to the given value. If a key ends
393
+ # with a '?', it's validated as a File method.
394
+ #
395
+ def validate_and_set_options(options)
396
+ options.each do |key, value|
397
+ key = key.to_s.downcase
398
+
399
+ if key[-1].chr == '?'
400
+ sym = key.to_sym
401
+
402
+ unless File.respond_to?(sym)
403
+ raise ArgumentError, "invalid option '#{key}'"
404
+ end
405
+
406
+ @filetest << [sym, value]
407
+ else
408
+ unless VALID_OPTIONS.include?(key)
409
+ raise ArgumentError, "invalid option '#{key}'"
410
+ end
411
+
412
+ send("#{key}=", value)
413
+ end
414
+ end
415
+ end
416
+
417
+ # Converts a symoblic permissions mode into its octal equivalent.
418
+ #--
419
+ # Taken almost entirely from ruby-talk: 96956 (Hal Fulton).
420
+ #
421
+ def sym2oct(str)
422
+ left = {'u' => 0700, 'g' => 0070, 'o' => 0007, 'a' => 0777}
423
+ right = {'r' => 0444, 'w' => 0222, 'x' => 0111}
424
+ regex = /([ugoa]+)([+-=])([rwx]+)/
425
+
426
+ cmds = str.split(',')
427
+
428
+ perm = 0
429
+
430
+ cmds.each do |cmd|
431
+ match = cmd.match(regex)
432
+ raise "Invalid symbolic permissions: '#{str}'" if match.nil?
433
+
434
+ junk, who, what, how = match.to_a
435
+
436
+ who = who.split(//).inject(num=0) { |num,b| num |= left[b]; num }
437
+ how = how.split(//).inject(num=0) { |num,b| num |= right[b]; num }
438
+ mask = who & how
439
+
440
+ case what
441
+ when '+'
442
+ perm = perm | mask
443
+ when '-'
444
+ perm = perm & ~mask
445
+ when '='
446
+ perm = mask
447
+ end
448
+ end
449
+
450
+ perm
451
+ end
452
+
453
+ # Returns the group object based on the group id. Implemented for the
454
+ # sake of platforms that cannot build extensions, such as JRuby.
455
+ #
456
+ def get_group(gid)
457
+ if defined? Sys::Admin
458
+ Sys::Admin.get_group(gid)
459
+ else
460
+ Etc.getgrgid(gid)
461
+ end
462
+ end
463
+
464
+ # Returns the user object based on the group id. Implemented for the
465
+ # sake of platforms that cannot build extensions, such as JRuby.
466
+ #
467
+ def get_user(uid)
468
+ if defined? Sys::Admin
469
+ Sys::Admin.get_user(uid)
470
+ else
471
+ Etc.getpwuid(uid)
472
+ end
473
+ end
474
+ end
@@ -0,0 +1,431 @@
1
+ ######################################################################
2
+ # test_file_find.rb
3
+ #
4
+ # Test case for the File::Find package. You should run this via the
5
+ # 'rake test' task.
6
+ ######################################################################
7
+ require 'rubygems'
8
+ gem 'test-unit'
9
+
10
+ require 'test/unit'
11
+ require 'fileutils'
12
+ require 'file/find'
13
+ require 'rbconfig'
14
+
15
+ begin
16
+ require 'sys/admin'
17
+ rescue LoadError
18
+ require 'etc'
19
+ end
20
+
21
+ include Config
22
+ include FileUtils
23
+
24
+ class TC_File_Find < Test::Unit::TestCase
25
+ def self.startup
26
+ Dir.chdir('test') unless File.basename(Dir.pwd) == 'test'
27
+
28
+ @@windows = CONFIG['host_os'] =~ /windows|mswin/i
29
+ @@jruby = RUBY_PLATFORM.match('java')
30
+
31
+ unless @@windows
32
+ if @@jruby
33
+ @@loguser = Etc.getpwnam(Etc.getlogin)
34
+ @@logroup = Etc.getgrgid(@@loguser.gid)
35
+ else
36
+ @@loguser = Sys::Admin.get_user(Sys::Admin.get_login)
37
+ @@logroup = Sys::Admin.get_group(@@loguser.gid)
38
+ end
39
+ end
40
+ end
41
+
42
+ def setup
43
+ @file1 = 'test1.rb'
44
+ @file2 = 'test1.txt'
45
+ @file3 = 'foo.txt'
46
+ @file4 = 'foo.doc'
47
+ @dir1 = 'dir1'
48
+ @dir2 = 'dir2'
49
+
50
+ File.open(@file1, 'w'){}
51
+ File.open(@file2, 'w'){}
52
+ File.open(@file3, 'w'){}
53
+ File.open(@file4, 'w'){}
54
+
55
+ unless @@windows
56
+ @link1 = 'link1'
57
+ File.symlink(@file1, @link1)
58
+ end
59
+
60
+ Dir.mkdir(@dir1) unless File.exists?(@dir1)
61
+ Dir.mkdir(@dir2) unless File.exists?(@dir2)
62
+
63
+ File.open(File.join(@dir1, 'bar.txt'), 'w'){}
64
+ File.open(File.join(@dir2, 'baz.txt'), 'w'){}
65
+
66
+ @rule1 = File::Find.new(:name => '*.txt')
67
+ @rule2 = File::Find.new
68
+ end
69
+
70
+ def test_version
71
+ assert_equal('0.3.1', File::Find::VERSION)
72
+ end
73
+
74
+ def test_path
75
+ assert_respond_to(@rule1, :path)
76
+ assert_respond_to(@rule1, :path=)
77
+ assert_equal(Dir.pwd, @rule1.path)
78
+ end
79
+
80
+ def test_options
81
+ assert_respond_to(@rule1, :options)
82
+ assert_respond_to(@rule1, :options=)
83
+ assert_equal({:name => '*.txt'}, @rule1.options)
84
+ end
85
+
86
+ def test_atime_basic
87
+ assert_respond_to(@rule1, :atime)
88
+ assert_respond_to(@rule1, :atime=)
89
+ assert_nil(@rule1.atime)
90
+ end
91
+
92
+ def test_atime
93
+ rule1 = File::Find.new(:name => "*.rb", :atime => 0)
94
+ rule2 = File::Find.new(:name => "*.rb", :atime => 1)
95
+
96
+ assert_false(rule1.find.empty?)
97
+ assert_true(rule2.find.empty?)
98
+ end
99
+
100
+ def test_ctime_basic
101
+ assert_respond_to(@rule1, :ctime)
102
+ assert_respond_to(@rule1, :ctime=)
103
+ assert_nil(@rule1.ctime)
104
+ end
105
+
106
+ def test_ctime
107
+ rule1 = File::Find.new(:name => "*.rb", :ctime => 0)
108
+ rule2 = File::Find.new(:name => "*.rb", :ctime => 1)
109
+
110
+ assert_false(rule1.find.empty?)
111
+ assert_true(rule2.find.empty?)
112
+ end
113
+
114
+ def test_find_basic
115
+ assert_respond_to(@rule1, :find)
116
+ assert_nothing_raised{ @rule1.find }
117
+ end
118
+
119
+ def test_find
120
+ assert_kind_of(Array, @rule1.find)
121
+ assert_nil(@rule1.find{})
122
+ end
123
+
124
+ def test_filetest_basic
125
+ assert_respond_to(@rule1, :filetest)
126
+ assert_respond_to(@rule1, :filetest=)
127
+ assert_nothing_raised{ @rule1.filetest }
128
+ assert_kind_of(Array, @rule1.filetest)
129
+ end
130
+
131
+ def test_filetest_valid_options
132
+ assert_nothing_raised{ File::Find.new(:readable? => true) }
133
+ assert_nothing_raised{ File::Find.new(:writable? => true) }
134
+ end
135
+
136
+ def test_filetest
137
+ omit_if(@@windows && @@jruby, "Skipping file test on JRuby/Windows")
138
+
139
+ rule = File::Find.new(:name => "*.doc", :writable? => true)
140
+ File.chmod(0644, @file4)
141
+
142
+ assert_equal([@file4], rule.find.map{ |f| File.basename(f) })
143
+
144
+ File.chmod(0444, @file4)
145
+
146
+ assert_equal([], rule.find)
147
+ end
148
+
149
+ def test_mtime
150
+ rule1 = File::Find.new(:name => "*.rb", :mtime => 0)
151
+ rule2 = File::Find.new(:name => "*.rb", :mtime => 1)
152
+
153
+ assert_false(rule1.find.empty?)
154
+ assert_true(rule2.find.empty?)
155
+ end
156
+
157
+ def test_mtime_basic
158
+ assert_respond_to(@rule1, :mtime)
159
+ assert_respond_to(@rule1, :mtime=)
160
+ assert_nil(@rule1.mtime)
161
+ end
162
+
163
+ def test_ftype_basic
164
+ assert_respond_to(@rule1, :ftype)
165
+ assert_respond_to(@rule1, :ftype=)
166
+ assert_nil(@rule1.ftype)
167
+ end
168
+
169
+ def test_ftype
170
+ rule1 = File::Find.new(:name => "*.rb", :ftype => "file")
171
+ rule2 = File::Find.new(:name => "*.rb", :ftype => "characterSpecial")
172
+
173
+ assert_false(rule1.find.empty?)
174
+ assert_true(rule2.find.empty?)
175
+ end
176
+
177
+ def test_group_basic
178
+ assert_respond_to(@rule1, :group)
179
+ assert_respond_to(@rule1, :group=)
180
+ assert_nil(@rule1.group)
181
+ end
182
+
183
+ def test_group_with_numeric_id
184
+ omit_if(@@windows, 'group test skipped on MS Windows')
185
+ @rule1 = File::Find.new(:name => '*.doc', :group => @@loguser.gid)
186
+ assert_equal([File.expand_path(@file4)], @rule1.find)
187
+ end
188
+
189
+ def test_group_with_string
190
+ omit_if(@@windows, 'group test skipped on MS Windows')
191
+ @rule1 = File::Find.new(:name => '*.doc', :group => @@logroup.name)
192
+ assert_equal([File.expand_path(@file4)], @rule1.find)
193
+ end
194
+
195
+ def test_group_with_bad_id
196
+ omit_if(@@windows, 'group test skipped on MS Windows')
197
+ @rule1 = File::Find.new(:name => '*.doc', :group => 'totallybogus')
198
+ @rule2 = File::Find.new(:name => '*.doc', :group => 99999999)
199
+ assert_equal([], @rule1.find)
200
+ assert_equal([], @rule2.find)
201
+ end
202
+
203
+ def test_inum_basic
204
+ assert_respond_to(@rule1, :inum)
205
+ assert_respond_to(@rule1, :inum=)
206
+ assert_nil(@rule1.inum)
207
+ end
208
+
209
+ def test_follow_basic
210
+ assert_respond_to(@rule1, :follow)
211
+ assert_respond_to(@rule1, :follow=)
212
+ assert_true(@rule1.follow)
213
+ end
214
+
215
+ def test_maxdepth_basic
216
+ assert_respond_to(@rule1, :maxdepth)
217
+ assert_respond_to(@rule1, :maxdepth=)
218
+ assert_nil(@rule1.maxdepth)
219
+ end
220
+
221
+ def test_maxdepth_file
222
+ mkpath('a1/a2/a3')
223
+ touch('a1/a.foo')
224
+ touch('a1/a2/b.foo')
225
+ touch('a1/a2/c.foo')
226
+ touch('a1/a2/a3/d.foo')
227
+ touch('a1/a2/a3/e.foo')
228
+ touch('a1/a2/a3/f.foo')
229
+
230
+ @rule2.pattern = "*.foo"
231
+ @rule2.maxdepth = 1
232
+ assert_equal([], @rule2.find)
233
+
234
+ @rule2.maxdepth = 2
235
+ assert_equal(['a.foo'], @rule2.find.map{ |e| File.basename(e) })
236
+
237
+ @rule2.maxdepth = 3
238
+ assert_equal(['a.foo', 'b.foo', 'c.foo'], @rule2.find.map{ |e| File.basename(e) })
239
+
240
+ @rule2.maxdepth = nil
241
+ assert_equal(['a.foo', 'b.foo', 'c.foo', 'd.foo', 'e.foo', 'f.foo'], @rule2.find.map{ |e| File.basename(e) })
242
+ end
243
+
244
+ def test_maxdepth_directory
245
+ mkpath('a/b/c')
246
+ @rule2.pattern = "c"
247
+
248
+ @rule2.maxdepth = 1
249
+ assert_equal([], @rule2.find)
250
+
251
+ @rule2.maxdepth = 2
252
+ assert_equal([], @rule2.find)
253
+
254
+ @rule2.maxdepth = 3
255
+ assert_equal(['c'], @rule2.find.map{ |e| File.basename(e) })
256
+ end
257
+
258
+ def test_mindepth_basic
259
+ assert_respond_to(@rule1, :mindepth)
260
+ assert_respond_to(@rule1, :mindepth=)
261
+ assert_nil(@rule1.mindepth)
262
+ end
263
+
264
+ def test_mindepth_file
265
+ mkpath('a1/a2/a3')
266
+ touch('z.min')
267
+ touch('a1/a.min')
268
+ touch('a1/a2/b.min')
269
+ touch('a1/a2/c.min')
270
+ touch('a1/a2/a3/d.min')
271
+ touch('a1/a2/a3/e.min')
272
+ touch('a1/a2/a3/f.min')
273
+
274
+ @rule2.pattern = "*.min"
275
+
276
+ @rule2.mindepth = 0
277
+ assert_equal(['z.min', 'a.min', 'b.min', 'c.min', 'd.min', 'e.min', 'f.min'], @rule2.find.map{ |e| File.basename(e) })
278
+
279
+ @rule2.mindepth = 1
280
+ assert_equal(['z.min', 'a.min', 'b.min', 'c.min', 'd.min', 'e.min', 'f.min'], @rule2.find.map{ |e| File.basename(e) })
281
+
282
+ @rule2.mindepth = 2
283
+ assert_equal(['a.min', 'b.min', 'c.min', 'd.min', 'e.min', 'f.min'], @rule2.find.map{ |e| File.basename(e) })
284
+
285
+ @rule2.mindepth = 3
286
+ assert_equal(['b.min', 'c.min', 'd.min', 'e.min', 'f.min'], @rule2.find.map{ |e| File.basename(e) })
287
+
288
+ @rule2.mindepth = 4
289
+ assert_equal(['d.min', 'e.min', 'f.min'], @rule2.find.map{ |e| File.basename(e) })
290
+
291
+ @rule2.mindepth = 5
292
+ assert_equal([], @rule2.find.map{ |e| File.basename(e) })
293
+ end
294
+
295
+ def test_mindepth_directory
296
+ mkpath('a/b/c')
297
+ @rule2.pattern = "a"
298
+
299
+ @rule2.mindepth = 1
300
+ assert_equal(['a'], @rule2.find.map{ |e| File.basename(e) })
301
+
302
+ @rule2.mindepth = 2
303
+ assert_equal([], @rule2.find)
304
+
305
+ @rule2.mindepth = 3
306
+ assert_equal([], @rule2.find)
307
+ end
308
+
309
+ def test_name_basic
310
+ assert_respond_to(@rule1, :name)
311
+ assert_respond_to(@rule1, :name=)
312
+ assert_equal('*.txt', @rule1.name)
313
+ end
314
+
315
+ def test_pattern_alias
316
+ assert_respond_to(@rule1, :pattern)
317
+ assert_respond_to(@rule1, :pattern=)
318
+ assert_true(@rule1.method(:name) == @rule1.method(:pattern))
319
+ assert_true(@rule1.method(:name=) == @rule1.method(:pattern=))
320
+ end
321
+
322
+ def test_perm_basic
323
+ assert_respond_to(@rule1, :perm)
324
+ assert_respond_to(@rule1, :perm=)
325
+ assert_nil(@rule1.perm)
326
+ end
327
+
328
+ def test_perm
329
+ omit_if(@@windows, 'perm test skipped on MS Windows')
330
+ File.chmod(0664, @file1)
331
+ File.chmod(0644, @file2)
332
+ results = File::Find.new(:name => "test1*", :perm => 664).find
333
+
334
+ assert_equal(1, results.length)
335
+ assert_equal('test1.rb', File.basename(results.first))
336
+ end
337
+
338
+ def test_perm_with_symbolic_permissions
339
+ omit_if(@@windows, 'symbolic perm test skipped on MS Windows')
340
+
341
+ File.chmod(0664, @file1) # test1.rb
342
+ File.chmod(0644, @file2) # test1.txt
343
+ results1 = File::Find.new(:name => "test1*", :perm => "g=rw").find
344
+ results2 = File::Find.new(:name => "test1*", :perm => "u=rw").find
345
+
346
+ assert_equal(1, results1.length)
347
+ assert_equal(2, results2.length)
348
+ assert_equal('test1.rb', File.basename(results1.first))
349
+ assert_equal(['test1.rb', 'test1.txt'], results2.map{ |e| File.basename(e) })
350
+ end
351
+
352
+ def test_prune_basic
353
+ assert_respond_to(@rule1, :prune)
354
+ assert_respond_to(@rule1, :prune=)
355
+ assert_nil(@rule1.prune)
356
+ end
357
+
358
+ def test_prune
359
+ rule = File::Find.new(:name => "*.txt", :prune => 'foo')
360
+ assert_equal('test1.txt', File.basename(rule.find.first))
361
+ end
362
+
363
+ def test_size_basic
364
+ assert_respond_to(@rule1, :size)
365
+ assert_respond_to(@rule1, :size=)
366
+ assert_nil(@rule1.size)
367
+ end
368
+
369
+ def test_user_basic
370
+ assert_respond_to(@rule1, :user)
371
+ assert_respond_to(@rule1, :user=)
372
+ assert_nil(@rule1.user)
373
+ end
374
+
375
+ def test_user_with_numeric_id
376
+ omit_if(@@windows, 'user test skipped on MS Windows')
377
+ @rule1 = File::Find.new(:name => '*.doc', :user => @@loguser.uid)
378
+ assert_equal([File.expand_path(@file4)], @rule1.find)
379
+ end
380
+
381
+ def test_user_with_string
382
+ omit_if(@@windows, 'user test skipped on MS Windows')
383
+ @rule1 = File::Find.new(:name => '*.doc', :user => @@loguser.name)
384
+ assert_equal([File.expand_path(@file4)], @rule1.find)
385
+ end
386
+
387
+ def test_user_with_bad_id
388
+ omit_if(@@windows, 'user test skipped on MS Windows')
389
+ @rule1 = File::Find.new(:name => '*.doc', :user => 'totallybogus')
390
+ @rule2 = File::Find.new(:name => '*.doc', :user => 99999999)
391
+ assert_equal([], @rule1.find)
392
+ assert_equal([], @rule2.find)
393
+ end
394
+
395
+ def test_previous_basic
396
+ assert_respond_to(@rule1, :previous)
397
+ end
398
+
399
+ def test_expected_errors
400
+ assert_raise(Errno::ENOENT){ File::Find.new(:path => '/bogus/dir').find }
401
+ assert_raise(ArgumentError){ File::Find.new(:bogus => 1) }
402
+ assert_raise(ArgumentError){ File::Find.new(:bogus? => true) }
403
+ end
404
+
405
+ def teardown
406
+ rm_rf(@file1)
407
+ rm_rf(@file2)
408
+ rm_rf(@file3)
409
+ rm_rf(@file4)
410
+ rm_rf(@dir1)
411
+ rm_rf(@dir2)
412
+ rm_rf(@link1) unless @@windows
413
+ rm_rf('a')
414
+ rm_rf('a1')
415
+ rm_rf('z.min') if File.exists?('z.min')
416
+
417
+ @rule1 = nil
418
+ @rule2 = nil
419
+ @file1 = nil
420
+ @file2 = nil
421
+ @file3 = nil
422
+ @file4 = nil
423
+ end
424
+
425
+ def self.shutdown
426
+ @@windows = nil
427
+ @@jruby = nil
428
+ @@loguser = nil unless @@windows
429
+ @@logroup = nil unless @@windows
430
+ end
431
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ extensions: []
3
+
4
+ homepage: http://www.rubyforge.org/projects/shards
5
+ executables: []
6
+
7
+ version: !ruby/object:Gem::Version
8
+ version: 0.3.1
9
+ post_install_message:
10
+ date: 2009-01-09 07:00:00 +00:00
11
+ files:
12
+ - lib/file
13
+ - lib/file/find.rb
14
+ - test/test_file_find.rb
15
+ - README
16
+ - CHANGES
17
+ - MANIFEST
18
+ rubygems_version: 1.3.1
19
+ rdoc_options: []
20
+
21
+ signing_key:
22
+ cert_chain: []
23
+
24
+ name: file-find
25
+ has_rdoc: true
26
+ platform: universal-java-1.5
27
+ summary: A better way to find files
28
+ default_executable:
29
+ bindir: bin
30
+ required_rubygems_version: !ruby/object:Gem::Requirement
31
+ version:
32
+ requirements:
33
+ - - '>='
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ version:
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: "0"
42
+ require_paths:
43
+ - lib
44
+ specification_version: 2
45
+ test_files:
46
+ - test/test_file_find.rb
47
+ dependencies:
48
+ - !ruby/object:Gem::Dependency
49
+ type: :runtime
50
+ name: test-unit
51
+ version_requirement:
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ version:
54
+ requirements:
55
+ - - '>='
56
+ - !ruby/object:Gem::Version
57
+ version: 2.0.2
58
+ description: A better way to find files
59
+ email: djberg96@gmail.com
60
+ authors:
61
+ - Daniel Berger
62
+ extra_rdoc_files:
63
+ - README
64
+ - CHANGES
65
+ - MANIFEST
66
+ requirements: []
67
+
68
+ rubyforge_project: shards
69
+ autorequire: