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
|