Class: Trop::FileFind
- Inherits:
-
Object
- Object
- Trop::FileFind
- Defined in:
- lib/trop/filefind.rb
Constant Summary collapse
- VERSION =
The version of the file-find library
'0.4.2'.freeze
- VALID_OPTIONS =
:stopdoc:
%w[ atime ctime follow ftype inum group links maxdepth mindepth mount mtime name pattern path perm prune size user ]
Instance Attribute Summary collapse
-
#atime ⇒ Object
Limits searches by file access time, where the value you supply is the number of days back from the time that the File::Find#find method was called.
-
#ctime ⇒ Object
Limits searches by file change time, where the value you supply is the number of days back from the time that the File::Find#find method was called.
-
#filetest ⇒ Object
An array of two element arrays for storing FileTest methods and their boolean value.
-
#follow ⇒ Object
Controls the behavior of how symlinks are followed.
-
#ftype ⇒ Object
Limits searches to specific types of files.
-
#group ⇒ Object
Limits searches to files that belong to a specific group, where the group can be either a group name or ID.
-
#inum ⇒ Object
Limits search to a file with a specific inode number.
-
#links ⇒ Object
Limits search to files with the specified number of links.
-
#maxdepth ⇒ Object
Limits search to a maximum depth into the tree relative to the starting search directory.
-
#mindepth ⇒ Object
Limits searches to a minimum depth into the tree relative to the starting search directory.
-
#mount ⇒ Object
Limits searches to the same filesystem as the specified directory.
-
#mtime ⇒ Object
Limits searches by file modification time, where the value you supply is the number of days back from the time that the File::Find#find method was called.
-
#name ⇒ Object
(also: #pattern)
The name pattern used to limit file searches.
-
#options ⇒ Object
The list of options passed to the constructor and/or used by the Trop::Find#find method.
-
#path ⇒ Object
The starting path(s) for the search.
-
#perm ⇒ Object
Limits searches to files which have permissions that match the octal value that you provide.
-
#previous ⇒ Object
readonly
The file that matched previously in the current search.
-
#prune ⇒ Object
Skips files or directories that match the string provided as an argument.
-
#size ⇒ Object
If the value passed is an integer, this option limits searches to files that match the size, in bytes, exactly.
-
#user ⇒ Object
Limits searches to files that belong to a specific user, where the user can be either a user name or an ID.
Instance Method Summary collapse
-
#find ⇒ Object
Executes the find based on the rules you set for the File::Find object.
-
#initialize(options = {}) ⇒ FileFind
constructor
Creates and returns a new File::Find object.
Constructor Details
#initialize(options = {}) ⇒ FileFind
Creates and returns a new File::Find object. The options set for this object serve as the rules for determining what files the File::Find#find method will search for.
In addition to the standard list of valid options, you may also use FileTest methods as options, setting their value to true or false.
Example:
rule = File::Find.new(
:name => "*.rb",
:follow => false,
:path => ['/usr/local/lib', '/opt/local/lib'],
:readable? => true
)
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/trop/filefind.rb', line 169 def initialize( = {}) @options = @atime = nil @ctime = nil @ftype = nil @group = nil @follow = true @inum = nil @links = nil @mount = nil @mtime = nil @perm = nil @prune = nil @size = nil @user = nil @previous = nil @maxdepth = nil @mindepth = nil @filetest = [] () unless .empty? @filesystem = File.stat(@mount).dev if @mount @path ||= Dir.pwd @name ||= '*' end |
Instance Attribute Details
#atime ⇒ Object
Limits searches by file access time, where the value you supply is the number of days back from the time that the File::Find#find method was called.
57 58 59 |
# File 'lib/trop/filefind.rb', line 57 def atime @atime end |
#ctime ⇒ Object
Limits searches by file change time, where the value you supply is the number of days back from the time that the File::Find#find method was called.
63 64 65 |
# File 'lib/trop/filefind.rb', line 63 def ctime @ctime end |
#filetest ⇒ Object
An array of two element arrays for storing FileTest methods and their boolean value.
73 74 75 |
# File 'lib/trop/filefind.rb', line 73 def filetest @filetest end |
#follow ⇒ Object
Controls the behavior of how symlinks are followed. If set to true (the default), then follows the file pointed to. If false, it considers the symlink itself.
79 80 81 |
# File 'lib/trop/filefind.rb', line 79 def follow @follow end |
#ftype ⇒ Object
Limits searches to specific types of files. The possible values here are those returned by the File.ftype method.
84 85 86 |
# File 'lib/trop/filefind.rb', line 84 def ftype @ftype end |
#group ⇒ Object
Limits searches to files that belong to a specific group, where the group can be either a group name or ID.
68 69 70 |
# File 'lib/trop/filefind.rb', line 68 def group @group end |
#inum ⇒ Object
Limits search to a file with a specific inode number.
88 89 90 |
# File 'lib/trop/filefind.rb', line 88 def inum @inum end |
#links ⇒ Object
Limits search to files with the specified number of links.
92 93 94 |
# File 'lib/trop/filefind.rb', line 92 def links @links end |
#maxdepth ⇒ Object
Limits search to a maximum depth into the tree relative to the starting search directory.
97 98 99 |
# File 'lib/trop/filefind.rb', line 97 def maxdepth @maxdepth end |
#mindepth ⇒ Object
Limits searches to a minimum depth into the tree relative to the starting search directory.
102 103 104 |
# File 'lib/trop/filefind.rb', line 102 def mindepth @mindepth end |
#mount ⇒ Object
Limits searches to the same filesystem as the specified directory. For Windows users, this refers to the volume.
107 108 109 |
# File 'lib/trop/filefind.rb', line 107 def mount @mount end |
#mtime ⇒ Object
Limits searches by file modification time, where the value you supply is the number of days back from the time that the File::Find#find method was called.
113 114 115 |
# File 'lib/trop/filefind.rb', line 113 def mtime @mtime end |
#name ⇒ Object Also known as: pattern
The name pattern used to limit file searches. The patterns that are legal for Dir.glob are legal here. The default is ‘*’, i.e. everything.
118 119 120 |
# File 'lib/trop/filefind.rb', line 118 def name @name end |
#options ⇒ Object
The list of options passed to the constructor and/or used by the Trop::Find#find method.
51 52 53 |
# File 'lib/trop/filefind.rb', line 51 def @options end |
#path ⇒ Object
The starting path(s) for the search. The default is the current directory. This can be a single path or an array of paths.
46 47 48 |
# File 'lib/trop/filefind.rb', line 46 def path @path end |
#perm ⇒ Object
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.
You may optionally use symbolic permissions, e.g. “g+rw”, “u=rwx”, etc.
MS Windows only recognizes two modes, 0644 and 0444.
128 129 130 |
# File 'lib/trop/filefind.rb', line 128 def perm @perm end |
#previous ⇒ Object (readonly)
The file that matched previously in the current search.
148 149 150 |
# File 'lib/trop/filefind.rb', line 148 def previous @previous end |
#prune ⇒ Object
Skips files or directories that match the string provided as an argument.
132 133 134 |
# File 'lib/trop/filefind.rb', line 132 def prune @prune end |
#size ⇒ Object
If the value passed is an integer, this option limits searches to files that match the size, in bytes, exactly. If a string is passed, you can use the standard comparable operators to match files, e.g. “>= 200” would limit searches to files greater than or equal to 200 bytes.
139 140 141 |
# File 'lib/trop/filefind.rb', line 139 def size @size end |
#user ⇒ Object
Limits searches to files that belong to a specific user, where the user can be either a user name or an ID.
144 145 146 |
# File 'lib/trop/filefind.rb', line 144 def user @user end |
Instance Method Details
#find ⇒ Object
Executes the find based on the rules you set for the File::Find object. In block form, yields each file in turn that matches the specified rules. In non-block form it will return an array of matches instead.
Example:
rule = Trop::Find.new(
:name => "*.rb",
:follow => false,
:path => ['/usr/local/lib', '/opt/local/lib']
)
rule.find{ |f|
puts f
}
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 |
# File 'lib/trop/filefind.rb', line 215 def find results = [] unless block_given? paths = @path.is_a?(String) ? [@path] : @path # Ruby 1.9.x compatibility if @prune prune_regex = Regexp.new(@prune) else prune_regex = nil end paths.each {|path| begin Dir.foreach(path) {|file| next if file == '.' next if file == '..' if prune_regex next if prune_regex.match(file) end file = File.join(path, file) stat_method = @follow ? :stat : :lstat # Skip files we cannot access, stale links, etc. begin stat_info = File.send(stat_method, file) rescue Errno::ENOENT, Errno::EACCES next rescue Errno::ELOOP stat_method = :lstat # Handle recursive symlinks retry if stat_method.to_s != 'lstat' end # We need to escape any brackets in the directory name. glob = File.join(File.dirname(file).gsub(/([\[\]])/, '\\\\\1'), @name) # Dir[] doesn't like backslashes if File::ALT_SEPARATOR file.tr!(File::ALT_SEPARATOR, File::SEPARATOR) glob.tr!(File::ALT_SEPARATOR, File::SEPARATOR) end if @mount next unless stat_info.dev == @filesystem end if @links next unless stat_info.nlink == @links end if @maxdepth || @mindepth file_depth = file.split(File::SEPARATOR).length current_base_path = [@path].flatten.find {|tpath| file.include?(tpath)} path_depth = current_base_path.split(File::SEPARATOR).length depth = file_depth - path_depth if @maxdepth && (depth > @maxdepth) if File.directory?(file) unless paths.include?(file) && depth > @maxdepth paths << file end end next end if @mindepth && (depth < @mindepth) if File.directory?(file) unless paths.include?(file) && depth < @mindepth paths << file end end next end end # Add directories back onto the list of paths to search unless # they've already been added # if File.directory?(file) ## stat_info.directory? paths << file unless paths.include?(file) end next unless Dir[glob].include?(file) unless @filetest.empty? file_test = true @filetest.each {|array| meth = array[0] bool = array[1] unless File.send(meth, file) == bool file_test = false break end } next unless file_test end if @atime || @ctime || @mtime date1 = Date.parse(Time.now.to_s) if @atime date2 = Date.parse(stat_info.atime.to_s) next unless (date1 - date2).numerator == @atime end if @ctime date2 = Date.parse(stat_info.ctime.to_s) next unless (date1 - date2).numerator == @ctime end if @mtime date2 = Date.parse(stat_info.mtime.to_s) next unless (date1 - date2).numerator == @mtime end end if @ftype next unless File.ftype(file) == @ftype end if @group if @group.is_a?(String) if File::ALT_SEPARATOR begin next unless Sys::Admin.get_group(stat_info.gid, :LocalAccount => true).name == @group rescue Sys::Admin::Error next end else begin next unless Sys::Admin.get_group(stat_info.gid).name == @group rescue Sys::Admin::Error next end end else next unless stat_info.gid == @group end end if @inum next unless stat_info.ino == @inum end # Note that only 0644 and 0444 are supported on MS Windows. if @perm if @perm.is_a?(String) octal_perm = sym2oct(@perm) next unless stat_info.mode & octal_perm == octal_perm else next unless sprintf("%o", stat_info.mode & 07777) == sprintf("%o", @perm) end end # Allow plain numbers, or strings for comparison operators. if @size if @size.is_a?(String) regex = /^([><=]+)\s*?(\d+)$/ match = regex.match(@size) if match.nil? || match.captures.include?(nil) raise ArgumentError, "invalid size string: '#{@size}'" end operator = match.captures.first.strip number = match.captures.last.strip.to_i next unless stat_info.size.send(operator, number) else next unless stat_info.size == @size end end if @user if @user.is_a?(String) if File::ALT_SEPARATOR begin next unless Sys::Admin.get_user(stat_info.uid, :LocalAccount => true).name == @user rescue Sys::Admin::Error next end else begin next unless Sys::Admin.get_user(stat_info.uid).name == @user rescue Sys::Admin::Error next end end else next unless stat_info.uid == @user end end if block_given? yield file else results << file end @previous = file unless @previous == file } rescue Errno::EACCES next # Skip inaccessible directories end } block_given? ? nil : results end |