lib/bagit/valid.rb in bagit-0.3.2 vs lib/bagit/valid.rb in bagit-0.3.4

- old
+ new

@@ -1,29 +1,45 @@ require 'validatable' +require 'open-uri' +require 'cgi' +require 'logger' module BagIt class Bag include Validatable validates_true_for :consistency, :logic => Proc.new { consistent? } validates_true_for :completeness, :logic => Proc.new { complete? } end module Validity - + def decode_filename(s) + s = s.gsub('%0D',"\r") + s = s.gsub('%0A',"\n") + return s + end + # Return true if the manifest cover all files and all files are # covered. def complete? + logger = Logger.new(STDOUT) + if manifest_files == [] + errors.add :completeness, "there are no manifest files" + end + unmanifested_files.each do |file| + logger.error("#{file} is present but not manifested".red) errors.add :completeness, "#{file} is present but not manifested" end empty_manifests.each do |file| + logger.error("#{file} is manifested but not present".red) errors.add :completeness, "#{file} is manifested but not present" end tag_empty_manifests.each do |file| + logger.error("#{file} is a manifested tag but not present".red) errors.add :completeness, "#{file} is a manifested tag but not present" end errors.on(:completeness).nil? end @@ -31,44 +47,53 @@ # Return true if all manifested files message digests match. def consistent? (manifest_files|tagmanifest_files).each do |mf| # get the algorithm implementation File.basename(mf) =~ /manifest-(.+).txt$/ - algo = case $1 + manifest_type = $1 + algo = case manifest_type when /sha1/i Digest::SHA1 when /md5/i Digest::MD5 + when /sha256/i + Digest::SHA256 + when /sha384/i + Digest::SHA384 + when /sha512/i + Digest::SHA512 else - :unknown + raise ArgumentError.new("Algorithm #{manifest_type} is not supported.") end # Check every file in the manifest File.open(mf) do |io| io.each_line do |line| expected, path = line.chomp.split /\s+/, 2 - file = File.join(bag_dir, path) + file = File.join(bag_dir, decode_filename(path)) + if File.exist? file + actual = algo.file(file).hexdigest if expected != actual + errors.add :consistency, "expected #{file} to have #{algo}: #{expected}, actual is #{actual}" end end end end end - errors.on(:consistency).nil? end # Checks for validity against Payload-Oxum def valid_oxum? bag_info["Payload-Oxum"] == payload_oxum end protected - + # Returns all files in the instance that are not manifested def unmanifested_files mfs = manifested_files.map { |f| File.join bag_dir, f } bag_files.reject { |f| mfs.member? f } end @@ -95,10 +120,10 @@ files = File.open(mf) do |io| io.readlines.map do |line| digest, path = line.chomp.split /\s+/, 2 - path + decode_filename(path) end end (acc + files).uniq