treevisitor 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +20 -0
- data/README.rdoc +42 -0
- data/Rakefile +9 -0
- data/VERSION.yml +5 -0
- data/bin/tree.rb +9 -0
- data/examples/find_files.rb +17 -0
- data/examples/print_files.rb +15 -0
- data/lib/tree_visitor.rb +2 -0
- data/lib/treevisitor.rb +31 -0
- data/lib/treevisitor/abs_node.rb +146 -0
- data/lib/treevisitor/cli/cli_tree.rb +98 -0
- data/lib/treevisitor/dir_processor.rb +46 -0
- data/lib/treevisitor/dir_tree_walker.rb +164 -0
- data/lib/treevisitor/leaf_node.rb +33 -0
- data/lib/treevisitor/tree_node.rb +247 -0
- data/lib/treevisitor/tree_node_visitor.rb +29 -0
- data/lib/treevisitor/visitors/block_tree_node_visitor.rb +21 -0
- data/lib/treevisitor/visitors/build_dir_tree_visitor.rb +53 -0
- data/lib/treevisitor/visitors/callback_tree_node_visitor.rb +43 -0
- data/lib/treevisitor/visitors/callback_tree_node_visitor2.rb +61 -0
- data/lib/treevisitor/visitors/clone_tree_node_visitor.rb +39 -0
- data/lib/treevisitor/visitors/depth_tree_node_visitor.rb +27 -0
- data/lib/treevisitor/visitors/flat_print_tree_node_visitors.rb +20 -0
- data/lib/treevisitor/visitors/print_dir_tree_visitor.rb +21 -0
- data/lib/treevisitor/visitors/print_tree_node_visitor.rb +40 -0
- data/lib/treevisitor_cli.rb +7 -0
- data/spec/fixtures/test_dir/.dir_with_dot/dummy.txt +0 -0
- data/spec/fixtures/test_dir/dir.1/dir.1.2/file.1.2.1 +0 -0
- data/spec/fixtures/test_dir/dir.1/file.1.1 +0 -0
- data/spec/fixtures/test_dir/dir.2/file.2.1 +0 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/treevisitor/cli/cli_tree_spec.rb +58 -0
- data/spec/treevisitor/dir_processor_spec.rb +15 -0
- data/spec/treevisitor/dir_tree_walker_spec.rb +33 -0
- data/spec/treevisitor/tree_node_dsl_spec.rb +153 -0
- data/spec/treevisitor/tree_node_spec.rb +153 -0
- data/spec/treevisitor/tree_node_visitor_spec.rb +70 -0
- data/tasks/jeweler.rake +55 -0
- data/tasks/rspec.rake +34 -0
- data/tasks/rubyforge.rake +28 -0
- data/tasks/yard.rake +36 -0
- 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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/spec/spec_helper.rb
ADDED
@@ -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
|