treevisitor 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +6 -1
- data/Rakefile +6 -11
- data/lib/tree_visitor.rb +1 -1
- data/lib/treevisitor.rb +1 -38
- data/lib/treevisitor_cli.rb +2 -4
- data/treevisitor.gemspec +16 -28
- metadata +11 -143
- data/.gemtest +0 -0
- data/bin/tree.rb +0 -9
- data/examples/directory_walker/directory_without_subdirectory.rb +0 -37
- data/examples/directory_walker/find_files.rb +0 -18
- data/examples/directory_walker/print_files.rb +0 -12
- data/examples/protovis/directory_to_json_visitor.rb +0 -15
- data/examples/protovis/index.html +0 -87
- data/examples/protovis/protovis-r3.2.js +0 -277
- data/examples/protovis/treevisitor.js +0 -33
- data/examples/protovis/treevisitor.png +0 -0
- data/lib/treevisitor/abs_node.rb +0 -144
- data/lib/treevisitor/basic_tree_node_visitor.rb +0 -44
- data/lib/treevisitor/cli/cli_tree.rb +0 -106
- data/lib/treevisitor/directory_walker.rb +0 -300
- data/lib/treevisitor/leaf_node.rb +0 -33
- data/lib/treevisitor/tree_node.rb +0 -251
- data/lib/treevisitor/tree_node_visitor.rb +0 -119
- data/lib/treevisitor/util/dir_processor.rb +0 -46
- data/lib/treevisitor/version.rb +0 -4
- data/lib/treevisitor/visitors/block_tree_node_visitor.rb +0 -21
- data/lib/treevisitor/visitors/build_dir_tree_visitor.rb +0 -57
- data/lib/treevisitor/visitors/callback_tree_node_visitor2.rb +0 -48
- data/lib/treevisitor/visitors/clone_tree_node_visitor.rb +0 -39
- data/lib/treevisitor/visitors/depth_tree_node_visitor.rb +0 -27
- data/lib/treevisitor/visitors/directory_to_hash_visitor.rb +0 -33
- data/lib/treevisitor/visitors/flat_print_tree_node_visitors.rb +0 -20
- data/lib/treevisitor/visitors/print_dir_tree_visitor.rb +0 -21
- data/lib/treevisitor/visitors/print_tree_node_visitor.rb +0 -40
- data/spec/fixtures/test_dir_1/.dir_with_dot/dummy.txt +0 -0
- data/spec/fixtures/test_dir_1/dir.1/dir.1.2/file.1.2.1 +0 -0
- data/spec/fixtures/test_dir_1/dir.1/file.1.1 +0 -0
- data/spec/fixtures/test_dir_1/dir.2/file.2.1 +0 -0
- data/spec/fixtures/test_dir_2/[Dsube]/sub/.gitkeep +0 -0
- data/spec/spec_helper.rb +0 -28
- data/spec/treevisitor/cli/cli_tree_spec.rb +0 -69
- data/spec/treevisitor/directory_walker_spec.rb +0 -99
- data/spec/treevisitor/tree_dsl_spec.rb +0 -57
- data/spec/treevisitor/tree_dsl_with_derived_class1_spec.rb +0 -53
- data/spec/treevisitor/tree_dsl_with_derived_class_spec.rb +0 -51
- data/spec/treevisitor/tree_node_paths_spec.rb +0 -70
- data/spec/treevisitor/tree_node_spec.rb +0 -135
- data/spec/treevisitor/tree_node_visitor_delegate_spec.rb +0 -35
- data/spec/treevisitor/tree_node_visitor_dsl_spec.rb +0 -66
- data/spec/treevisitor/util/dir_processor_spec.rb +0 -13
- data/spec/treevisitor/visitors/block_tree_node_visitor_spec.rb +0 -25
- data/spec/treevisitor/visitors/callback_tree_node_visitor2_spec.rb +0 -38
- data/spec/treevisitor/visitors/depth_tree_node_visitor_spec.rb +0 -28
- data/spec/treevisitor/visitors/tree_node_visitors_spec.rb +0 -27
- data/tasks/rspec.rake +0 -34
- data/tasks/yard.rake +0 -36
| @@ -1,44 +0,0 @@ | |
| 1 | 
            -
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            -
            module TreeVisitor
         | 
| 3 | 
            -
              #
         | 
| 4 | 
            -
              # Callback methods used to visit a tree
         | 
| 5 | 
            -
              # Are empty so it is possible to define only a subset when deriving subclass
         | 
| 6 | 
            -
              #
         | 
| 7 | 
            -
              class BasicTreeNodeVisitor
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                #
         | 
| 10 | 
            -
                # called on tree node at start of the visit i.e. we start to visit the subtree
         | 
| 11 | 
            -
                #
         | 
| 12 | 
            -
                def enter_node( tree_node )
         | 
| 13 | 
            -
                end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                #
         | 
| 16 | 
            -
                # called when the tree node is not accessible or an exception is raise when the node is accessed
         | 
| 17 | 
            -
                #
         | 
| 18 | 
            -
                def cannot_enter_node( tree_node, error)
         | 
| 19 | 
            -
                end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                # alias :enter_tree_node :enter_node
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                #
         | 
| 24 | 
            -
                # called on tree node at end of the visit i.e. oll subtree are visited
         | 
| 25 | 
            -
                #
         | 
| 26 | 
            -
                def exit_node( tree_node )
         | 
| 27 | 
            -
                end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
                # alias :exit_tree_node :exit_node
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                #
         | 
| 32 | 
            -
                # called when visit leaf node
         | 
| 33 | 
            -
                #
         | 
| 34 | 
            -
                def visit_leaf( leaf_node )
         | 
| 35 | 
            -
                end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
                #
         | 
| 38 | 
            -
                # called when the leaf node is not accessible or an exception is raise when the node is accessed
         | 
| 39 | 
            -
                #
         | 
| 40 | 
            -
                def cannot_visit_leaf( tree_node, error)
         | 
| 41 | 
            -
                end
         | 
| 42 | 
            -
              end
         | 
| 43 | 
            -
             | 
| 44 | 
            -
            end
         | 
| @@ -1,106 +0,0 @@ | |
| 1 | 
            -
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            -
            module TreeVisitor
         | 
| 3 | 
            -
              #
         | 
| 4 | 
            -
              #
         | 
| 5 | 
            -
              #
         | 
| 6 | 
            -
              class CliTree
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                def self.run
         | 
| 9 | 
            -
                  self.new.parse_args(ARGV)
         | 
| 10 | 
            -
                end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                def parse_args(argv)
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                  options     = {:verbose => true, :force => false, :algo => 'build-dir'}
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                  opts        = OptionParser.new
         | 
| 17 | 
            -
                  opts.banner = "Usage: tree.rb [options] [directory]"
         | 
| 18 | 
            -
                  opts.separator "list contents of directories in a tree-like format"
         | 
| 19 | 
            -
                  opts.separator "this is a almost :-) a clone of tree unix command written in ruby"
         | 
| 20 | 
            -
                  opts.separator "Code https://github.com/tokiro/treevisitor. Feedback to tokiro.oyama@gmail.com"
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                  opts.separator ""
         | 
| 23 | 
            -
                  opts.separator "options: "
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                  opts.on("-h", "--help", "Show this message") do
         | 
| 26 | 
            -
                    puts opts
         | 
| 27 | 
            -
                    return 0
         | 
| 28 | 
            -
                  end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                  opts.on("--version", "Show the version") do
         | 
| 31 | 
            -
                    puts "tree.rb version #{TreeVisitor::VERSION}"
         | 
| 32 | 
            -
                    return 0
         | 
| 33 | 
            -
                  end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                  opts.on("-a", "All file are listed") do |v|
         | 
| 36 | 
            -
                    options[:all_files] = true
         | 
| 37 | 
            -
                  end
         | 
| 38 | 
            -
             | 
| 39 | 
            -
                  opts.on("-d", "List directories only") do |v|
         | 
| 40 | 
            -
                    options[:only_directories] = true
         | 
| 41 | 
            -
                  end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                  opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
         | 
| 44 | 
            -
                    options[:verbose] = v
         | 
| 45 | 
            -
                  end
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                  opts.on("-q", "--quiet", "quiet mode as --no-verbose") do |v|
         | 
| 48 | 
            -
                    options[:verbose] = false
         | 
| 49 | 
            -
                  end
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                  algos        = %w[build-dir print-dir json yaml]
         | 
| 52 | 
            -
                  algo_aliases = {"b" => "build-dir", "v" => "print-dir", "j" => "json", "y" => "yaml"}
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                  algo_list    = (algo_aliases.keys + algos).join(',')
         | 
| 55 | 
            -
                  opts.on("-f", "--format ALGO", algos, algo_aliases, "select an algo", "  (#{algo_list})") do |algo|
         | 
| 56 | 
            -
                    options[:algo] = algo
         | 
| 57 | 
            -
                  end
         | 
| 58 | 
            -
             | 
| 59 | 
            -
                  begin
         | 
| 60 | 
            -
                    rest = opts.parse(argv)
         | 
| 61 | 
            -
                  rescue OptionParser::InvalidOption => e
         | 
| 62 | 
            -
                    $stderr.puts e.to_s
         | 
| 63 | 
            -
                    $stderr.puts "try -h for help"
         | 
| 64 | 
            -
                    return false
         | 
| 65 | 
            -
                  end
         | 
| 66 | 
            -
             | 
| 67 | 
            -
                  if rest.length < 1
         | 
| 68 | 
            -
                    dirname = Dir.pwd
         | 
| 69 | 
            -
                  else
         | 
| 70 | 
            -
                    dirname = rest[0]
         | 
| 71 | 
            -
                  end
         | 
| 72 | 
            -
             | 
| 73 | 
            -
                  dirname = File.expand_path(dirname)
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                  dtw     = DirTreeWalker.new(dirname)
         | 
| 76 | 
            -
                  unless options[:all_files]
         | 
| 77 | 
            -
                    dtw.ignore(/^\.[^.]+/) # ignore all file starting with "."
         | 
| 78 | 
            -
                  end
         | 
| 79 | 
            -
             | 
| 80 | 
            -
                  dtw.visit_file = !options[:only_directories]
         | 
| 81 | 
            -
             | 
| 82 | 
            -
                  case options[:algo]
         | 
| 83 | 
            -
                    when 'build-dir'
         | 
| 84 | 
            -
                      visitor = BuildDirTreeVisitor.new
         | 
| 85 | 
            -
                      dtw.run(visitor)
         | 
| 86 | 
            -
                      puts visitor.root.to_str
         | 
| 87 | 
            -
                      puts
         | 
| 88 | 
            -
                      puts "#{visitor.nr_directories} directories, #{visitor.nr_files} files"
         | 
| 89 | 
            -
                    when 'print-dir'
         | 
| 90 | 
            -
                      visitor = PrintDirTreeVisitor.new
         | 
| 91 | 
            -
                      dtw.run(visitor)
         | 
| 92 | 
            -
                    when 'json'
         | 
| 93 | 
            -
                      root = dtw.run(DirectoryToHashVisitor.new(dirname)).root
         | 
| 94 | 
            -
                      puts JSON.pretty_generate(root)
         | 
| 95 | 
            -
                    when 'yaml'
         | 
| 96 | 
            -
                      root = dtw.run(DirectoryToHashVisitor.new(dirname)).root
         | 
| 97 | 
            -
                      puts root.to_yaml
         | 
| 98 | 
            -
                    else
         | 
| 99 | 
            -
                      puts "unknown algo #{options[:algo]} specified"
         | 
| 100 | 
            -
                  end
         | 
| 101 | 
            -
             | 
| 102 | 
            -
                  0
         | 
| 103 | 
            -
                end
         | 
| 104 | 
            -
             | 
| 105 | 
            -
              end
         | 
| 106 | 
            -
            end
         | 
| @@ -1,300 +0,0 @@ | |
| 1 | 
            -
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            -
            module TreeVisitor
         | 
| 3 | 
            -
             | 
| 4 | 
            -
              #
         | 
| 5 | 
            -
              # Visit a file system directory
         | 
| 6 | 
            -
              #
         | 
| 7 | 
            -
              class DirTreeWalker
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                # Build a tree walker.
         | 
| 10 | 
            -
                # Visit a director starting from dirname
         | 
| 11 | 
            -
                # if dirname is missing, must be supplied when invoking run
         | 
| 12 | 
            -
                #
         | 
| 13 | 
            -
                # @yield [a, b, c] TreeNodeVisitor
         | 
| 14 | 
            -
                # @yieldparam [optional, types, ...] argname description
         | 
| 15 | 
            -
                # @yieldreturn [optional, types, ...] description
         | 
| 16 | 
            -
                #
         | 
| 17 | 
            -
                # @overload initialize(dirname)
         | 
| 18 | 
            -
                #   @param [String] dirname the root of the tree (top level directory)
         | 
| 19 | 
            -
                #
         | 
| 20 | 
            -
                # @overload initialize(dirname, options)
         | 
| 21 | 
            -
                #   @param [Hash] options
         | 
| 22 | 
            -
                #   @option options [String,Regex, Array<String,Regexp>] :ignore list of ignore pattern
         | 
| 23 | 
            -
                #   @option options [String] :ignore_dir
         | 
| 24 | 
            -
                #   @option options [String] :ignore_file
         | 
| 25 | 
            -
                #   @option options [String] :match
         | 
| 26 | 
            -
                #
         | 
| 27 | 
            -
                #
         | 
| 28 | 
            -
                # @example Print the contents of tmp directory
         | 
| 29 | 
            -
                #   DirTreeWalker.new("/tmp") do
         | 
| 30 | 
            -
                #     on_visit_leaf_node { |pathname| puts pathname }
         | 
| 31 | 
            -
                #   end.run
         | 
| 32 | 
            -
                #
         | 
| 33 | 
            -
                def initialize(dirname = nil, options = nil)
         | 
| 34 | 
            -
                  #
         | 
| 35 | 
            -
                  # arg detection
         | 
| 36 | 
            -
                  #
         | 
| 37 | 
            -
                  if dirname and dirname.respond_to?(:key?)
         | 
| 38 | 
            -
                    options = dirname
         | 
| 39 | 
            -
                    dirname = nil
         | 
| 40 | 
            -
                  end
         | 
| 41 | 
            -
             | 
| 42 | 
            -
                  if dirname
         | 
| 43 | 
            -
                    @dirname = dirname
         | 
| 44 | 
            -
                    unless File.directory?(dirname)
         | 
| 45 | 
            -
                      raise "#{dirname} is not a directory!"
         | 
| 46 | 
            -
                    end
         | 
| 47 | 
            -
                  end
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                  @visitor              = nil
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                  #
         | 
| 52 | 
            -
                  # pattern
         | 
| 53 | 
            -
                  #
         | 
| 54 | 
            -
                  @ignore_dir_patterns  = []
         | 
| 55 | 
            -
                  @ignore_file_patterns = []
         | 
| 56 | 
            -
                  @match_file_patterns  = []
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                  if options and options[:ignore]
         | 
| 59 | 
            -
                    unless options[:ignore].respond_to?(:at)
         | 
| 60 | 
            -
                      options[:ignore] = [options[:ignore]]
         | 
| 61 | 
            -
                    end
         | 
| 62 | 
            -
                    options[:ignore].each { |p| ignore(p) }
         | 
| 63 | 
            -
                  end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                  if options and options[:ignore_dir]
         | 
| 66 | 
            -
                    unless options[:ignore_dir].respond_to?(:at)
         | 
| 67 | 
            -
                      options[:ignore_dir] = [options[:ignore_dir]]
         | 
| 68 | 
            -
                    end
         | 
| 69 | 
            -
                    options[:ignore_dir].each { |p| ignore_dir(p) }
         | 
| 70 | 
            -
                  end
         | 
| 71 | 
            -
             | 
| 72 | 
            -
                  if options and options[:ignore_file]
         | 
| 73 | 
            -
                    unless options[:ignore_file].respond_to?(:at)
         | 
| 74 | 
            -
                      options[:ignore_file] = [options[:ignore_file]]
         | 
| 75 | 
            -
                    end
         | 
| 76 | 
            -
                    options[:ignore_file].each { |p| ignore_file(p) }
         | 
| 77 | 
            -
                  end
         | 
| 78 | 
            -
             | 
| 79 | 
            -
                  if options and options[:match]
         | 
| 80 | 
            -
                    unless options[:match].respond_to?(:at)
         | 
| 81 | 
            -
                      options[:match] = [options[:match]]
         | 
| 82 | 
            -
                    end
         | 
| 83 | 
            -
                    options[:match].each { |p| match(p) }
         | 
| 84 | 
            -
                  end
         | 
| 85 | 
            -
             | 
| 86 | 
            -
                  #
         | 
| 87 | 
            -
                  # options
         | 
| 88 | 
            -
                  #
         | 
| 89 | 
            -
                  @visit_file = true
         | 
| 90 | 
            -
                end
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                ##########################################################################
         | 
| 93 | 
            -
                # Pattern
         | 
| 94 | 
            -
             | 
| 95 | 
            -
                #
         | 
| 96 | 
            -
                # Ignore a node (leaf/Tree) matching pattern
         | 
| 97 | 
            -
                # @param [RegEx] pattern
         | 
| 98 | 
            -
                #
         | 
| 99 | 
            -
                def ignore(pattern)
         | 
| 100 | 
            -
                  @ignore_dir_patterns << pattern
         | 
| 101 | 
            -
                  @ignore_file_patterns << pattern
         | 
| 102 | 
            -
                  self
         | 
| 103 | 
            -
                end
         | 
| 104 | 
            -
             | 
| 105 | 
            -
                #
         | 
| 106 | 
            -
                # Ignore a directory (Tree) matching pattern
         | 
| 107 | 
            -
                # @param [RegEx] pattern
         | 
| 108 | 
            -
                #
         | 
| 109 | 
            -
                def ignore_dir(pattern)
         | 
| 110 | 
            -
                  @ignore_dir_patterns << pattern
         | 
| 111 | 
            -
                  self
         | 
| 112 | 
            -
                end
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                #
         | 
| 115 | 
            -
                # Ignore a file (Leaf) matching pattern
         | 
| 116 | 
            -
                # @param [RegEx] pattern
         | 
| 117 | 
            -
                #
         | 
| 118 | 
            -
                def ignore_file(pattern)
         | 
| 119 | 
            -
                  @ignore_file_patterns << pattern
         | 
| 120 | 
            -
                  self
         | 
| 121 | 
            -
                end
         | 
| 122 | 
            -
             | 
| 123 | 
            -
                #
         | 
| 124 | 
            -
                # Just the opposite of ignore
         | 
| 125 | 
            -
                # directory/file matching pattern will be visited
         | 
| 126 | 
            -
                #
         | 
| 127 | 
            -
                # @param [RegEx] pattern
         | 
| 128 | 
            -
                #
         | 
| 129 | 
            -
                def match(pattern)
         | 
| 130 | 
            -
                  @match_file_patterns << pattern
         | 
| 131 | 
            -
                  self
         | 
| 132 | 
            -
                end
         | 
| 133 | 
            -
             | 
| 134 | 
            -
                ##########################################################################
         | 
| 135 | 
            -
                # Options
         | 
| 136 | 
            -
             | 
| 137 | 
            -
                #
         | 
| 138 | 
            -
                # it is true to visit file
         | 
| 139 | 
            -
                #
         | 
| 140 | 
            -
                attr_accessor :visit_file
         | 
| 141 | 
            -
             | 
| 142 | 
            -
                ##########################################################################
         | 
| 143 | 
            -
             | 
| 144 | 
            -
                #
         | 
| 145 | 
            -
                # Test directory ignore pattern
         | 
| 146 | 
            -
                #
         | 
| 147 | 
            -
                # @param [String] directory name
         | 
| 148 | 
            -
                # @return [boolean] if dirname match almost one pattern
         | 
| 149 | 
            -
                #
         | 
| 150 | 
            -
                def ignore_dir?(dirname)
         | 
| 151 | 
            -
                  _include?(@ignore_dir_patterns, File.basename(dirname))
         | 
| 152 | 
            -
                end
         | 
| 153 | 
            -
             | 
| 154 | 
            -
                #
         | 
| 155 | 
            -
                # Test file ignore pattern
         | 
| 156 | 
            -
                #
         | 
| 157 | 
            -
                # @param [String] file name
         | 
| 158 | 
            -
                # @return [boolean] if filename match almost one pattern
         | 
| 159 | 
            -
                #
         | 
| 160 | 
            -
                def ignore_file?(filename)
         | 
| 161 | 
            -
                  _include?(@ignore_file_patterns, File.basename(filename))
         | 
| 162 | 
            -
                end
         | 
| 163 | 
            -
             | 
| 164 | 
            -
                #
         | 
| 165 | 
            -
                # Test common ignore pattern
         | 
| 166 | 
            -
                #
         | 
| 167 | 
            -
                # @param [String] file name
         | 
| 168 | 
            -
                # @return [boolean] if filename match almost one pattern
         | 
| 169 | 
            -
                #
         | 
| 170 | 
            -
                def match?(filename)
         | 
| 171 | 
            -
                  return true if @match_file_patterns.empty?
         | 
| 172 | 
            -
                  _include?(@match_file_patterns, File.basename(filename))
         | 
| 173 | 
            -
                end
         | 
| 174 | 
            -
             | 
| 175 | 
            -
                #
         | 
| 176 | 
            -
                # Run the visitor through the directory tree
         | 
| 177 | 
            -
                #
         | 
| 178 | 
            -
                # @overload run
         | 
| 179 | 
            -
                #
         | 
| 180 | 
            -
                # @overload run(dirname)
         | 
| 181 | 
            -
                #   @param [String] dirname
         | 
| 182 | 
            -
                #   @yield define TreeNodeVisitor
         | 
| 183 | 
            -
                #
         | 
| 184 | 
            -
                # @overload run(tree_node_visitor)
         | 
| 185 | 
            -
                #   @param [TreeNodeVisitor]
         | 
| 186 | 
            -
                #   @yield define TreeNodeVisitor
         | 
| 187 | 
            -
                #
         | 
| 188 | 
            -
                # @overload run(dirname, tree_node_visitor)
         | 
| 189 | 
            -
                #   @param [String] dirname
         | 
| 190 | 
            -
                #   @param [TreeNodeVisitor]
         | 
| 191 | 
            -
                #   @yield define TreeNodeVisitor
         | 
| 192 | 
            -
                #
         | 
| 193 | 
            -
                # @return [TreeNodeVisitor] the visitor
         | 
| 194 | 
            -
                #
         | 
| 195 | 
            -
                # @example Print the contents of tmp directory
         | 
| 196 | 
            -
                #   w = DirTreeWalker.new
         | 
| 197 | 
            -
                #   w.run("/tmp") do
         | 
| 198 | 
            -
                #     on_visit_leaf_node { |pathname| puts pathname }
         | 
| 199 | 
            -
                #   end.run
         | 
| 200 | 
            -
                #
         | 
| 201 | 
            -
                def run(dirname = nil, tree_node_visitor = nil, &block)
         | 
| 202 | 
            -
             | 
| 203 | 
            -
                  #
         | 
| 204 | 
            -
                  # args detection
         | 
| 205 | 
            -
                  #
         | 
| 206 | 
            -
                  if dirname and dirname.respond_to?(:enter_node)
         | 
| 207 | 
            -
                    tree_node_visitor = dirname
         | 
| 208 | 
            -
                    dirname           = nil
         | 
| 209 | 
            -
                  end
         | 
| 210 | 
            -
             | 
| 211 | 
            -
                  #
         | 
| 212 | 
            -
                  # check dirname
         | 
| 213 | 
            -
                  #
         | 
| 214 | 
            -
                  if @dirname.nil? and dirname.nil?
         | 
| 215 | 
            -
                    raise "missing starting directory"
         | 
| 216 | 
            -
                  end
         | 
| 217 | 
            -
                  @dirname = dirname if dirname
         | 
| 218 | 
            -
             | 
| 219 | 
            -
                  #
         | 
| 220 | 
            -
                  # check visitor
         | 
| 221 | 
            -
                  #
         | 
| 222 | 
            -
                  if tree_node_visitor and block
         | 
| 223 | 
            -
                    raise "cannot use block and parameter together"
         | 
| 224 | 
            -
                  end
         | 
| 225 | 
            -
             | 
| 226 | 
            -
                  if tree_node_visitor
         | 
| 227 | 
            -
                    @visitor = tree_node_visitor
         | 
| 228 | 
            -
                  end
         | 
| 229 | 
            -
             | 
| 230 | 
            -
                  if block
         | 
| 231 | 
            -
                    @visitor = TreeNodeVisitor.new(&block)
         | 
| 232 | 
            -
                  end
         | 
| 233 | 
            -
             | 
| 234 | 
            -
                  unless @visitor
         | 
| 235 | 
            -
                    raise "missing visitor"
         | 
| 236 | 
            -
                  end
         | 
| 237 | 
            -
             | 
| 238 | 
            -
                  #
         | 
| 239 | 
            -
                  # finally starts to process
         | 
| 240 | 
            -
                  #
         | 
| 241 | 
            -
                  process_directory(File.expand_path(@dirname))
         | 
| 242 | 
            -
                  @visitor
         | 
| 243 | 
            -
                end
         | 
| 244 | 
            -
             | 
| 245 | 
            -
                private
         | 
| 246 | 
            -
             | 
| 247 | 
            -
                def _include?(patterns, basename)
         | 
| 248 | 
            -
                  # return false if the patters.empty?
         | 
| 249 | 
            -
                  patterns.find { |pattern|
         | 
| 250 | 
            -
                    if pattern.kind_of? Regexp
         | 
| 251 | 
            -
                      pattern.match(basename)
         | 
| 252 | 
            -
                    else
         | 
| 253 | 
            -
                      basename == pattern
         | 
| 254 | 
            -
                    end
         | 
| 255 | 
            -
                  }
         | 
| 256 | 
            -
                end
         | 
| 257 | 
            -
             | 
| 258 | 
            -
                #
         | 
| 259 | 
            -
                # recurse on other directories
         | 
| 260 | 
            -
                #
         | 
| 261 | 
            -
                def process_directory(dirname)
         | 
| 262 | 
            -
                  # return if ignore_dir?( dirname )
         | 
| 263 | 
            -
             | 
| 264 | 
            -
                  begin
         | 
| 265 | 
            -
                    entries = Dir.entries(dirname).sort
         | 
| 266 | 
            -
                  rescue Errno::EACCES => e
         | 
| 267 | 
            -
                    $stderr.puts e
         | 
| 268 | 
            -
                    @visitor.cannot_enter_node(dirname, e)
         | 
| 269 | 
            -
                    return
         | 
| 270 | 
            -
                  rescue  Errno::EPERM => e
         | 
| 271 | 
            -
                    $stderr.puts e
         | 
| 272 | 
            -
                    @visitor.cannot_enter_node(dirname, e)
         | 
| 273 | 
            -
                    return
         | 
| 274 | 
            -
                  end
         | 
| 275 | 
            -
             | 
| 276 | 
            -
             | 
| 277 | 
            -
                  @visitor.enter_node(dirname)
         | 
| 278 | 
            -
                    entries.each { |basename|
         | 
| 279 | 
            -
                      begin
         | 
| 280 | 
            -
                      next if basename == "." or basename == ".." # ignore always "." and ".."
         | 
| 281 | 
            -
                      pathname = File.join(dirname, basename)
         | 
| 282 | 
            -
             | 
| 283 | 
            -
                      if File.directory?(pathname)
         | 
| 284 | 
            -
                        process_directory(pathname) unless ignore_dir?(basename)
         | 
| 285 | 
            -
                      else
         | 
| 286 | 
            -
                        if !!@visit_file && match?(basename) && !ignore_file?(basename)
         | 
| 287 | 
            -
                          @visitor.visit_leaf(pathname)
         | 
| 288 | 
            -
                        end
         | 
| 289 | 
            -
                      end
         | 
| 290 | 
            -
                      rescue Errno::EACCES => e
         | 
| 291 | 
            -
                        $stderr.puts e
         | 
| 292 | 
            -
                      rescue  Errno::EPERM
         | 
| 293 | 
            -
                        $stderr.puts e
         | 
| 294 | 
            -
                      end
         | 
| 295 | 
            -
                    }
         | 
| 296 | 
            -
             | 
| 297 | 
            -
                  @visitor.exit_node(dirname)
         | 
| 298 | 
            -
                end
         | 
| 299 | 
            -
              end
         | 
| 300 | 
            -
            end
         |