file-find 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/CHANGES +11 -2
  2. data/README +1 -1
  3. data/test/test_file_find.rb +55 -39
  4. metadata +8 -10
  5. data/lib/file/find.rb +0 -487
data/CHANGES CHANGED
@@ -1,8 +1,17 @@
1
- == 0.3.2 - 20-Feb-2008
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-2008
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
@@ -99,7 +99,7 @@ http://www.rubyforge.org/projects/shards.
99
99
  * Hal Fulton for his implementation of symbolic permissions.
100
100
 
101
101
  = License
102
- Ruby's
102
+ Artistic 2.0
103
103
 
104
104
  = Copyright
105
105
  (C) 2007-2009, Daniel J. Berger, All Rights Reserved
@@ -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('test') unless File.basename(Dir.pwd) == 'test'
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
- @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'){}
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(@file1, @link1)
57
+ File.symlink(@file_rb, @link1)
58
58
  end
59
59
 
60
- Dir.mkdir(@dir1) unless File.exists?(@dir1)
61
- Dir.mkdir(@dir2) unless File.exists?(@dir2)
60
+ Dir.mkdir(@directory1) unless File.exists?(@directory1)
61
+ Dir.mkdir(@directory2) unless File.exists?(@directory2)
62
62
 
63
- File.open(File.join(@dir1, 'bar.txt'), 'w'){}
64
- File.open(File.join(@dir2, 'baz.txt'), 'w'){}
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.2', File::Find::VERSION)
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, @file4)
140
+ File.chmod(0644, @file_doc)
141
141
 
142
- assert_equal([@file4], rule.find.map{ |f| File.basename(f) })
142
+ assert_equal([@file_doc], rule.find.map{ |f| File.basename(f) })
143
143
 
144
- File.chmod(0444, @file4)
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(@file4)], @rule1.find)
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(@file4)], @rule1.find)
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, @file1)
337
- File.chmod(0644, @file2)
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, @file1) # test1.rb
348
- File.chmod(0644, @file2) # test1.txt
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(@file4)], @rule1.find)
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(@file4)], @rule1.find)
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(@file1)
413
- rm_rf(@file2)
414
- rm_rf(@file3)
415
- rm_rf(@file4)
416
- rm_rf(@dir1)
417
- rm_rf(@dir2)
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
- @file1 = nil
426
- @file2 = nil
427
- @file3 = nil
428
- @file4 = nil
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.2
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-02-20 00:00:00 -07:00
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: :runtime
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.2
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: A better, object oriented way to find files
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.1
74
+ rubygems_version: 1.3.5
77
75
  signing_key:
78
76
  specification_version: 3
79
77
  summary: A better way to find files
@@ -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