lib/bagit/manifest.rb in bagit-0.2.0 vs lib/bagit/manifest.rb in bagit-0.3.0.pre
- old
+ new
@@ -7,11 +7,14 @@
# Requires response to bag_dir, tag_files, bag_files
module Manifest
# All tag files that are bag manifest files (manifest-[algorithm].txt)
def manifest_files
- tag_files.select { |f| File.basename(f) =~ /^manifest-.*.txt/ }
+ files = Dir[File.join(@bag_dir, '*')].select { |f|
+ File.file? f and File.basename(f) =~ /^manifest-.*.txt/
+ }
+ files
end
# A path to a manifest file of the specified algorithm
def manifest_file(algo)
File.join bag_dir, "manifest-#{algo}.txt"
@@ -24,53 +27,107 @@
manifest_files.each { |f| FileUtils::rm f }
# manifest each tag file for each algorithm
bag_files.each do |f|
rel_path = Pathname.new(f).relative_path_from(Pathname.new(bag_dir)).to_s
- data = open(f) { |io| io.read }
# sha1
- sha1 = Digest::SHA1.hexdigest data
+ sha1 = Digest::SHA1.file f
open(manifest_file(:sha1), 'a') { |io| io.puts "#{sha1} #{rel_path}" }
# md5
- md5 = Digest::MD5.hexdigest data
+ md5 = Digest::MD5.file f
open(manifest_file(:md5), 'a') { |io| io.puts "#{md5} #{rel_path}" }
end
end
# All tag files that are bag manifest files (tagmanifest-[algorithm].txt)
def tagmanifest_files
- tag_files.select { |f| File.basename(f) =~ /^tagmanifest-.*.txt/ }
+ files = Dir[File.join(@bag_dir, '*')].select { |f|
+ File.file? f and File.basename(f) =~ /^tagmanifest-.*.txt/
+ }
+ files
end
# A path to a tagmanifest file of the specified algorithm
def tagmanifest_file(algo)
File.join bag_dir, "tagmanifest-#{algo}.txt"
end
# Generate manifest files for all the tag files (except the tag
# manifest files)
- def tagmanifest!
+ def tagmanifest!(tags=nil)
+
+ tags = tag_files if tags == nil
# nuke all the existing tagmanifest files
tagmanifest_files.each { |f| FileUtils::rm f }
+
+ # ensure presence of manfiest files
+ manifest_files.each do |manifest|
+ tags << manifest unless tags.include?(manifest)
+ end
+ # ensure presence of bag info files
+ tags << bag_info_txt_file unless tags.include?(bag_info_txt_file)
+ tags << bagit_txt_file unless tags.include?(bagit_txt_file)
+
# manifest each (non tagmanifest) tag file for each algorithm
- (tag_files - tagmanifest_files).each do |f|
- data = open(f) { |io| io.read }
- rel_path = File.basename f
+ tags.each do |f|
+ add_tag_file(Pathname.new(f).relative_path_from(Pathname.new(bag_dir)).to_s)
+ end
+ tag_files
+ end
- # sha1
- sha1 = Digest::SHA1.hexdigest data
- open(tagmanifest_file(:sha1), 'a') { |io| io.puts "#{sha1} #{rel_path}" }
+ def add_tag_file(path, src_path=nil)
- # md5
- md5 = Digest::MD5.hexdigest data
- open(tagmanifest_file(:md5), 'a') { |io| io.puts "#{md5} #{rel_path}" }
+ f = File.join(@bag_dir, path)
+ raise "Tag file already in manifest: #{path}" if tag_files.include?(f)
+
+ if not File.exist? f
+ FileUtils::mkdir_p File.dirname(f)
+
+ # write file
+ if src_path.nil?
+ open(f, 'w') { |io| yield io }
+ else
+ FileUtils::cp src_path, f
+ end
+ # this adds the manifest and bag info files on initial creation
+ # it must only run when the manifest doesn't already exist or it will
+ # infinitely recall add_tag_file. Better way of doing this?
+ tagmanifest!
+ elsif not src_path.nil?
+ raise "Tag file already exists, will not overwrite: #{path}\n Use add_tag_file(path) to add an existing tag file."
end
+ data = open(f) { |io| io.read }
+ rel_path = Pathname.new(f).relative_path_from(Pathname.new(bag_dir)).to_s
+
+ # sha1
+ sha1 = Digest::SHA1.hexdigest data
+ open(tagmanifest_file(:sha1), 'a') { |io| io.puts "#{sha1} #{rel_path}" }
+
+ # md5
+ md5 = Digest::MD5.hexdigest data
+ open(tagmanifest_file(:md5), 'a') { |io| io.puts "#{md5} #{rel_path}" }
+ tag_files
+ end
+
+ def remove_tag_file(path)
+ tags = tag_files
+ raise "Tag file is not in manifest: #{path}" unless tags.include?(File.join(@bag_dir, path))
+ tags.delete(File.join(@bag_dir, path))
+ tagmanifest!(tags)
+ end
+
+ def delete_tag_file(path)
+ filepath = File.join(@bag_dir, path)
+ raise "Tag file does not exist: #{path}" unless File.exist? filepath
+ #TODO: delete tags even when they are not in the manifest
+ remove_tag_file(path)
+ FileUtils::rm filepath
end
# Returns true if all present manifested files' message digests
# match the actual message digest
def fixed?