lib/file/find.rb in file-find-0.2.3 vs lib/file/find.rb in file-find-0.2.4
- old
+ new
@@ -4,11 +4,11 @@
include Config
include Sys
class File::Find
# The version of this library
- VERSION = '0.2.3'
+ VERSION = '0.2.4'
# :stopdoc:
VALID_OPTIONS = %w/
atime
ctime
@@ -86,10 +86,12 @@
# Limits searches to files which have permissions that match the octal
# value that you provide. For purposes of this comparison, only the user,
# group, and world settings are used. Do not use a leading 0 in the values
# that you supply, e.g. use 755 not 0755.
#
+ # You may optionally use symbolic permissions, e.g. "g+rw", "u=rwx", etc.
+ #
# Not currently supported on MS Windows.
#
attr_accessor :perm
# Skips files or directories that match the string provided as an argument.
@@ -142,14 +144,14 @@
@perm = nil
@prune = nil
@size = nil
@user = nil
- validate_and_set_options(options) unless options.empty?
-
@previous = nil
+ validate_and_set_options(options) unless options.empty?
+
@path ||= Dir.pwd
@name ||= '*'
end
# Executes the find based on the rules you set for the File::Find object.
@@ -263,11 +265,15 @@
# This currently doesn't work on MS Windows, even in limited
# fashion for 0666 and 0664, because File.stat.mode doesn't
# return the proper value.
#
if @perm
- next unless sprintf("%o", stat_info.mode & 07777) == @perm.to_s
+ if @perm.is_a?(String)
+ next unless stat_info.mode & sym2oct(@perm) == sym2oct(@perm)
+ else
+ next unless sprintf("%o", stat_info.mode & 07777) == @perm.to_s
+ end
end
# Allow plain numbers, or strings for comparison operators.
if @size
if @size.is_a?(String)
@@ -322,7 +328,43 @@
unless VALID_OPTIONS.include?(key)
raise ArgumentError, "invalid option '#{key}'"
end
send("#{key}=", value)
end
+ end
+
+ # Converts a symoblic permissions mode into its octal equivalent.
+ #--
+ # Taken almost entirely from ruby-talk: 96956 (Hal Fulton).
+ #
+ def sym2oct(str)
+ left = {'u' => 0700, 'g' => 0070, 'o' => 0007, 'a' => 0777}
+ right = {'r' => 0444, 'w' => 0222, 'x' => 0111}
+ regex = /([ugoa]+)([+-=])([rwx]+)/
+
+ cmds = str.split(',')
+
+ perm = 0
+
+ cmds.each do |cmd|
+ match = cmd.match(regex)
+ raise "Invalid symbolic permissions: '#{str}'" if match.nil?
+
+ junk, who, what, how = match.to_a
+
+ who = who.split(//).inject(num=0) { |num,b| num |= left[b]; num }
+ how = how.split(//).inject(num=0) { |num,b| num |= right[b]; num }
+ mask = who & how
+
+ case what
+ when '+'
+ perm = perm | mask
+ when '-'
+ perm = perm & ~mask
+ when '='
+ perm = mask
+ end
+ end
+
+ perm
end
end