treevisitor 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/LICENSE.txt +20 -0
  2. data/README.rdoc +42 -0
  3. data/Rakefile +9 -0
  4. data/VERSION.yml +5 -0
  5. data/bin/tree.rb +9 -0
  6. data/examples/find_files.rb +17 -0
  7. data/examples/print_files.rb +15 -0
  8. data/lib/tree_visitor.rb +2 -0
  9. data/lib/treevisitor.rb +31 -0
  10. data/lib/treevisitor/abs_node.rb +146 -0
  11. data/lib/treevisitor/cli/cli_tree.rb +98 -0
  12. data/lib/treevisitor/dir_processor.rb +46 -0
  13. data/lib/treevisitor/dir_tree_walker.rb +164 -0
  14. data/lib/treevisitor/leaf_node.rb +33 -0
  15. data/lib/treevisitor/tree_node.rb +247 -0
  16. data/lib/treevisitor/tree_node_visitor.rb +29 -0
  17. data/lib/treevisitor/visitors/block_tree_node_visitor.rb +21 -0
  18. data/lib/treevisitor/visitors/build_dir_tree_visitor.rb +53 -0
  19. data/lib/treevisitor/visitors/callback_tree_node_visitor.rb +43 -0
  20. data/lib/treevisitor/visitors/callback_tree_node_visitor2.rb +61 -0
  21. data/lib/treevisitor/visitors/clone_tree_node_visitor.rb +39 -0
  22. data/lib/treevisitor/visitors/depth_tree_node_visitor.rb +27 -0
  23. data/lib/treevisitor/visitors/flat_print_tree_node_visitors.rb +20 -0
  24. data/lib/treevisitor/visitors/print_dir_tree_visitor.rb +21 -0
  25. data/lib/treevisitor/visitors/print_tree_node_visitor.rb +40 -0
  26. data/lib/treevisitor_cli.rb +7 -0
  27. data/spec/fixtures/test_dir/.dir_with_dot/dummy.txt +0 -0
  28. data/spec/fixtures/test_dir/dir.1/dir.1.2/file.1.2.1 +0 -0
  29. data/spec/fixtures/test_dir/dir.1/file.1.1 +0 -0
  30. data/spec/fixtures/test_dir/dir.2/file.2.1 +0 -0
  31. data/spec/spec_helper.rb +29 -0
  32. data/spec/treevisitor/cli/cli_tree_spec.rb +58 -0
  33. data/spec/treevisitor/dir_processor_spec.rb +15 -0
  34. data/spec/treevisitor/dir_tree_walker_spec.rb +33 -0
  35. data/spec/treevisitor/tree_node_dsl_spec.rb +153 -0
  36. data/spec/treevisitor/tree_node_spec.rb +153 -0
  37. data/spec/treevisitor/tree_node_visitor_spec.rb +70 -0
  38. data/tasks/jeweler.rake +55 -0
  39. data/tasks/rspec.rake +34 -0
  40. data/tasks/rubyforge.rake +28 -0
  41. data/tasks/yard.rake +36 -0
  42. metadata +192 -0
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TreeVisitor
3
+ #
4
+ # It calls a block when visit a tree_node or leaf_node
5
+ #
6
+ class BlockTreeNodeVisitor < TreeNodeVisitor
7
+
8
+ def initialize( &action )
9
+ @block = action
10
+ end
11
+
12
+ def enter_tree_node( tree_node )
13
+ @block.call( tree_node )
14
+ end
15
+
16
+ def visit_leaf_node( leaf_node )
17
+ @block.call( leaf_node )
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,53 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TreeVisitor
3
+ #
4
+ # Builds a TreeNode from a filesystem directory
5
+ # It similar to CloneTreeNodeVisitor
6
+ #
7
+ class BuildDirTreeVisitor < TreeNodeVisitor
8
+
9
+ attr_reader :root
10
+
11
+ #
12
+ # Number of visited directory (aka nr_nodes - nr_leaf)
13
+ #
14
+ attr_reader :nr_directories
15
+
16
+
17
+ #
18
+ # Number of visited directory (nr_leaves)
19
+ # @see AbsNode#nr_leaves
20
+ #
21
+ attr_reader :nr_files
22
+
23
+ def initialize
24
+ super
25
+ @root = nil
26
+ @stack = []
27
+ @nr_directories = 0
28
+ @nr_files = 0
29
+ end
30
+
31
+ def enter_tree_node( pathname )
32
+ if @stack.empty?
33
+ tree_node = TreeNode.new( File.basename( pathname ) )
34
+ @root = tree_node
35
+ else
36
+ tree_node = TreeNode.new( File.basename( pathname ), @stack.last )
37
+ end
38
+ @nr_directories += 1
39
+ @stack.push( tree_node )
40
+ end
41
+
42
+ def exit_tree_node( pathname )
43
+ @stack.pop
44
+ end
45
+
46
+ def visit_leaf_node( pathname )
47
+ @nr_files += 1
48
+ # connect the leaf_node created to the last tree_node on the stack
49
+ LeafNode.new( File.basename(pathname), @stack.last )
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,43 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TreeVisitor
3
+ #
4
+ # Executes a block when enter in a node
5
+ # The block are defined from on_enter_X methods
6
+ # The blocks take as argument only the node
7
+ #
8
+ class CallbackTreeNodeVisitor < TreeNodeVisitor
9
+
10
+ def initialize
11
+ super()
12
+ @root = nil
13
+ @stack = []
14
+ @action_enter_tree_node = nil
15
+ @action_visit_leaf_node = nil
16
+ end
17
+
18
+ def on_enter_tree_node( &action )
19
+ @action_enter_tree_node = action
20
+ end
21
+
22
+ def on_visit_leaf_node( &action )
23
+ @action_visit_leaf_node = action
24
+ end
25
+
26
+ def enter_tree_node( tree_node )
27
+ # parent_node = @stack.empty? ? nil : @stack.last
28
+ @root = tree_node if @stack.empty?
29
+ @stack.push( tree_node )
30
+ @action_enter_tree_node.call( tree_node ) if @action_enter_tree_node
31
+ end
32
+
33
+ def exit_tree_node( tree_node )
34
+ @stack.pop
35
+ end
36
+
37
+ def visit_leaf_node( leaf_node )
38
+ # parent_node = @stack.last
39
+ @action_visit_leaf_node.call( leaf_node ) if @action_visit_leaf_node
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,61 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TreeVisitor
3
+ #
4
+ # Executes a block when enter in a node
5
+ # The block are defined from on_enter_X methods
6
+ # The blocks take as argument the node and the parent_node
7
+ #
8
+ class CallbackTreeNodeVisitor2 < TreeNodeVisitor
9
+
10
+ attr_reader :root
11
+
12
+ def initialize( delegate = nil)
13
+ super()
14
+ @stack = []
15
+ @root = nil
16
+ @delegate = delegate
17
+ end
18
+
19
+ def on_enter_tree_node( &action )
20
+ @action_enter_tree_node = action
21
+ end
22
+
23
+ def on_visit_leaf_node( &action )
24
+ @action_visit_leaf_node = action
25
+ end
26
+
27
+ def _on_enter_tree_node( src_tree_node, dst_parent_node )
28
+ if @action_enter_tree_node
29
+ dst_tree_node = @action_enter_tree_node.call( src_tree_node, dst_parent_node )
30
+ elsif @delegate
31
+ dst_tree_node = @delegate.on_enter_tree_node( src_tree_node, dst_parent_node )
32
+ end
33
+ dst_tree_node
34
+ end
35
+
36
+ def _on_visit_leaf_node( src_leaf_node, parent_node )
37
+ if @action_visit_leaf_node
38
+ @action_visit_leaf_node.call( src_leaf_node, parent_node )
39
+ elsif @delegate
40
+ @delegate.on_visit_leaf_node( src_leaf_node, parent_node )
41
+ end
42
+ end
43
+
44
+ def enter_tree_node( src_tree_node )
45
+ dst_parent_node = @stack.empty? ? nil : @stack.last
46
+ dst_tree_node = _on_enter_tree_node( src_tree_node, dst_parent_node )
47
+ @root = dst_tree_node if @stack.empty?
48
+ @stack.push( dst_tree_node )
49
+ end
50
+
51
+ def exit_tree_node( src_tree_node )
52
+ @stack.pop
53
+ end
54
+
55
+ def visit_leaf_node( src_leaf_node )
56
+ parent_node = @stack.last
57
+ _on_visit_leaf_node( src_leaf_node, parent_node )
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TreeVisitor
3
+ #
4
+ # Clone a tree_node, nodes are duplicated.
5
+ # Node content are not duplicated!
6
+ #
7
+ class CloneTreeNodeVisitor < TreeNodeVisitor
8
+
9
+ #
10
+ # Contains the cloned tree node after the visit
11
+ #
12
+ attr_reader :cloned_root
13
+
14
+ def initialize
15
+ super
16
+ @cloned_root = nil
17
+ @stack = []
18
+ end
19
+
20
+ def enter_tree_node( tree_node )
21
+ if @stack.empty?
22
+ cloned_tree_node = TreeNode.new( tree_node.content )
23
+ @cloned_root = cloned_tree_node
24
+ else
25
+ cloned_tree_node = TreeNode.new( tree_node.content, @stack.last )
26
+ end
27
+ @stack.push( cloned_tree_node )
28
+ end
29
+
30
+ def exit_tree_node( tree_node )
31
+ @stack.pop
32
+ end
33
+
34
+ def visit_leaf_node( leaf_node )
35
+ LeafNode.new( leaf_node.content, @stack.last )
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TreeVisitor
3
+ #
4
+ # Simple visitor: show how calculate the depth of a tree
5
+ #
6
+ class DepthTreeNodeVisitor < TreeNodeVisitor
7
+
8
+ attr_reader :depth
9
+
10
+ def initialize
11
+ super
12
+ @depth = 0
13
+ end
14
+
15
+ def enter_tree_node( tree_node )
16
+ @depth += 1
17
+ end
18
+
19
+ def exit_tree_node( tree_node )
20
+ @depth -= 1
21
+ end
22
+
23
+ def visit_leaf_node( leaf_node )
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TreeVisitor
3
+ #
4
+ # Print for every node the name
5
+ #
6
+ class FlatPrintTreeNodeVisitor < TreeNodeVisitor
7
+
8
+ def enter_tree_node( tree_node )
9
+ puts tree_node.name
10
+ end
11
+
12
+ def exit_tree_node( tree_node )
13
+ end
14
+
15
+ def visit_leaf_node( leaf_node )
16
+ puts leaf_node.name
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TreeVisitor
3
+ #
4
+ # Visitor for DirTreeWalker
5
+ # Prints the node at enter
6
+ # TODO: join this con PrintTreeNodeVisitor
7
+ class PrintDirTreeVisitor < TreeNodeVisitor
8
+
9
+ def enter_tree_node( pathname )
10
+ puts pathname
11
+ end
12
+
13
+ def exit_tree_node( pathname )
14
+ end
15
+
16
+ def visit_leaf_node( pathname )
17
+ puts pathname
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,40 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TreeVisitor
3
+ #
4
+ # Prints TreeNode names indenting according to depth
5
+ #
6
+ class PrintTreeNodeVisitor < TreeNodeVisitor
7
+
8
+ def initialize
9
+ @depth = 0
10
+ end
11
+
12
+ def enter_tree_node( tree_node )
13
+ str = ""
14
+ (0...@depth).step {
15
+ str << " |-"
16
+ }
17
+
18
+ if @depth == 0
19
+ puts str + tree_node.name.to_s
20
+ else
21
+ puts str + tree_node.name.to_s
22
+ end
23
+ @depth += 1
24
+ end
25
+
26
+ def exit_tree_node( tree_node )
27
+ @depth -= 1
28
+ end
29
+
30
+ def visit_leaf_node( leaf_node )
31
+ str = ""
32
+ (0...@depth-1).step {
33
+ str << " |-"
34
+ }
35
+ str << " | "
36
+ puts str + leaf_node.name.to_s
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,7 @@
1
+ #
2
+ # cli
3
+ #
4
+
5
+ require 'optparse'
6
+ require 'treevisitor'
7
+ require "treevisitor/cli/cli_tree"
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,29 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'treevisitor'
5
+ require 'treevisitor_cli'
6
+
7
+ include TreeVisitor
8
+
9
+ TEST_DIR = File.expand_path( File.join( File.dirname(__FILE__), "fixtures", "test_dir" ) )
10
+
11
+
12
+ # Spec::Runner.configure do |config|
13
+ # end
14
+
15
+
16
+ require 'test/unit'
17
+ require "stringio"
18
+
19
+ def with_stdout_captured
20
+ old_stdout = $stdout
21
+ out = StringIO.new
22
+ $stdout = out
23
+ begin
24
+ yield
25
+ ensure
26
+ $stdout = old_stdout
27
+ end
28
+ out.string
29
+ end
@@ -0,0 +1,58 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.join(File.dirname(__FILE__), "..", "..", "spec_helper")
3
+
4
+ describe CliTree do
5
+
6
+ it "help message" do
7
+ out = with_stdout_captured do
8
+ args = %w{-h}
9
+ CliTree.new.parse_args(args)
10
+ end
11
+ out.should match /Usage:/
12
+ end
13
+
14
+ it "version" do
15
+ out = with_stdout_captured do
16
+ args = %w{--version}
17
+ CliTree.new.parse_args(args)
18
+ end
19
+ version = "0.1.4"
20
+ out.should match version
21
+ end
22
+
23
+ it "should accepts switch -d (directories only)" do
24
+ out = with_stdout_captured do
25
+ args = %w{-d}
26
+ args << TEST_DIR
27
+ CliTree.new.parse_args(args)
28
+ end
29
+ # pp out
30
+ out.split("\n").length.should == 6
31
+
32
+ out = with_stdout_captured do
33
+ args = %w{-da}
34
+ args << TEST_DIR
35
+ CliTree.new.parse_args(args)
36
+ end
37
+ #puts out
38
+ out.split("\n").length.should == 7
39
+ end
40
+
41
+ it "should accepts switch -a (all files)" do
42
+ out = with_stdout_captured do
43
+ args = %w{-a}
44
+ args << TEST_DIR
45
+ CliTree.new.parse_args(args)
46
+ end
47
+ # pp out
48
+ out.split("\n").length.should == 11
49
+
50
+ out = with_stdout_captured do
51
+ args = []
52
+ args << TEST_DIR
53
+ CliTree.new.parse_args(args)
54
+ end
55
+ # puts out
56
+ out.split("\n").length.should == 9
57
+ end
58
+ end