treevisitor 0.1.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/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
|