class Fingerprint::Checker
Given two fingerprints (master and copy) ensures that the copy has at least everything contained in master: For every file in the master, a corresponding file must exist in the copy. This means that there may be extraneous files in the copy, but ensures that every file in the master has been replicated accurately.
At this time, this implementation may require a large amount of memory, proportional to the number of files being checked.
Master and copy are IO
objects corresponding to the output produced by Fingerprint::Scanner
.
Attributes
copy[R]
failures[R]
A list of files which either did not exist in the copy, or had the wrong checksum.
master[R]
Public Class Methods
check_files(master, copy, **options, &block)
click to toggle source
# File lib/fingerprint/checker.rb, line 98 def self.check_files(master, copy, **options, &block) # New API that takes two RecordSets... master_recordset = RecordSet.load_file(master) copy_recordset = RecordSet.load_file(copy) verify(master_recordset, copy_recordset, **options, &block) end
new(master, copy, **options)
click to toggle source
# File lib/fingerprint/checker.rb, line 34 def initialize(master, copy, **options) @master = master @copy = copy @options = options end
verify(master, copy, **options, &block)
click to toggle source
Helper function to check two fingerprint files.
# File lib/fingerprint/checker.rb, line 108 def self.verify(master, copy, **options, &block) error_count = 0 errors = options.delete(:recordset) || RecordSet.new if options[:output] errors = RecordSetPrinter.new(errors, options[:output]) end checker = Checker.new(master, copy, **options) checker.check do |record, result, message| error_count += 1 metadata = { 'error.code' => result, 'error.message' => message } if result == :addition metadata.merge!(record.metadata) errors << Record.new(:warning, record.path, metadata) elsif (copy = checker.copy.paths[record.path]) changes = record.diff(copy) changes.each do |name| metadata["changes.#{name}.old"] = record[name] metadata["changes.#{name}.new"] = copy[name] end errors << Record.new(:warning, record.path, metadata) else errors << Record.new(:warning, record.path, metadata) end end if error_count summary_message = "#{error_count} error(s) detected." else summary_message = "No errors detected" end errors << Record.new(:summary, summary_message, { 'error.count' => error_count }) return error_count end
Public Instance Methods
check() { |record, result, message| ... }
click to toggle source
Run the checking process.
# File lib/fingerprint/checker.rb, line 45 def check(&block) # For every file in the src, we check that it exists # in the destination: total_count = @master.records.count processed_size = 0 total_size = @master.records.inject(0) { |count, record| count + (record['file.size'] || 0).to_i } if @options[:additions] copy_paths = @copy.paths.dup else copy_paths = {} end @master.records.each_with_index do |record, processed_count| copy_paths.delete(record.path) if @options[:progress] $stderr.puts "# Checking: #{record.path}" end next if record.mode != :file result, message = @copy.compare(record) if result != :valid yield record, result, message elsif @options[:extended] # Extended check compares other attributes such as user, group, file modes. changes = record.diff(copy.paths[record.path]) if changes.size > 0 yield record, :attribute_changed, "Attribute(s) #{changes.join(', ')} changed" end end if @options[:progress] $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)}" processed_size += (record['file.size'] || 0).to_i end end if @options[:additions] copy_paths.each do |path, record| next unless record.mode == :file || record.mode == :directory yield record, :addition, "File added" end end end