fingerprint 3.1.0 → 3.4.0
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/fingerprint/checker.rb +6 -13
- data/lib/fingerprint/command/duplicates.rb +45 -40
- data/lib/fingerprint/command/verify.rb +1 -5
- data/lib/fingerprint/record.rb +33 -13
- data/lib/fingerprint/scanner.rb +1 -1
- data/lib/fingerprint/version.rb +1 -1
- data.tar.gz.sig +3 -0
- metadata +33 -5
- metadata.gz.sig +0 -0
- data/lib/.DS_Store +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe183e59d36938796040005023943811697ab7c5f4d18c78f4740dd21bdcacb5
|
4
|
+
data.tar.gz: a781c31d0eb206bf505ca521331e13681b43014a15260c7a6aeb6cf7056796c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9fea4f8529180e152013a160c8e87f7deb046cd7270a2f9b4206ecb9ff84454f6fccedd93b98488cfc79baf9b33c9dcd863ce7fd586cd12da29d56203f59c31a
|
7
|
+
data.tar.gz: db95df8fbbf8b5d67a0bfe68d3953d8066c549d055c772d15705f3b54e2bf7c2f555e854335694da3ec27347e0c1d50835a3c0871b16656ca229eff70232b479
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data/lib/fingerprint/checker.rb
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
-
|
21
|
+
require_relative 'record'
|
22
22
|
|
23
23
|
module Fingerprint
|
24
24
|
# Given two fingerprints (master and copy) ensures that the copy has at least everything contained
|
@@ -77,7 +77,7 @@ module Fingerprint
|
|
77
77
|
end
|
78
78
|
|
79
79
|
if @options[:progress]
|
80
|
-
$stderr.puts "# Progress: File #{processed_count} / #{total_count}; Byte #{processed_size} / #{total_size} = #{sprintf('%0.2f
|
80
|
+
$stderr.puts "# Progress: File #{processed_count} / #{total_count}; Byte #{processed_size} / #{total_size} = #{sprintf('%0.2f%%', processed_size.to_f / total_size.to_f * 100.0)}"
|
81
81
|
|
82
82
|
processed_size += (record['file.size'] || 0).to_i
|
83
83
|
end
|
@@ -98,17 +98,10 @@ module Fingerprint
|
|
98
98
|
def self.check_files(master, copy, **options, &block)
|
99
99
|
# New API that takes two RecordSets...
|
100
100
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
copy_recordset = RecordSet.new
|
107
|
-
copy_recordset.parse(copy_file)
|
108
|
-
|
109
|
-
verify(master_recordset, copy_recordset, **options, &block)
|
110
|
-
end
|
111
|
-
end
|
101
|
+
master_recordset = RecordSet.load_file(master)
|
102
|
+
copy_recordset = RecordSet.load_file(copy)
|
103
|
+
|
104
|
+
verify(master_recordset, copy_recordset, **options, &block)
|
112
105
|
end
|
113
106
|
|
114
107
|
# Helper function to check two fingerprint files.
|
@@ -33,6 +33,8 @@ module Fingerprint
|
|
33
33
|
option "-i/--inverse", "Invert the output, i.e. show files which are not duplicates."
|
34
34
|
option "-x/--extended", "Include extended information about files and directories."
|
35
35
|
|
36
|
+
option "--delete", "Delete duplicates."
|
37
|
+
|
36
38
|
option "--verbose", "Verbose output, e.g. what is happening."
|
37
39
|
end
|
38
40
|
|
@@ -41,54 +43,57 @@ module Fingerprint
|
|
41
43
|
|
42
44
|
attr :duplicates_recordset
|
43
45
|
|
46
|
+
def delete(path)
|
47
|
+
FileUtils.rm_f(path)
|
48
|
+
end
|
49
|
+
|
44
50
|
def call
|
45
|
-
@options[:output] = @parent.output
|
46
|
-
|
47
51
|
@duplicates_recordset = RecordSet.new
|
48
|
-
results = RecordSetPrinter.new(duplicates_recordset, @
|
52
|
+
results = RecordSetPrinter.new(@duplicates_recordset, @parent.output)
|
49
53
|
|
50
54
|
master_file_path = @master
|
51
|
-
|
52
|
-
master_recordset = RecordSet.new
|
53
|
-
master_recordset.parse(master_file)
|
55
|
+
master_recordset = RecordSet.load_file(master_file_path)
|
54
56
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
57
|
+
ignore_similar = false
|
58
|
+
|
59
|
+
copy_file_paths = @copies
|
60
|
+
|
61
|
+
if copy_file_paths.size == 0
|
62
|
+
copy_file_paths = [master_file_path]
|
63
|
+
ignore_similar = true
|
64
|
+
end
|
65
|
+
|
66
|
+
copy_file_paths.each do |copy_file_path|
|
67
|
+
copy_recordset = RecordSet.load_file(copy_file_path)
|
63
68
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
69
|
+
copy_recordset.records.each do |record|
|
70
|
+
next unless record.file?
|
71
|
+
|
72
|
+
record.metadata['fingerprint'] = copy_file_path
|
73
|
+
|
74
|
+
# We need to see if the record exists in the master
|
75
|
+
|
76
|
+
if @options[:verbose]
|
77
|
+
$stderr.puts "Checking #{record.inspect}"
|
78
|
+
end
|
79
|
+
|
80
|
+
main_record = master_recordset.find_by_key(record)
|
81
|
+
|
82
|
+
# If we are scanning the same index, don't print out every file, just those that are duplicates within the single file.
|
83
|
+
if ignore_similar && main_record && (main_record.path == record.path)
|
84
|
+
main_record = nil
|
85
|
+
end
|
86
|
+
|
87
|
+
if main_record
|
88
|
+
record.metadata['original.path'] = main_record.path
|
89
|
+
record.metadata['original.fingerprint'] = master_file_path
|
90
|
+
results << record if !@options[:inverse]
|
68
91
|
|
69
|
-
|
70
|
-
record.
|
71
|
-
# We need to see if the record exists in the master
|
72
|
-
|
73
|
-
if @options[:verbose]
|
74
|
-
$stderr.puts "Checking #{record.inspect}"
|
75
|
-
end
|
76
|
-
|
77
|
-
main_record = master_recordset.find_by_key(record)
|
78
|
-
|
79
|
-
# If we are scanning the same index, don't print out every file, just those that are duplicates within the single file.
|
80
|
-
if ignore_similar && main_record && (main_record.path == record.path)
|
81
|
-
main_record = nil
|
82
|
-
end
|
83
|
-
|
84
|
-
if main_record
|
85
|
-
record.metadata['original.path'] = main_record.path
|
86
|
-
record.metadata['original.fingerprint'] = master_file_path
|
87
|
-
results << record if !@options[:inverse]
|
88
|
-
else
|
89
|
-
results << record if @options[:inverse]
|
90
|
-
end
|
92
|
+
if @options[:delete]
|
93
|
+
delete(copy_recordset.full_path(record.path))
|
91
94
|
end
|
95
|
+
else
|
96
|
+
results << record if @options[:inverse]
|
92
97
|
end
|
93
98
|
end
|
94
99
|
end
|
@@ -60,11 +60,7 @@ module Fingerprint
|
|
60
60
|
options = @options.dup
|
61
61
|
options[:output] = @parent.output
|
62
62
|
|
63
|
-
master = RecordSet.
|
64
|
-
|
65
|
-
File.open(input_file, "r") do |io|
|
66
|
-
master.parse(io)
|
67
|
-
end
|
63
|
+
master = RecordSet.load_file(input_file)
|
68
64
|
|
69
65
|
if master.configuration
|
70
66
|
options.merge!(master.configuration.options)
|
data/lib/fingerprint/record.rb
CHANGED
@@ -46,6 +46,10 @@ module Fingerprint
|
|
46
46
|
attr :metadata
|
47
47
|
attr :keys
|
48
48
|
|
49
|
+
def file?
|
50
|
+
@mode == :file
|
51
|
+
end
|
52
|
+
|
49
53
|
def [](key)
|
50
54
|
@metadata[key]
|
51
55
|
end
|
@@ -86,38 +90,54 @@ module Fingerprint
|
|
86
90
|
|
87
91
|
class RecordSet
|
88
92
|
def self.load_file(path)
|
93
|
+
path = File.expand_path(path)
|
94
|
+
root = File.dirname(path)
|
95
|
+
|
96
|
+
record_set = self.new(root)
|
97
|
+
|
89
98
|
File.open(path, "r") do |io|
|
90
|
-
|
99
|
+
record_set.parse(io)
|
91
100
|
end
|
101
|
+
|
102
|
+
return record_set
|
92
103
|
end
|
93
104
|
|
94
|
-
def
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
def initialize
|
105
|
+
def initialize(root = nil)
|
106
|
+
@root = root
|
99
107
|
@records = []
|
100
108
|
@paths = {}
|
101
109
|
@keys = {}
|
102
110
|
|
103
111
|
@configuration = nil
|
104
|
-
|
112
|
+
|
105
113
|
@callback = nil
|
106
114
|
end
|
107
|
-
|
115
|
+
|
116
|
+
attr :root
|
117
|
+
|
108
118
|
attr :records
|
109
119
|
attr :paths
|
110
120
|
attr :keys
|
111
|
-
|
121
|
+
|
112
122
|
attr :configuration
|
113
|
-
|
123
|
+
|
124
|
+
def full_path(path)
|
125
|
+
Build::Files::Path.join(@root, path)
|
126
|
+
end
|
127
|
+
|
114
128
|
def <<(record)
|
115
129
|
@records << record
|
130
|
+
|
116
131
|
if record.mode == :configuration
|
117
|
-
|
132
|
+
if @configuration
|
133
|
+
raise "Multiple configurations detected!"
|
134
|
+
end
|
135
|
+
|
118
136
|
@configuration = record
|
137
|
+
@root ||= @configuration.path
|
119
138
|
else
|
120
139
|
@paths[record.path] = record
|
140
|
+
|
121
141
|
record.keys.each do |key|
|
122
142
|
@keys[key] ||= {}
|
123
143
|
|
@@ -125,7 +145,7 @@ module Fingerprint
|
|
125
145
|
end
|
126
146
|
end
|
127
147
|
end
|
128
|
-
|
148
|
+
|
129
149
|
def include?(path)
|
130
150
|
@paths.include?(path)
|
131
151
|
end
|
@@ -222,7 +242,7 @@ module Fingerprint
|
|
222
242
|
elsif line.match(/^\s+([a-zA-Z\.0-9]+)\s+(.*)$/)
|
223
243
|
metadata[$1] = $2
|
224
244
|
else
|
225
|
-
|
245
|
+
raise "Unhandled line: #{line}"
|
226
246
|
end
|
227
247
|
end
|
228
248
|
|
data/lib/fingerprint/scanner.rb
CHANGED
@@ -259,7 +259,7 @@ module Fingerprint
|
|
259
259
|
|
260
260
|
if @options[:progress]
|
261
261
|
@progress = lambda do |read_size|
|
262
|
-
$stderr.puts "# Progress: File #{processed_count} / #{total_count}; Byte #{processed_size + read_size} / #{total_size} = #{sprintf('%0.3f
|
262
|
+
$stderr.puts "# Progress: File #{processed_count} / #{total_count}; Byte #{processed_size + read_size} / #{total_size} = #{sprintf('%0.3f%%', (processed_size + read_size).to_f / total_size.to_f * 100.0)} (#{read_size}, #{processed_size}, #{total_size})"
|
263
263
|
end
|
264
264
|
end
|
265
265
|
|
data/lib/fingerprint/version.rb
CHANGED
data.tar.gz.sig
ADDED
@@ -0,0 +1,3 @@
|
|
1
|
+
�X?�x�O��z"�y�����u�*�&6c��ơ+��<�wW��iZ���>�<b�Q}�5���5��æz���:/k���s�3�}{5����� Sc6���n�������4�@YOTQ �h�& ������p%J�1/�ʔ�A^��Uf��UNL��ؗbP��Q�|���I=���
|
2
|
+
���^h�ߞYv�Ğ�,��<d��N�RCB���� ��ם�|��Je~(gU�4�����j�mX]^�gS`n����B��5m;���>���~���r���7jB�棖��QYo!��� ���%�c��~��n�Cd��k��A/N�`�G��95[�%o�F��z9�*�f�����
|
3
|
+
^6�l�����U"
|
metadata
CHANGED
@@ -1,14 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fingerprint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
|
+
- Glenn Rempe
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
|
-
cert_chain:
|
11
|
-
|
11
|
+
cert_chain:
|
12
|
+
- |
|
13
|
+
-----BEGIN CERTIFICATE-----
|
14
|
+
MIIEhDCCAuygAwIBAgIBATANBgkqhkiG9w0BAQsFADA3MTUwMwYDVQQDDCxzYW11
|
15
|
+
ZWwud2lsbGlhbXMvREM9b3Jpb250cmFuc2Zlci9EQz1jby9EQz1uejAeFw0yMTA4
|
16
|
+
MTYwNjMzNDRaFw0yMjA4MTYwNjMzNDRaMDcxNTAzBgNVBAMMLHNhbXVlbC53aWxs
|
17
|
+
aWFtcy9EQz1vcmlvbnRyYW5zZmVyL0RDPWNvL0RDPW56MIIBojANBgkqhkiG9w0B
|
18
|
+
AQEFAAOCAY8AMIIBigKCAYEAyXLSS/cw+fXJ5e7hi+U/TeChPWeYdwJojDsFY1xr
|
19
|
+
xvtqbTTL8gbLHz5LW3QD2nfwCv3qTlw0qI3Ie7a9VMJMbSvgVEGEfQirqIgJXWMj
|
20
|
+
eNMDgKsMJtC7u/43abRKx7TCURW3iWyR19NRngsJJmaR51yGGGm2Kfsr+JtKKLtL
|
21
|
+
L188Wm3f13KAx7QJU8qyuBnj1/gWem076hzdA7xi1DbrZrch9GCRz62xymJlrJHn
|
22
|
+
9iZEZ7AxrS7vokhMlzSr/XMUihx/8aFKtk+tMLClqxZSmBWIErWdicCGTULXCBNb
|
23
|
+
E/mljo4zEVKhlTWpJklMIhr55ZRrSarKFuW7en0+tpJrfsYiAmXMJNi4XAYJH7uL
|
24
|
+
rgJuJwSaa/dMz+VmUoo7VKtSfCoOI+6v5/z0sK3oT6sG6ZwyI47DBq2XqNC6tnAj
|
25
|
+
w+XmCywiTQrFzMMAvcA7rPI4F0nU1rZId51rOvvfxaONp+wgTi4P8owZLw0/j0m4
|
26
|
+
8C20DYi6EYx4AHDXiLpElWh3AgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8E
|
27
|
+
BAMCBLAwHQYDVR0OBBYEFB6ZaeWKxQjGTI+pmz7cKRmMIywwMC4GA1UdEQQnMCWB
|
28
|
+
I3NhbXVlbC53aWxsaWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWB
|
29
|
+
I3NhbXVlbC53aWxsaWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEB
|
30
|
+
CwUAA4IBgQBVoM+pu3dpdUhZM1w051iw5GfiqclAr1Psypf16Tiod/ho//4oAu6T
|
31
|
+
9fj3DPX/acWV9P/FScvqo4Qgv6g4VWO5ZU7z2JmPoTXZtYMunRAmQPFL/gSUc6aK
|
32
|
+
vszMHIyhtyzRc6DnfW2AiVOjMBjaYv8xXZc9bduniRVPrLR4J7ozmGLh4o4uJp7w
|
33
|
+
x9KCFaR8Lvn/r0oJWJOqb/DMAYI83YeN2Dlt3jpwrsmsONrtC5S3gOUle5afSGos
|
34
|
+
bYt5ocnEpKSomR9ZtnCGljds/aeO1Xgpn2r9HHcjwnH346iNrnHmMlC7BtHUFPDg
|
35
|
+
Ts92S47PTOXzwPBDsrFiq3VLbRjHSwf8rpqybQBH9MfzxGGxTaETQYOd6b4e4Ag6
|
36
|
+
y92abGna0bmIEb4+Tx9rQ10Uijh1POzvr/VTH4bbIPy9FbKrRsIQ24qDbNJRtOpE
|
37
|
+
RAOsIl+HOBTb252nx1kIRN5hqQx272AJCbCjKx8egcUQKffFVVCI0nye09v5CK+a
|
38
|
+
HiLJ8VOFx6w=
|
39
|
+
-----END CERTIFICATE-----
|
40
|
+
date: 2022-06-01 00:00:00.000000000 Z
|
12
41
|
dependencies:
|
13
42
|
- !ruby/object:Gem::Dependency
|
14
43
|
name: build-files
|
@@ -88,7 +117,6 @@ extensions: []
|
|
88
117
|
extra_rdoc_files: []
|
89
118
|
files:
|
90
119
|
- bin/fingerprint
|
91
|
-
- lib/.DS_Store
|
92
120
|
- lib/fingerprint.rb
|
93
121
|
- lib/fingerprint/checker.rb
|
94
122
|
- lib/fingerprint/checksums.rb
|
@@ -122,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
150
|
- !ruby/object:Gem::Version
|
123
151
|
version: '0'
|
124
152
|
requirements: []
|
125
|
-
rubygems_version: 3.
|
153
|
+
rubygems_version: 3.3.7
|
126
154
|
signing_key:
|
127
155
|
specification_version: 4
|
128
156
|
summary: Fingerprint is a tool for creating checksums of entire directory structures,
|
metadata.gz.sig
ADDED
Binary file
|
data/lib/.DS_Store
DELETED
Binary file
|