file-find 0.3.3-universal-java-1.5 → 0.3.4-universal-java-1.5

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