tree.rb 0.3.4 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/tree_rb.rb +9 -4
- data/lib/tree_rb/cli/cli_tree.rb +176 -49
- data/lib/tree_rb/extension_digest.rb +42 -0
- data/lib/tree_rb/tree_node.rb +10 -6
- data/lib/tree_rb/version.rb +1 -1
- data/lib/tree_rb/visitors/build_dir_tree_visitor.rb +51 -29
- data/lib/tree_rb_cli.rb +1 -7
- data/spec/tree_rb/extension_digest_spec.rb +19 -0
- data/tree.rb.gemspec +11 -7
- metadata +22 -7
- data/lib/tree_rb/extension_md5.rb +0 -29
- data/spec/tree_rb/extension_md5_spec.rb +0 -8
data/lib/tree_rb.rb
CHANGED
@@ -12,16 +12,21 @@ require 'yaml'
|
|
12
12
|
# require 'rubygems' # rubygems must be loaded from binary file (tree.rb) so $LOAD_PATH is not modified
|
13
13
|
require 'json'
|
14
14
|
require 'ansi/code'
|
15
|
+
begin
|
16
|
+
require 'Win32/Console/ANSI' if RUBY_PLATFORM =~ /win32/
|
17
|
+
rescue LoadError
|
18
|
+
puts 'You must gem install win32console to use color on Windows'
|
19
|
+
end
|
15
20
|
|
16
21
|
#
|
17
22
|
# treevisitor
|
18
23
|
#
|
19
24
|
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
25
|
+
require 'tree_rb/version'
|
26
|
+
require 'tree_rb/extension_digest'
|
27
|
+
require 'tree_rb/extension_numeric'
|
23
28
|
|
24
|
-
require
|
29
|
+
require 'tree_rb/abs_node'
|
25
30
|
require 'tree_rb/leaf_node'
|
26
31
|
require 'tree_rb/tree_node'
|
27
32
|
require 'tree_rb/basic_tree_node_visitor'
|
data/lib/tree_rb/cli/cli_tree.rb
CHANGED
@@ -9,72 +9,81 @@ module TreeRb
|
|
9
9
|
self.new.parse_args(ARGV)
|
10
10
|
end
|
11
11
|
|
12
|
-
def parse_args(argv)
|
13
12
|
|
14
|
-
|
13
|
+
def options_parser(options)
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
parser = OptionParser.new
|
16
|
+
parser.banner = "Usage: tree.rb [options] [directory]"
|
17
|
+
parser.separator "list contents of directories in a tree-like format"
|
18
|
+
parser.separator "this is a almost :-) a clone of tree unix command written in ruby"
|
19
|
+
parser.separator "Code https://github.com/tokiro/treevisitor. Feedback to tokiro.oyama@gmail.com"
|
21
20
|
|
22
|
-
|
23
|
-
|
21
|
+
parser.separator ""
|
22
|
+
parser.separator "options: "
|
24
23
|
|
25
|
-
|
26
|
-
puts
|
27
|
-
|
24
|
+
parser.on("--help", "Show this message") do
|
25
|
+
puts parser
|
26
|
+
options[:exit] = 1
|
28
27
|
end
|
29
28
|
|
30
|
-
|
29
|
+
parser.on("--version", "Show the version") do
|
31
30
|
puts "tree.rb version #{TreeRb::VERSION}"
|
32
|
-
|
31
|
+
options[:exit] = 1
|
33
32
|
end
|
34
33
|
|
35
|
-
|
34
|
+
parser.on("-a", "All file are listed i.e. include dot files") do
|
36
35
|
options[:all_files] = true
|
37
36
|
end
|
38
37
|
|
39
|
-
|
38
|
+
parser.on("-d", "List directories only") do
|
40
39
|
options[:only_directories] = true
|
41
40
|
end
|
42
41
|
|
43
|
-
|
42
|
+
options[:only_files] = false
|
43
|
+
parser.on("--only-files", "show only file implies -i") do
|
44
|
+
options[:only_files] = true
|
45
|
+
options[:show_indentation] = false
|
46
|
+
end
|
47
|
+
|
48
|
+
parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
44
49
|
options[:verbose] = v
|
45
50
|
end
|
46
51
|
|
47
|
-
|
52
|
+
parser.on("-q", "--quiet", "quiet mode as --no-verbose") do
|
48
53
|
options[:verbose] = false
|
49
54
|
end
|
50
55
|
|
51
|
-
algos = %w[build-dir print-dir json yaml]
|
52
|
-
algo_aliases = { "b" => "build-dir", "v" => "print-dir", "j" => "json", "y" => "yaml" }
|
56
|
+
algos = %w[build-dir print-dir json yaml sqlite]
|
57
|
+
algo_aliases = { "b" => "build-dir", "v" => "print-dir", "j" => "json", "y" => "yaml", "s" => "sqlite" }
|
53
58
|
|
54
59
|
algo_list = (algo_aliases.keys + algos).join(',')
|
55
|
-
|
60
|
+
parser.on("--format ALGO", algos, algo_aliases, "select an algo", " (#{algo_list})") do |algo|
|
56
61
|
options[:algo] = algo
|
57
62
|
end
|
58
63
|
|
64
|
+
options[:show_full_path] = false
|
65
|
+
parser.on("-f", "Prints the full path prefix for each file.") do
|
66
|
+
options[:show_full_path] = true
|
67
|
+
end
|
68
|
+
|
59
69
|
#
|
60
70
|
# begin colorize
|
61
71
|
#
|
62
72
|
# copied from tree man page
|
63
|
-
|
64
|
-
options[:
|
73
|
+
parser.on("-n", "Turn colorization off always, over-ridden by the -C option.") do
|
74
|
+
options[:colorize_force] = false
|
65
75
|
end
|
66
76
|
|
67
77
|
# copied from tree man page
|
68
|
-
|
69
|
-
options[:
|
78
|
+
parser.on("-C", "Turn colorization on always, using built-in color defaults if the LS_COLORS environment variable is not set. Useful to colorize output to a pipe.") do
|
79
|
+
options[:colorize_force] = true
|
70
80
|
end
|
71
|
-
options[:colorize] ||= $stdout.isatty
|
72
81
|
|
73
82
|
#
|
74
83
|
# end colorize
|
75
84
|
#
|
76
85
|
|
77
|
-
|
86
|
+
parser.on("-s", "Print the size of each file in bytes along with the name.") do
|
78
87
|
options[:show_size] = true
|
79
88
|
end
|
80
89
|
|
@@ -83,48 +92,112 @@ module TreeRb
|
|
83
92
|
megabytes (M), gigabytes (G), terrabytes (T), petabytes (P) and exabytes (E).
|
84
93
|
EOS
|
85
94
|
|
86
|
-
|
95
|
+
parser.on("-h", msg) do
|
87
96
|
options[:show_size_human] = true
|
88
97
|
end
|
89
98
|
|
90
99
|
options[:show_indentation] = true
|
91
|
-
|
100
|
+
parser.on("-i", "Makes tree not print the indentation lines, useful when used in conjunction with the -f option.") do
|
92
101
|
options[:show_indentation] = false
|
93
102
|
end
|
94
103
|
|
95
104
|
options[:show_md5] = false
|
96
|
-
|
105
|
+
parser.on("--md5", "show md5 of file") do
|
97
106
|
options[:show_md5] = true
|
98
107
|
end
|
99
108
|
|
109
|
+
options[:show_sha1] = false
|
110
|
+
parser.on("--sha1", "show sha1 of a file") do
|
111
|
+
options[:show_sha1] = true
|
112
|
+
end
|
113
|
+
|
114
|
+
options[:show_md5sum] = false
|
115
|
+
parser.on("--md5sum", "show ake md5sum implies -i and --only-files") do
|
116
|
+
options[:only_files] = true
|
117
|
+
options[:show_md5sum] = true
|
118
|
+
options[:show_indentation] = false
|
119
|
+
end
|
120
|
+
|
121
|
+
options[:show_sha1sum] = false
|
122
|
+
parser.on("--md5sum", "show ake md5sum implies -i and --only-files") do
|
123
|
+
options[:only_files] = true
|
124
|
+
options[:show_sha1sum] = true
|
125
|
+
options[:show_indentation] = false
|
126
|
+
end
|
127
|
+
|
128
|
+
parser.on("-o [FILE]", "--output [FILE]", String) do |v|
|
129
|
+
if options[:output]
|
130
|
+
puts "only one file of output can be used"
|
131
|
+
options[:exit] = true
|
132
|
+
end
|
133
|
+
options[:output] = v
|
134
|
+
end
|
135
|
+
|
136
|
+
options[:force_overwrite_output] = false
|
137
|
+
parser.on("--force", "overwrite output") do
|
138
|
+
options[:force_overwrite_output] = true
|
139
|
+
end
|
140
|
+
|
141
|
+
parser
|
142
|
+
end
|
143
|
+
|
144
|
+
def parse_args(argv)
|
145
|
+
|
146
|
+
options = { :verbose => true, :force => false, :algo => 'build-dir' }
|
147
|
+
parser = options_parser(options)
|
148
|
+
|
100
149
|
begin
|
101
|
-
rest =
|
150
|
+
rest = parser.parse(argv)
|
102
151
|
rescue OptionParser::InvalidOption => e
|
103
152
|
$stderr.puts e.to_s
|
104
|
-
$stderr.puts "try
|
153
|
+
$stderr.puts "try --help for help"
|
105
154
|
return false
|
106
155
|
rescue OptionParser::MissingArgument => e
|
107
156
|
$stderr.puts e.to_s
|
108
|
-
$stderr.puts "try
|
157
|
+
$stderr.puts "try --help for help"
|
109
158
|
return false
|
110
159
|
end
|
111
160
|
|
161
|
+
unless options[:exit].nil?
|
162
|
+
return options[:exit]
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# option: output, force
|
167
|
+
#
|
168
|
+
output = $stdout
|
169
|
+
if options[:output]
|
170
|
+
filename = options[:output]
|
171
|
+
if File.exist?(filename) and not options[:force_overwrite_output]
|
172
|
+
$stderr.puts "catalog '#{filename}' exists use --force to overwrite"
|
173
|
+
return 0
|
174
|
+
end
|
175
|
+
output = File.open(filename, "w")
|
176
|
+
$stderr.puts "Writing file '#{filename}'"
|
177
|
+
end
|
178
|
+
|
179
|
+
if options[:colorize_force]
|
180
|
+
options[:colorize] = options[:colorize_force]
|
181
|
+
else
|
182
|
+
options[:colorize] = output.isatty
|
183
|
+
end
|
184
|
+
|
185
|
+
Signal.trap('INT') { puts "intercepted ctr+c"; exit }
|
186
|
+
|
112
187
|
if rest.length < 1
|
113
188
|
dirname = Dir.pwd
|
114
189
|
else
|
115
190
|
dirname = rest[0]
|
116
191
|
end
|
117
192
|
|
118
|
-
|
119
|
-
|
120
|
-
|
193
|
+
#
|
194
|
+
# 1. build dirtreewalker
|
195
|
+
#
|
121
196
|
dirname = File.expand_path(dirname)
|
122
|
-
|
123
|
-
dtw = DirTreeWalker.new(dirname)
|
197
|
+
dtw = DirTreeWalker.new(dirname)
|
124
198
|
unless options[:all_files]
|
125
199
|
dtw.ignore(/^\.[^.]+/) # ignore all file starting with "."
|
126
200
|
end
|
127
|
-
|
128
201
|
dtw.visit_file = !options[:only_directories]
|
129
202
|
|
130
203
|
case options[:algo]
|
@@ -132,26 +205,80 @@ module TreeRb
|
|
132
205
|
when 'build-dir'
|
133
206
|
# TODO: capture CTRL^C to avoid show the stack trace
|
134
207
|
# http://ruby-doc.org/core-1.9.3/Kernel.html#method-i-trap
|
135
|
-
Signal.trap('INT') { put "User interrupted exit"; exit }
|
136
208
|
|
137
209
|
visitor = BuildDirTreeVisitor.new(options)
|
138
210
|
dtw.run(visitor)
|
139
211
|
|
140
|
-
puts visitor.root.to_str('', options)
|
141
|
-
puts
|
142
|
-
puts "#{visitor.nr_directories} directories, #{visitor.nr_files} files"
|
212
|
+
output.puts visitor.root.to_str('', options)
|
213
|
+
output.puts
|
214
|
+
output.puts "#{visitor.nr_directories} directories, #{visitor.nr_files} files"
|
143
215
|
|
144
216
|
when 'print-dir'
|
145
217
|
visitor = PrintDirTreeVisitor.new
|
146
218
|
dtw.run(visitor)
|
147
219
|
|
148
220
|
when 'json'
|
149
|
-
|
150
|
-
|
221
|
+
visitor = DirectoryToHashVisitor.new(dirname)
|
222
|
+
root = dtw.run(visitor).root
|
223
|
+
output.puts JSON.pretty_generate(root)
|
151
224
|
|
152
225
|
when 'yaml'
|
153
|
-
|
154
|
-
|
226
|
+
visitor = DirectoryToHashVisitor.new(dirname)
|
227
|
+
root = dtw.run(visitor).root
|
228
|
+
output.puts root.to_yaml
|
229
|
+
|
230
|
+
when 'sqlite'
|
231
|
+
begin
|
232
|
+
require 'sqlite3'
|
233
|
+
unless options[:output]
|
234
|
+
$stderr.puts "need to specify the -o options"
|
235
|
+
else
|
236
|
+
output.close
|
237
|
+
filename = options[:output]
|
238
|
+
|
239
|
+
db = SQLite3::Database.new(filename)
|
240
|
+
db.execute("create table files(digest varchar(40),path varchar(1024))")
|
241
|
+
|
242
|
+
start = Time.now
|
243
|
+
me = self
|
244
|
+
bytes = 0
|
245
|
+
dtw.run do
|
246
|
+
on_leaf do |filename|
|
247
|
+
|
248
|
+
puts filename
|
249
|
+
digest = SHA1.file(filename).hexdigest
|
250
|
+
db.execute("insert into files values(\"#{digest}\",\"#{filename}\")")
|
251
|
+
|
252
|
+
# entry = Entry.from_filename(filename)
|
253
|
+
# me.add_entry(entry)
|
254
|
+
# bytes += entry.size
|
255
|
+
# if me.verbose_level > 0
|
256
|
+
# print "#{CR}#{filename}#{CLEAR}"
|
257
|
+
# end
|
258
|
+
# if me.show_progress
|
259
|
+
# sec = Time.now - start
|
260
|
+
# print "#{CR}bytes: #{bytes.to_human} time: #{sec} bytes/sec #{bytes/sec} #{CLEAR}"
|
261
|
+
# end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
# Loop through digests.
|
266
|
+
db.execute("select digest,count(1) as count from files group by digest order by count desc").each do |row|
|
267
|
+
if row[1] > 1 # Skip unique files.
|
268
|
+
puts "Duplicates found:"
|
269
|
+
digest = row[0]
|
270
|
+
# List the duplicate files.
|
271
|
+
db.execute("select digest,path from files where digest='#{digest}'").each do |dup_row|
|
272
|
+
puts "[#{digest}] #{dup_row[1]}"
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
end
|
278
|
+
|
279
|
+
rescue LoadError
|
280
|
+
puts 'You must gem install sqlite3 to use this output format'
|
281
|
+
end
|
155
282
|
|
156
283
|
else
|
157
284
|
puts "unknown algo #{options[:algo]} specified"
|
@@ -160,5 +287,5 @@ module TreeRb
|
|
160
287
|
0
|
161
288
|
end
|
162
289
|
|
163
|
-
end
|
164
|
-
end
|
290
|
+
end # end class
|
291
|
+
end # end module
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
if RUBY_VERSION =~ /1\.8/
|
4
|
+
# std lib
|
5
|
+
require 'md5'
|
6
|
+
else
|
7
|
+
# std lib
|
8
|
+
require 'digest/md5'
|
9
|
+
require 'digest/sha1'
|
10
|
+
include Digest
|
11
|
+
end
|
12
|
+
|
13
|
+
# Return an MD5 object
|
14
|
+
# example:
|
15
|
+
# MD5.file( filename ).hexdigest
|
16
|
+
#
|
17
|
+
class MD5
|
18
|
+
# calculate md5 of big files, snipped found on usenet
|
19
|
+
def self.file(file)
|
20
|
+
File.open(file, "rb") do |f|
|
21
|
+
digest = self.new
|
22
|
+
while (data = f.read(4096))
|
23
|
+
digest << data
|
24
|
+
end
|
25
|
+
digest
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
class SHA1
|
32
|
+
# Create a hash digest for the file.
|
33
|
+
def self.file(file)
|
34
|
+
digest = self.new
|
35
|
+
File.open(file, 'r') do |handle|
|
36
|
+
while (data = handle.read(1024))
|
37
|
+
digest << data
|
38
|
+
end
|
39
|
+
end
|
40
|
+
digest
|
41
|
+
end
|
42
|
+
end
|
data/lib/tree_rb/tree_node.rb
CHANGED
@@ -283,7 +283,9 @@ module TreeRb
|
|
283
283
|
|
284
284
|
# print node itself
|
285
285
|
if root?
|
286
|
-
|
286
|
+
unless options[:only_files]
|
287
|
+
str << node_content_to_str(content, options)
|
288
|
+
end
|
287
289
|
else
|
288
290
|
|
289
291
|
if show_indentation
|
@@ -295,9 +297,11 @@ module TreeRb
|
|
295
297
|
end
|
296
298
|
end
|
297
299
|
|
298
|
-
|
299
|
-
|
300
|
-
|
300
|
+
unless options[:only_files]
|
301
|
+
str << node_content_to_str(content, options)
|
302
|
+
if show_indentation
|
303
|
+
prefix += self.next ? CONT_1 : CONT_2
|
304
|
+
end
|
301
305
|
end
|
302
306
|
end
|
303
307
|
|
@@ -334,7 +338,7 @@ module TreeRb
|
|
334
338
|
private
|
335
339
|
|
336
340
|
def node_content_to_str(content, options)
|
337
|
-
if options[:
|
341
|
+
if options[:colorize]
|
338
342
|
"#{ANSI.red { content.to_str }}\n"
|
339
343
|
else
|
340
344
|
"#{content.to_str }\n"
|
@@ -342,7 +346,7 @@ module TreeRb
|
|
342
346
|
end
|
343
347
|
|
344
348
|
def leaf_content_to_str(content, options)
|
345
|
-
if options[:
|
349
|
+
if options[:colorize]
|
346
350
|
"#{ANSI.green { content.to_str }}\n"
|
347
351
|
else
|
348
352
|
"#{content.to_str }\n"
|
data/lib/tree_rb/version.rb
CHANGED
@@ -2,13 +2,19 @@
|
|
2
2
|
module TreeRb
|
3
3
|
|
4
4
|
#
|
5
|
-
# contains
|
5
|
+
# contains information related to directory (TreeNode)
|
6
6
|
#
|
7
7
|
class ContentDir
|
8
|
-
def initialize(
|
9
|
-
|
10
|
-
|
8
|
+
def initialize(pathname, options)
|
9
|
+
if options[:show_full_path]
|
10
|
+
file_name = pathname
|
11
|
+
else
|
12
|
+
file_name = File.basename(pathname)
|
13
|
+
end
|
14
|
+
|
15
|
+
@str = file_name
|
11
16
|
end
|
17
|
+
|
12
18
|
def to_str
|
13
19
|
@basename
|
14
20
|
end
|
@@ -18,24 +24,40 @@ module TreeRb
|
|
18
24
|
# contains information related to file (LeafNode)
|
19
25
|
#
|
20
26
|
class ContentFile
|
21
|
-
def initialize(
|
27
|
+
def initialize(pathname, options)
|
22
28
|
stat = File.lstat(pathname)
|
23
29
|
# stat.symlink?
|
24
30
|
|
31
|
+
if options[:show_full_path]
|
32
|
+
file_name = pathname
|
33
|
+
else
|
34
|
+
file_name = File.basename(pathname)
|
35
|
+
end
|
36
|
+
|
37
|
+
if options[:show_md5sum]
|
38
|
+
@str = "#{MD5.file(pathname).hexdigest} #{file_name}"
|
39
|
+
return
|
40
|
+
end
|
41
|
+
|
25
42
|
if options[:show_size]
|
26
|
-
str
|
43
|
+
str = "#{file_name} #{stat.size}"
|
27
44
|
elsif options[:show_size_human]
|
28
|
-
str
|
45
|
+
str = "#{file_name} #{stat.size.to_human}"
|
29
46
|
else
|
30
|
-
str
|
47
|
+
str = "#{file_name}"
|
31
48
|
end
|
32
|
-
|
49
|
+
|
33
50
|
if options[:show_md5]
|
34
|
-
str << " #{MD5.file(
|
51
|
+
str << " md5: #{MD5.file(pathname).hexdigest}"
|
52
|
+
end
|
53
|
+
|
54
|
+
if options[:show_sha1]
|
55
|
+
str << " sha1: #{SHA1.file(pathname).hexdigest}"
|
35
56
|
end
|
36
|
-
@str = str
|
37
57
|
|
58
|
+
@str = str
|
38
59
|
end
|
60
|
+
|
39
61
|
def to_str
|
40
62
|
@str
|
41
63
|
end
|
@@ -45,7 +67,7 @@ module TreeRb
|
|
45
67
|
# Builds a TreeNode from a filesystem directory
|
46
68
|
# It similar to CloneTreeNodeVisitor
|
47
69
|
#
|
48
|
-
class BuildDirTreeVisitor
|
70
|
+
class BuildDirTreeVisitor
|
49
71
|
|
50
72
|
attr_reader :root
|
51
73
|
|
@@ -59,39 +81,39 @@ module TreeRb
|
|
59
81
|
# @see AbsNode#nr_leaves
|
60
82
|
#
|
61
83
|
attr_reader :nr_files
|
62
|
-
|
63
|
-
def initialize(options = {})
|
64
|
-
@root
|
65
|
-
@stack
|
84
|
+
|
85
|
+
def initialize(options = { })
|
86
|
+
@root = nil
|
87
|
+
@stack = []
|
66
88
|
@nr_directories = 0
|
67
|
-
@nr_files
|
68
|
-
@options
|
89
|
+
@nr_files = 0
|
90
|
+
@options = options
|
69
91
|
end
|
70
92
|
|
71
|
-
def enter_node(
|
72
|
-
content = ContentDir.new(
|
93
|
+
def enter_node(pathname)
|
94
|
+
content = ContentDir.new(pathname, @options)
|
73
95
|
if @stack.empty?
|
74
|
-
tree_node = TreeNode.new(
|
75
|
-
@root
|
96
|
+
tree_node = TreeNode.new(content)
|
97
|
+
@root = tree_node
|
76
98
|
else
|
77
|
-
tree_node = TreeNode.new(
|
99
|
+
tree_node = TreeNode.new(content, @stack.last)
|
78
100
|
end
|
79
101
|
@nr_directories += 1
|
80
|
-
@stack.push(
|
102
|
+
@stack.push(tree_node)
|
81
103
|
end
|
82
104
|
|
83
105
|
def cannot_enter_node(pathname, error)
|
84
106
|
end
|
85
107
|
|
86
|
-
def exit_node(
|
108
|
+
def exit_node(pathname)
|
87
109
|
@stack.pop
|
88
110
|
end
|
89
111
|
|
90
|
-
def visit_leaf(
|
91
|
-
content
|
112
|
+
def visit_leaf(pathname)
|
113
|
+
content = ContentFile.new(pathname, @options)
|
92
114
|
# connect the leaf_node created to the last tree_node on the stack
|
93
|
-
@nr_files
|
94
|
-
LeafNode.new(
|
115
|
+
@nr_files += 1
|
116
|
+
LeafNode.new(content, @stack.last)
|
95
117
|
end
|
96
118
|
|
97
119
|
end
|
data/lib/tree_rb_cli.rb
CHANGED
@@ -9,14 +9,8 @@ require 'optparse'
|
|
9
9
|
# gem
|
10
10
|
#
|
11
11
|
|
12
|
-
begin
|
13
|
-
require 'Win32/Console/ANSI'
|
14
|
-
rescue LoadError
|
15
|
-
puts 'You must gem install win32console to use color on Windows'
|
16
|
-
end
|
17
|
-
|
18
12
|
#
|
19
13
|
# tree_rb cli
|
20
14
|
#
|
21
15
|
require 'tree_rb'
|
22
|
-
require
|
16
|
+
require 'tree_rb/cli/cli_tree'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.expand_path( File.join(File.dirname(__FILE__), "..", "spec_helper") )
|
3
|
+
|
4
|
+
describe "MD5" do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@file_name = File.expand_path( File.join( File.dirname(__FILE__), "..", "..", "lib", "tree_rb", "extension_digest.rb" ) )
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
it "should calculate md5" do
|
12
|
+
MD5.file( @file_name ).to_s.should == "b33c6b70109037fc02686f8babfc2db4"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should calculate sha1" do
|
16
|
+
SHA1.file( @file_name ).to_s.should == "f99700dbdd200d7255f586ceb0cac05e05871cc5"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/tree.rb.gemspec
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
#!/usr/bin/env gem build
|
1
2
|
# -*- encoding: utf-8; mode: ruby -*-
|
2
3
|
$:.push File.expand_path("../lib", __FILE__)
|
3
4
|
require "tree_rb/version"
|
@@ -30,22 +31,24 @@ An example of DSL to build tree:
|
|
30
31
|
gem.email = "tokiro.oyama@gmail.com"
|
31
32
|
gem.homepage = "http://github.com/tokiro/tree.rb"
|
32
33
|
|
33
|
-
gem.post_install_message = %q{
|
34
|
-
Thank you to have installed tree.rb, any feedback is appreciated.
|
35
|
-
}
|
34
|
+
gem.post_install_message = %q{Thank you to have installed tree.rb, any feedback is appreciated.}
|
36
35
|
|
37
36
|
gem.require_paths = %w{ lib }
|
38
37
|
|
38
|
+
#
|
39
|
+
# load platform dependent gems
|
40
|
+
#
|
41
|
+
# gem.extensions = 'ext/mkrf_conf.rb'
|
42
|
+
# win32 depends on win32console.gem but this must be installed from ext/mkrf_conf.rb
|
43
|
+
# gem.add_runtime_dependency(%q<win32console>, [">= 0"])
|
44
|
+
|
39
45
|
#
|
40
46
|
# dependencies
|
41
47
|
#
|
42
48
|
|
43
49
|
gem.add_runtime_dependency(%q<json>, [">= 0"])
|
44
50
|
gem.add_runtime_dependency(%q<ansi>, [">= 0"])
|
45
|
-
|
46
|
-
# win32 depends on win32console.gem but this must be installed from ext/mkrf_conf.rb
|
47
|
-
# gem.add_runtime_dependency(%q<win32console>, [">= 0"])
|
48
|
-
#
|
51
|
+
gem.add_runtime_dependency(%q<sqlite3-ruby>, [">= 0"])
|
49
52
|
|
50
53
|
gem.add_development_dependency(%q<rake>, [">= 0"])
|
51
54
|
gem.add_development_dependency(%q<yard>, [">= 0"])
|
@@ -68,6 +71,7 @@ An example of DSL to build tree:
|
|
68
71
|
#
|
69
72
|
# s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
70
73
|
# gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
74
|
+
# Dir["bin/*"].map(&File.method(:basename))
|
71
75
|
gem.executables = %w{ tree.rb rtree tree_rb }
|
72
76
|
|
73
77
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tree.rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
@@ -43,6 +43,22 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: sqlite3-ruby
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
46
62
|
- !ruby/object:Gem::Dependency
|
47
63
|
name: rake
|
48
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,11 +160,11 @@ files:
|
|
144
160
|
- lib/tree_rb/abs_node.rb
|
145
161
|
- lib/tree_rb/extension_numeric.rb
|
146
162
|
- lib/tree_rb/leaf_node.rb
|
163
|
+
- lib/tree_rb/extension_digest.rb
|
147
164
|
- lib/tree_rb/tree_node_visitor.rb
|
148
165
|
- lib/tree_rb/tree_node.rb
|
149
166
|
- lib/tree_rb/basic_tree_node_visitor.rb
|
150
167
|
- lib/tree_rb/version.rb
|
151
|
-
- lib/tree_rb/extension_md5.rb
|
152
168
|
- lib/treevisitor.rb
|
153
169
|
- lib/tree_rb.rb
|
154
170
|
- lib/tree_rb_cli.rb
|
@@ -171,7 +187,6 @@ files:
|
|
171
187
|
- spec/tree_rb/visitors/tree_node_visitors_spec.rb
|
172
188
|
- spec/tree_rb/tree_dsl_with_derived_class_spec.rb
|
173
189
|
- spec/tree_rb/directory_walker_spec.rb
|
174
|
-
- spec/tree_rb/extension_md5_spec.rb
|
175
190
|
- spec/tree_rb/tree_dsl_spec.rb
|
176
191
|
- spec/tree_rb/extension_numeric_spec.rb
|
177
192
|
- spec/tree_rb/tree_node_paths_spec.rb
|
@@ -179,6 +194,7 @@ files:
|
|
179
194
|
- spec/tree_rb/tree_node_visitor_delegate_spec.rb
|
180
195
|
- spec/tree_rb/tree_node_spec.rb
|
181
196
|
- spec/tree_rb/tree_node_visitor_dsl_spec.rb
|
197
|
+
- spec/tree_rb/extension_digest_spec.rb
|
182
198
|
- spec/fixtures/test_dir_1/dir.1/dir.1.2/file.1.2.1
|
183
199
|
- spec/fixtures/test_dir_1/dir.1/file.1.1
|
184
200
|
- spec/fixtures/test_dir_1/dir.2/file.2.1
|
@@ -189,8 +205,7 @@ files:
|
|
189
205
|
- bin/tree_rb
|
190
206
|
homepage: http://github.com/tokiro/tree.rb
|
191
207
|
licenses: []
|
192
|
-
post_install_message:
|
193
|
-
appreciated.\n"
|
208
|
+
post_install_message: Thank you to have installed tree.rb, any feedback is appreciated.
|
194
209
|
rdoc_options: []
|
195
210
|
require_paths:
|
196
211
|
- lib
|
@@ -223,7 +238,6 @@ test_files:
|
|
223
238
|
- spec/tree_rb/visitors/tree_node_visitors_spec.rb
|
224
239
|
- spec/tree_rb/tree_dsl_with_derived_class_spec.rb
|
225
240
|
- spec/tree_rb/directory_walker_spec.rb
|
226
|
-
- spec/tree_rb/extension_md5_spec.rb
|
227
241
|
- spec/tree_rb/tree_dsl_spec.rb
|
228
242
|
- spec/tree_rb/extension_numeric_spec.rb
|
229
243
|
- spec/tree_rb/tree_node_paths_spec.rb
|
@@ -231,6 +245,7 @@ test_files:
|
|
231
245
|
- spec/tree_rb/tree_node_visitor_delegate_spec.rb
|
232
246
|
- spec/tree_rb/tree_node_spec.rb
|
233
247
|
- spec/tree_rb/tree_node_visitor_dsl_spec.rb
|
248
|
+
- spec/tree_rb/extension_digest_spec.rb
|
234
249
|
- spec/fixtures/test_dir_1/dir.1/dir.1.2/file.1.2.1
|
235
250
|
- spec/fixtures/test_dir_1/dir.1/file.1.1
|
236
251
|
- spec/fixtures/test_dir_1/dir.2/file.2.1
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
#
|
3
|
-
# calculate md5 of big files, snipped found on usenet
|
4
|
-
#
|
5
|
-
|
6
|
-
if RUBY_VERSION =~ /1\.8/
|
7
|
-
# std lib
|
8
|
-
require 'md5'
|
9
|
-
else
|
10
|
-
# std lib
|
11
|
-
require 'digest/md5'
|
12
|
-
include Digest
|
13
|
-
end
|
14
|
-
|
15
|
-
# Return an MD5 object
|
16
|
-
# example:
|
17
|
-
# MD5.file( filename ).hexdigest
|
18
|
-
#
|
19
|
-
class MD5
|
20
|
-
def self.file(file)
|
21
|
-
File.open(file, "rb") do |f|
|
22
|
-
res = self.new
|
23
|
-
while (data = f.read(4096))
|
24
|
-
res << data
|
25
|
-
end
|
26
|
-
res
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,8 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
require File.expand_path( File.join(File.dirname(__FILE__), "..", "spec_helper") )
|
3
|
-
describe "MD5" do
|
4
|
-
it "test_simple_md5" do
|
5
|
-
file_name = File.expand_path( File.join( File.dirname(__FILE__), "..", "..", "lib", "tree_rb", "extension_md5.rb" ) )
|
6
|
-
MD5.file( file_name ).to_s.should == "ccd18527b14ec24ac250cb76f730b2dd"
|
7
|
-
end
|
8
|
-
end
|