tree.rb 0.3.4 → 0.3.5
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/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
|