hash-that-tree 0.1.2 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +5 -1
- data/README.md +22 -14
- data/bin/hashthattree +0 -0
- data/hash-that-tree.gemspec +5 -4
- data/lib/cli.rb +22 -5
- data/lib/compare.rb +2 -2
- data/lib/display.rb +73 -0
- data/lib/hashit.rb +53 -0
- data/templates/displaytemplates.rb +38 -0
- data/test.htm +94 -0
- metadata +10 -6
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,27 @@
|
|
1
1
|
#hash-that-tree
|
2
|
-
A ruby command line app
|
2
|
+
A ruby command line app prints the MD5 hashes all of the files in an array of folders.
|
3
|
+
The output can be in standard text, csv, html or json.
|
3
4
|
|
4
|
-
|
5
|
+
Also has a compare functionthat takes 2 folder, then iterates through the files and comparing the MD5 hashes of the files with the same name
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
# to view help
|
9
|
+
hashthattree help
|
10
|
+
|
11
|
+
# Get the hash of all files in a folder (with optional formatting)
|
12
|
+
hashthattree hashit ./spec/testfiles/1
|
13
|
+
hashthattree hashit ./spec/testfiles/1 -o=csv
|
14
|
+
hashthattree hashit ./spec/testfiles/1 -o=html
|
15
|
+
hashthattree hashit ./spec/testfiles/1 -o=json
|
16
|
+
|
17
|
+
# Get the hash of all files in multiple folders
|
18
|
+
hashthattree hashit ./spec/testfiles/1
|
19
|
+
|
20
|
+
# run the app on the test files in two folders (this will soon be depreciated)
|
21
|
+
hashthattree compare ./spec/testfiles/1 ./spec/testfiles/2
|
22
|
+
hashthattree compare ./spec/testfiles/1 ./spec/testfiles/2 csv
|
23
|
+
hashthattree compare ./spec/testfiles/1 ./spec/testfiles/2 html
|
24
|
+
hashthattree compare ./spec/testfiles/1 ./spec/testfiles/2 json
|
5
25
|
|
6
26
|
## Installation
|
7
27
|
|
@@ -17,17 +37,6 @@ Or install it yourself as:
|
|
17
37
|
|
18
38
|
$ gem install hash-that-tree
|
19
39
|
|
20
|
-
## Usage
|
21
|
-
# to view help
|
22
|
-
hashthattree help
|
23
|
-
|
24
|
-
# run the app on the test files
|
25
|
-
hashthattree compare ./spec/testfiles/1 ./spec/testfiles/2
|
26
|
-
hashthattree compare ./spec/testfiles/1 ./spec/testfiles/2 csv
|
27
|
-
hashthattree compare ./spec/testfiles/1 ./spec/testfiles/2 html
|
28
|
-
hashthattree compare ./spec/testfiles/1 ./spec/testfiles/2 json
|
29
|
-
|
30
|
-
|
31
40
|
## Creating Documentation
|
32
41
|
Run the following command to generate the documantation
|
33
42
|
|
@@ -63,7 +72,6 @@ Or install it yourself as:
|
|
63
72
|
I have a few items to do in upcoming releases
|
64
73
|
* Add Unit Tests
|
65
74
|
* Allow to be used as an API as well as a Command Line Tool
|
66
|
-
* Allow multiple folders to be specified
|
67
75
|
* Add folder recursion option
|
68
76
|
* Add SHA1
|
69
77
|
|
data/bin/hashthattree
CHANGED
File without changes
|
data/hash-that-tree.gemspec
CHANGED
@@ -4,11 +4,11 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |gem|
|
6
6
|
gem.name = %q{hash-that-tree}
|
7
|
-
gem.version = "0.1.
|
7
|
+
gem.version = "0.1.4"
|
8
8
|
gem.authors = ["John Ryan"]
|
9
9
|
gem.email = ["555john@gmail.com"]
|
10
|
-
gem.description = %q{Command line app that
|
11
|
-
gem.summary = %q{
|
10
|
+
gem.description = %q{Command line app that produces the MD5 hash of all files in a set of folders}
|
11
|
+
gem.summary = %q{A ruby command line app prints the MD5 hashes all of the files in an array of folders, the output can be in standard text, csv, html or json}
|
12
12
|
gem.homepage = %q{http://github.com/jnyryan/hash-that-tree}
|
13
13
|
|
14
14
|
gem.extra_rdoc_files = ["LICENSE.txt","README.md" ]
|
@@ -20,7 +20,8 @@ Gem::Specification.new do |gem|
|
|
20
20
|
|
21
21
|
gem.rdoc_options << '--exclude spec/testfiles'
|
22
22
|
|
23
|
-
gem.add_dependency "
|
23
|
+
gem.add_dependency "mustache"
|
24
24
|
gem.add_dependency "thor"
|
25
25
|
gem.add_dependency "yard"
|
26
|
+
|
26
27
|
end
|
data/lib/cli.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require_relative 'compare'
|
3
|
+
require_relative 'hashit'
|
4
|
+
require_relative 'display'
|
3
5
|
|
4
|
-
# Command Line Program that takes
|
6
|
+
# Command Line Program that takes multiple directories and creates a MD5 hash for every file contained within.<br/>
|
5
7
|
# It then builds a result set that compares files with the same name and allows for them to be outputted
|
6
8
|
# as a csv string
|
7
9
|
module HashThatTree
|
@@ -9,11 +11,26 @@ module HashThatTree
|
|
9
11
|
class CLI < Thor
|
10
12
|
#Create a hash of all files in the folders, compare them and output the results in CSV format
|
11
13
|
desc "compare FOLDER1 FOLDER2", "Create a hash of all files in the folders, compare them and output the results in the specified format"
|
12
|
-
|
13
|
-
|
14
|
+
method_option :output, :aliases => "-o", :default => :csv, :desc => "Choose the format to display the results in - csv, json or html"
|
15
|
+
def compare(folder1, folder2)
|
16
|
+
htt = CompareMD5.new(folder1, folder2, options)
|
14
17
|
htt.compare
|
15
18
|
htt.display_results
|
16
|
-
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "hashit FOLDERS", "Create a hash of all files in all folders supplied and display as standard, json, csv or html"
|
22
|
+
method_option :errors, :aliases => "-e", :type => :boolean, :default => false, :desc => "true = display files that could not be processed, false = do not display skipped files"
|
23
|
+
#method_option :hashtype, :aliases => "-h", :default => "cmd5", :desc => "Choose the hash algorithm to use - md5 or sha"
|
24
|
+
method_option :output, :aliases => "-o", :default => "standard", :desc => "Choose the format to display the results in - standard(default), csv, json or html"
|
25
|
+
#method_option :recursive, :aliases => "-r", :type => :boolean, :default => "false", :desc => "true = recurse through sub directories, false = only do top directory"
|
26
|
+
def hashit(*folders)
|
27
|
+
htt = HashIt.new(options, folders)
|
28
|
+
htt.create_hash_results
|
29
|
+
dis = Display.new(options, htt.error_data, htt.file_data)
|
30
|
+
dis.display_results()
|
31
|
+
end
|
32
|
+
|
17
33
|
end
|
18
|
-
CLI.start(ARGV)
|
34
|
+
#CLI.start(ARGV)
|
35
|
+
CLI.start()
|
19
36
|
end
|
data/lib/compare.rb
CHANGED
@@ -15,10 +15,10 @@ module HashThatTree
|
|
15
15
|
attr_accessor :format #the format to output the results to. csv, html or json
|
16
16
|
|
17
17
|
#initialize the class with the folders to be compared
|
18
|
-
def initialize(folder1, folder2,
|
18
|
+
def initialize(folder1, folder2, options)
|
19
19
|
@folder1 = folder1
|
20
20
|
@folder2 = folder2
|
21
|
-
@format =
|
21
|
+
@format = options['output']
|
22
22
|
@filehash = Hash.new
|
23
23
|
validate
|
24
24
|
end
|
data/lib/display.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'mustache'
|
3
|
+
require 'json'
|
4
|
+
require_relative '../templates/displaytemplates'
|
5
|
+
|
6
|
+
# Author:: John Ryan (mailto:555john@gmail.com)
|
7
|
+
# Copyright:: Copyright (c) 2012 John Ryan
|
8
|
+
# License:: Distributes under the same terms as Ruby
|
9
|
+
module HashThatTree
|
10
|
+
|
11
|
+
class Display
|
12
|
+
attr_accessor :format #the format to output the results to. csv, html or json
|
13
|
+
attr_accessor :file_data #array of files and associated hashes
|
14
|
+
attr_accessor :error_data #array of files that could not be processed
|
15
|
+
|
16
|
+
#initialize the class with the folders to be compared
|
17
|
+
def initialize(options, error_data, *file_data )
|
18
|
+
@format = options['output']
|
19
|
+
@displayerrors = options['errors']
|
20
|
+
@file_data = file_data
|
21
|
+
@error_data = error_data
|
22
|
+
p @error_data
|
23
|
+
end
|
24
|
+
|
25
|
+
#print the contents of the FileHashResults object standard out in the format specified. Default is csv
|
26
|
+
def display_results()
|
27
|
+
|
28
|
+
case @format
|
29
|
+
when "csv"
|
30
|
+
display_results_csv
|
31
|
+
when "html"
|
32
|
+
display_results_html
|
33
|
+
when "json"
|
34
|
+
display_results_json
|
35
|
+
else
|
36
|
+
display_results_std
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
#Prints the results to standard out in the csv format specified.
|
41
|
+
def display_results_std
|
42
|
+
puts Mustache.render(StandardTemplate, :filedetails => @file_data[0]);
|
43
|
+
if(@displayerrors)
|
44
|
+
puts Mustache.render(StandardTemplate, :errordetails => @error_data[0]);
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
#Prints the results to standard out in the csv format specified.
|
49
|
+
def display_results_csv
|
50
|
+
puts Mustache.render(CsvTemplate, :filedetails => @file_data[0]);
|
51
|
+
if(@displayerrors)
|
52
|
+
puts Mustache.render(CsvTemplate, :filedetails => @error_data[0]);
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
#Prints the results to standard out in the csv format specified.
|
57
|
+
def display_results_html
|
58
|
+
puts Mustache.render(HtmlTemplate, :filedetails => @file_data[0]);
|
59
|
+
if(@displayerrors)
|
60
|
+
puts Mustache.render(HtmlTemplate, :filedetails => @error_data[0]);
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
#Prints the results to standard out in the csv format specified.
|
65
|
+
def display_results_json
|
66
|
+
puts JSON.pretty_generate(@file_data)
|
67
|
+
if(@displayerrors)
|
68
|
+
puts JSON.pretty_generate(@error_data)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
data/lib/hashit.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
# Author:: John Ryan (mailto:555john@gmail.com)
|
4
|
+
# Copyright:: Copyright (c) 2012 John Ryan
|
5
|
+
# License:: Distributes under the same terms as Ruby
|
6
|
+
module HashThatTree
|
7
|
+
# This class accepts a folder array and provides methods to iterate
|
8
|
+
# through all files in the folder creating a hash of each file within.
|
9
|
+
# The results are displayed to Standard Out in csv, html, json or standard format
|
10
|
+
class HashIt
|
11
|
+
attr_accessor :format #the format to output the results to - standard, csv, html or json
|
12
|
+
attr_accessor :folders #path to folder containing files to hash
|
13
|
+
attr_accessor :file_data #the container for the hashing results
|
14
|
+
attr_accessor :error_data #the container for the files that could not be processed
|
15
|
+
|
16
|
+
#initialize the class with the folders to be processed
|
17
|
+
def initialize(options, folders )
|
18
|
+
@format = options['output']
|
19
|
+
@folders = folders
|
20
|
+
@file_data = []
|
21
|
+
@error_data = []
|
22
|
+
validate
|
23
|
+
end
|
24
|
+
|
25
|
+
# Validates the supplied folders ensuring they exist
|
26
|
+
def validate
|
27
|
+
@folders.each do |item|
|
28
|
+
if(item==nil) || (item=="") || !Dir.exists?(item)
|
29
|
+
puts "a valid folder path is required as argument #{item}"
|
30
|
+
exit
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Iterates through the folders and creates a FileHashResults object containing the
|
36
|
+
# results of the comparisson
|
37
|
+
def create_hash_results
|
38
|
+
|
39
|
+
@folders.each do |folder|
|
40
|
+
Dir.foreach(folder) do |item|
|
41
|
+
begin
|
42
|
+
next if item == '.' or item == '..'
|
43
|
+
fullfilename = File.expand_path(folder, item)
|
44
|
+
the_hash = Digest::MD5.hexdigest(File.read(File.join(File.expand_path(folder), item.downcase)))
|
45
|
+
@file_data << {:filename=>item, :folder=>folder, :filehash => the_hash}
|
46
|
+
rescue
|
47
|
+
@error_data << {:error=>"Skipped#{File.expand_path(folder, item)}"}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
StandardTemplate =<<-TEMPLATE
|
2
|
+
File Hash\t\t\t\tFile Name\t\t\tFolder
|
3
|
+
{{#filedetails}}
|
4
|
+
{{filehash}}\t{{filename}}\t\t{{folder}}
|
5
|
+
{{/filedetails}}
|
6
|
+
TEMPLATE
|
7
|
+
|
8
|
+
HtmlTemplate =<<-TEMPLATE
|
9
|
+
<!DOCTYPE html>
|
10
|
+
<html xmlns=\"http://www.w3.org/1999/xhtml\">
|
11
|
+
<head>
|
12
|
+
<title></title>
|
13
|
+
</head>
|
14
|
+
<body>
|
15
|
+
<table>
|
16
|
+
<tr>
|
17
|
+
<th>File Hash</th>
|
18
|
+
<th>File Name</th>
|
19
|
+
<th>Folder</th>
|
20
|
+
</tr>
|
21
|
+
{{#filedetails}}
|
22
|
+
<tr>
|
23
|
+
<td>{{filehash}}</td>
|
24
|
+
<td>{{filename}}</td>
|
25
|
+
<td>{{folder}}</td>
|
26
|
+
</tr>
|
27
|
+
{{/filedetails}}
|
28
|
+
</table>
|
29
|
+
</body>
|
30
|
+
</html>
|
31
|
+
TEMPLATE
|
32
|
+
|
33
|
+
CsvTemplate=<<-TEMPLATE
|
34
|
+
File Hash,File Name,Folder,
|
35
|
+
{{#filedetails}}
|
36
|
+
{{filehash}},{{filename}},{{folder}},
|
37
|
+
{{/filedetails}}
|
38
|
+
TEMPLATE
|
data/test.htm
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
"./spec/testfiles/1"
|
2
|
+
"./spec/testfiles/2"
|
3
|
+
Skipped:"fileA.txt"
|
4
|
+
Skipped:"fileB.txt"
|
5
|
+
Skipped:"fileA.txt"
|
6
|
+
Skipped:"fileB.txt"
|
7
|
+
<table>
|
8
|
+
<tr>
|
9
|
+
<th>File Name</th>
|
10
|
+
<th>Folder</th>
|
11
|
+
<th>File Hash</th>
|
12
|
+
</tr>
|
13
|
+
<tr>
|
14
|
+
<td>file3.txt</td>
|
15
|
+
<td>./spec/testfiles/1</td>
|
16
|
+
<td>b1946ac92492d2347c6235b4d2611184</td>
|
17
|
+
</tr>
|
18
|
+
<tr>
|
19
|
+
<td>file1.txt</td>
|
20
|
+
<td>./spec/testfiles/1</td>
|
21
|
+
<td>d41d8cd98f00b204e9800998ecf8427e</td>
|
22
|
+
</tr>
|
23
|
+
<tr>
|
24
|
+
<td>file2.txt</td>
|
25
|
+
<td>./spec/testfiles/1</td>
|
26
|
+
<td>d41d8cd98f00b204e9800998ecf8427e</td>
|
27
|
+
</tr>
|
28
|
+
<tr>
|
29
|
+
<td>file4.txt</td>
|
30
|
+
<td>./spec/testfiles/1</td>
|
31
|
+
<td>b1946ac92492d2347c6235b4d2611184</td>
|
32
|
+
</tr>
|
33
|
+
<tr>
|
34
|
+
<td>file3.txt</td>
|
35
|
+
<td>./spec/testfiles/2</td>
|
36
|
+
<td>d164cd9dcf2b16147c4fe8ca3db49a45</td>
|
37
|
+
</tr>
|
38
|
+
<tr>
|
39
|
+
<td>file1.txt</td>
|
40
|
+
<td>./spec/testfiles/2</td>
|
41
|
+
<td>d41d8cd98f00b204e9800998ecf8427e</td>
|
42
|
+
</tr>
|
43
|
+
<tr>
|
44
|
+
<td>file2.txt</td>
|
45
|
+
<td>./spec/testfiles/2</td>
|
46
|
+
<td>d41d8cd98f00b204e9800998ecf8427e</td>
|
47
|
+
</tr>
|
48
|
+
<tr>
|
49
|
+
<td>file4.txt</td>
|
50
|
+
<td>./spec/testfiles/2</td>
|
51
|
+
<td>6e175f736c6eb485932e8f3b8fda535a</td>
|
52
|
+
</tr>
|
53
|
+
<tr>
|
54
|
+
<td>file3.txt</td>
|
55
|
+
<td>./spec/testfiles/1</td>
|
56
|
+
<td>b1946ac92492d2347c6235b4d2611184</td>
|
57
|
+
</tr>
|
58
|
+
<tr>
|
59
|
+
<td>file1.txt</td>
|
60
|
+
<td>./spec/testfiles/1</td>
|
61
|
+
<td>d41d8cd98f00b204e9800998ecf8427e</td>
|
62
|
+
</tr>
|
63
|
+
<tr>
|
64
|
+
<td>file2.txt</td>
|
65
|
+
<td>./spec/testfiles/1</td>
|
66
|
+
<td>d41d8cd98f00b204e9800998ecf8427e</td>
|
67
|
+
</tr>
|
68
|
+
<tr>
|
69
|
+
<td>file4.txt</td>
|
70
|
+
<td>./spec/testfiles/1</td>
|
71
|
+
<td>b1946ac92492d2347c6235b4d2611184</td>
|
72
|
+
</tr>
|
73
|
+
<tr>
|
74
|
+
<td>file3.txt</td>
|
75
|
+
<td>./spec/testfiles/2</td>
|
76
|
+
<td>d164cd9dcf2b16147c4fe8ca3db49a45</td>
|
77
|
+
</tr>
|
78
|
+
<tr>
|
79
|
+
<td>file1.txt</td>
|
80
|
+
<td>./spec/testfiles/2</td>
|
81
|
+
<td>d41d8cd98f00b204e9800998ecf8427e</td>
|
82
|
+
</tr>
|
83
|
+
<tr>
|
84
|
+
<td>file2.txt</td>
|
85
|
+
<td>./spec/testfiles/2</td>
|
86
|
+
<td>d41d8cd98f00b204e9800998ecf8427e</td>
|
87
|
+
</tr>
|
88
|
+
<tr>
|
89
|
+
<td>file4.txt</td>
|
90
|
+
<td>./spec/testfiles/2</td>
|
91
|
+
<td>6e175f736c6eb485932e8f3b8fda535a</td>
|
92
|
+
</tr>
|
93
|
+
|
94
|
+
</table>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hash-that-tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,10 +9,10 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: mustache
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
@@ -59,7 +59,7 @@ dependencies:
|
|
59
59
|
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
-
description: Command line app that
|
62
|
+
description: Command line app that produces the MD5 hash of all files in a set of
|
63
63
|
folders
|
64
64
|
email:
|
65
65
|
- 555john@gmail.com
|
@@ -80,6 +80,8 @@ files:
|
|
80
80
|
- hash-that-tree.gemspec
|
81
81
|
- lib/cli.rb
|
82
82
|
- lib/compare.rb
|
83
|
+
- lib/display.rb
|
84
|
+
- lib/hashit.rb
|
83
85
|
- spec/testfiles/1/file1.txt
|
84
86
|
- spec/testfiles/1/file2.txt
|
85
87
|
- spec/testfiles/1/file3.txt
|
@@ -90,6 +92,8 @@ files:
|
|
90
92
|
- spec/testfiles/2/file4.txt
|
91
93
|
- spec/testfiles/2/fileA.txt
|
92
94
|
- spec/testfiles/2/fileB.txt
|
95
|
+
- templates/displaytemplates.rb
|
96
|
+
- test.htm
|
93
97
|
homepage: http://github.com/jnyryan/hash-that-tree
|
94
98
|
licenses: []
|
95
99
|
post_install_message:
|
@@ -114,8 +118,8 @@ rubyforge_project:
|
|
114
118
|
rubygems_version: 1.8.24
|
115
119
|
signing_key:
|
116
120
|
specification_version: 3
|
117
|
-
summary:
|
118
|
-
|
121
|
+
summary: A ruby command line app prints the MD5 hashes all of the files in an array
|
122
|
+
of folders, the output can be in standard text, csv, html or json
|
119
123
|
test_files:
|
120
124
|
- spec/testfiles/1/file1.txt
|
121
125
|
- spec/testfiles/1/file2.txt
|