/tools/Ruby/lib/ruby/1.8/find.rb

http://github.com/agross/netopenspace · Ruby · 79 lines · 36 code · 4 blank · 39 comment · 8 complexity · d3813f4f53afab0aaddc5f47b3a1dc0f MD5 · raw file

  1. #
  2. # find.rb: the Find module for processing all files under a given directory.
  3. #
  4. #
  5. # The +Find+ module supports the top-down traversal of a set of file paths.
  6. #
  7. # For example, to total the size of all files under your home directory,
  8. # ignoring anything in a "dot" directory (e.g. $HOME/.ssh):
  9. #
  10. # require 'find'
  11. #
  12. # total_size = 0
  13. #
  14. # Find.find(ENV["HOME"]) do |path|
  15. # if FileTest.directory?(path)
  16. # if File.basename(path)[0] == ?.
  17. # Find.prune # Don't look any further into this directory.
  18. # else
  19. # next
  20. # end
  21. # else
  22. # total_size += FileTest.size(path)
  23. # end
  24. # end
  25. #
  26. module Find
  27. #
  28. # Calls the associated block with the name of every file and directory listed
  29. # as arguments, then recursively on their subdirectories, and so on.
  30. #
  31. # See the +Find+ module documentation for an example.
  32. #
  33. def find(*paths) # :yield: path
  34. paths.collect!{|d| d.dup}
  35. while file = paths.shift
  36. catch(:prune) do
  37. yield file.dup.taint
  38. next unless File.exist? file
  39. begin
  40. if File.lstat(file).directory? then
  41. d = Dir.open(file)
  42. begin
  43. for f in d
  44. next if f == "." or f == ".."
  45. if File::ALT_SEPARATOR and file =~ /^(?:[\/\\]|[A-Za-z]:[\/\\]?)$/ then
  46. f = file + f
  47. elsif file == "/" then
  48. f = "/" + f
  49. else
  50. f = File.join(file, f)
  51. end
  52. paths.unshift f.untaint
  53. end
  54. ensure
  55. d.close
  56. end
  57. end
  58. rescue Errno::ENOENT, Errno::EACCES
  59. end
  60. end
  61. end
  62. end
  63. #
  64. # Skips the current file or directory, restarting the loop with the next
  65. # entry. If the current file is a directory, that directory will not be
  66. # recursively entered. Meaningful only within the block associated with
  67. # Find::find.
  68. #
  69. # See the +Find+ module documentation for an example.
  70. #
  71. def prune
  72. throw :prune
  73. end
  74. module_function :find, :prune
  75. end