bagit 0.3.1 → 0.3.2.pre
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.
- data/.gitignore +11 -0
- data/.rvmrc +1 -0
- data/.travis.yml +8 -0
- data/Gemfile +3 -0
- data/bagit.gemspec +15 -4
- data/bin/bagit +1 -1
- data/lib/bagit.rb +1 -0
- data/lib/bagit/bag.rb +6 -6
- data/lib/bagit/info.rb +17 -17
- data/lib/bagit/manifest.rb +18 -18
- data/lib/bagit/valid.rb +7 -7
- data/lib/bagit/version.rb +3 -0
- data/spec/bagit_spec.rb +160 -0
- data/spec/fetch_spec.rb +56 -0
- data/spec/manifest_spec.rb +144 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/tag_info_spec.rb +132 -0
- data/spec/tag_spec.rb +61 -0
- data/spec/util/bagit_matchers.rb +49 -0
- data/spec/validation_spec.rb +115 -0
- metadata +84 -14
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use ruby-1.9.3@bagit --create
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/bagit.gemspec
CHANGED
@@ -1,16 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bagit/version'
|
1
5
|
|
2
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
3
7
|
spec.name = "bagit"
|
4
|
-
spec.version =
|
8
|
+
spec.version = BagIt::VERSION
|
5
9
|
spec.summary = "BagIt package generation and validation"
|
6
10
|
spec.description = "Ruby Library and Command Line tools for bagit"
|
7
11
|
spec.email = "johnson.tom@gmail.com"
|
8
12
|
spec.homepage = 'http://github.com/tipr/bagit'
|
9
13
|
spec.authors = ["Tom Johnson, Francesco Lazzarino"]
|
14
|
+
spec.license = "MIT"
|
10
15
|
|
11
16
|
spec.add_dependency 'validatable', '~> 1.6'
|
12
17
|
spec.add_dependency 'docopt', '~> 0.5.0'
|
13
18
|
|
14
|
-
spec.
|
15
|
-
spec.
|
19
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
20
|
+
spec.add_development_dependency 'rake'
|
21
|
+
spec.add_development_dependency 'rspec'
|
22
|
+
|
23
|
+
spec.files = `git ls-files`.split($/)
|
24
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
25
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
26
|
+
spec.require_paths = ["lib"]
|
16
27
|
end
|
data/bin/bagit
CHANGED
data/lib/bagit.rb
CHANGED
data/lib/bagit/bag.rb
CHANGED
@@ -62,33 +62,33 @@ module BagIt
|
|
62
62
|
FileUtils::mkdir_p File.dirname(path)
|
63
63
|
|
64
64
|
if src_path.nil?
|
65
|
-
f = open(path, 'w') { |io| yield io }
|
65
|
+
f = File.open(path, 'w') { |io| yield io }
|
66
66
|
else
|
67
67
|
f = FileUtils::cp src_path, path
|
68
68
|
end
|
69
69
|
write_bag_info
|
70
70
|
return f
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
# Remove a bag file
|
74
74
|
def remove_file(base_path)
|
75
75
|
path = File.join(data_dir, base_path)
|
76
76
|
raise "Bag file does not exist: #{base_path}" unless File.exist? path
|
77
77
|
FileUtils::rm path
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
# Retrieve the IO handle for a file in the bag
|
81
81
|
def get(base_path)
|
82
82
|
path = File.join(data_dir, base_path)
|
83
83
|
return nil unless File.exist?(path)
|
84
84
|
File.open(path)
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
# Test if this bag is empty (no files)
|
88
88
|
def empty?
|
89
89
|
self.bag_files.empty?
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
# Get all bag file paths relative to the data dir
|
93
93
|
def paths
|
94
94
|
self.bag_files.collect { |f| f.sub(data_dir + '/', '') }
|
@@ -103,7 +103,7 @@ module BagIt
|
|
103
103
|
end
|
104
104
|
return bytes.to_s + '.' + bag_files.count.to_s
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
# Remove all empty directory trees from the bag
|
108
108
|
def gc!
|
109
109
|
Dir.entries(data_dir).each do |f|
|
data/lib/bagit/info.rb
CHANGED
@@ -4,7 +4,7 @@ module BagIt
|
|
4
4
|
|
5
5
|
module Info
|
6
6
|
|
7
|
-
@@bag_info_headers = {
|
7
|
+
@@bag_info_headers = {
|
8
8
|
:agent => 'Bag-Software-Agent',
|
9
9
|
:org => 'Source-Organization',
|
10
10
|
:org_addr => 'Organization-Address',
|
@@ -35,7 +35,7 @@ module BagIt
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def write_bag_info(hash={})
|
38
|
-
hash = bag_info.merge(hash)
|
38
|
+
hash = bag_info.merge(hash)
|
39
39
|
hash[@@bag_info_headers[:agent]] = "BagIt Ruby Gem (http://bagit.rubyforge.org)" if hash[@@bag_info_headers[:agent]].nil?
|
40
40
|
hash[@@bag_info_headers[:date]] = Date.today.strftime('%Y-%m-%d') if hash[@@bag_info_headers[:date]].nil?
|
41
41
|
hash[@@bag_info_headers[:oxum]] = payload_oxum
|
@@ -49,7 +49,7 @@ module BagIt
|
|
49
49
|
def bagit
|
50
50
|
read_info_file bagit_txt_file
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
def write_bagit(hash)
|
54
54
|
write_info_file bagit_txt_file, hash
|
55
55
|
end
|
@@ -62,18 +62,18 @@ module BagIt
|
|
62
62
|
protected
|
63
63
|
|
64
64
|
def read_info_file(file)
|
65
|
-
|
66
|
-
open(file) do |io|
|
67
|
-
|
65
|
+
|
66
|
+
File.open(file) do |io|
|
67
|
+
|
68
68
|
entries = io.read.split /\n(?=[^\s])/
|
69
|
-
|
69
|
+
|
70
70
|
entries.inject({}) do |hash, line|
|
71
71
|
name, value = line.chomp.split /\s*:\s*/, 2
|
72
72
|
hash.merge({name => value})
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
end
|
78
78
|
|
79
79
|
def write_info_file(file, hash)
|
@@ -82,25 +82,25 @@ module BagIt
|
|
82
82
|
a = hash.keys.grep(/#{key}/i)
|
83
83
|
acc + (a.size > 1 ? a : [])
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
raise "Multiple labels (#{dups.to_a.join ', '}) in #{file}" unless dups.empty?
|
87
|
-
|
88
|
-
open(file, 'w') do |io|
|
89
|
-
|
87
|
+
|
88
|
+
File.open(file, 'w') do |io|
|
89
|
+
|
90
90
|
hash.each do |name, value|
|
91
91
|
simple_entry = "#{name}: #{value.gsub /\s+/, ' '}"
|
92
|
-
|
92
|
+
|
93
93
|
entry = if simple_entry.length > 79
|
94
94
|
simple_entry.wrap(77).indent(2)
|
95
95
|
else
|
96
96
|
simple_entry
|
97
97
|
end
|
98
|
-
|
98
|
+
|
99
99
|
io.puts entry
|
100
100
|
end
|
101
|
-
|
101
|
+
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
end
|
105
105
|
|
106
106
|
end
|
data/lib/bagit/manifest.rb
CHANGED
@@ -10,7 +10,7 @@ module BagIt
|
|
10
10
|
# All tag files that are bag manifest files (manifest-[algorithm].txt)
|
11
11
|
def manifest_files
|
12
12
|
files = Dir[File.join(@bag_dir, '*')].select { |f|
|
13
|
-
File.file? f and File.basename(f) =~ /^manifest-.*.txt/
|
13
|
+
File.file? f and File.basename(f) =~ /^manifest-.*.txt/
|
14
14
|
}
|
15
15
|
files
|
16
16
|
end
|
@@ -32,19 +32,19 @@ module BagIt
|
|
32
32
|
|
33
33
|
# sha1
|
34
34
|
sha1 = Digest::SHA1.file f
|
35
|
-
open(manifest_file(:sha1), 'a') { |io| io.puts "#{sha1} #{rel_path}" }
|
35
|
+
File.open(manifest_file(:sha1), 'a') { |io| io.puts "#{sha1} #{rel_path}" }
|
36
36
|
|
37
37
|
# md5
|
38
38
|
md5 = Digest::MD5.file f
|
39
|
-
open(manifest_file(:md5), 'a') { |io| io.puts "#{md5} #{rel_path}" }
|
39
|
+
File.open(manifest_file(:md5), 'a') { |io| io.puts "#{md5} #{rel_path}" }
|
40
40
|
end
|
41
|
-
|
41
|
+
tagmanifest!
|
42
42
|
end
|
43
43
|
|
44
44
|
# All tag files that are bag manifest files (tagmanifest-[algorithm].txt)
|
45
45
|
def tagmanifest_files
|
46
46
|
files = Dir[File.join(@bag_dir, '*')].select { |f|
|
47
|
-
File.file? f and File.basename(f) =~ /^tagmanifest-.*.txt/
|
47
|
+
File.file? f and File.basename(f) =~ /^tagmanifest-.*.txt/
|
48
48
|
}
|
49
49
|
files
|
50
50
|
end
|
@@ -57,12 +57,12 @@ module BagIt
|
|
57
57
|
# Generate manifest files for all the tag files (except the tag
|
58
58
|
# manifest files)
|
59
59
|
def tagmanifest!(tags=nil)
|
60
|
-
|
60
|
+
|
61
61
|
tags = tag_files if tags == nil
|
62
62
|
|
63
63
|
# nuke all the existing tagmanifest files
|
64
64
|
tagmanifest_files.each { |f| FileUtils::rm f }
|
65
|
-
|
65
|
+
|
66
66
|
# ensure presence of manfiest files
|
67
67
|
manifest_files.each do |manifest|
|
68
68
|
tags << manifest unless tags.include?(manifest)
|
@@ -81,36 +81,36 @@ module BagIt
|
|
81
81
|
|
82
82
|
def add_tag_file(path, src_path=nil)
|
83
83
|
|
84
|
-
f = File.join(@bag_dir, path)
|
84
|
+
f = File.join(@bag_dir, path)
|
85
85
|
raise "Tag file already in manifest: #{path}" if tag_files.include?(f)
|
86
|
-
|
86
|
+
|
87
87
|
if not File.exist? f
|
88
88
|
FileUtils::mkdir_p File.dirname(f)
|
89
89
|
|
90
90
|
# write file
|
91
91
|
if src_path.nil?
|
92
|
-
open(f, 'w') { |io| yield io }
|
92
|
+
File.open(f, 'w') { |io| yield io }
|
93
93
|
else
|
94
94
|
FileUtils::cp src_path, f
|
95
95
|
end
|
96
96
|
# this adds the manifest and bag info files on initial creation
|
97
|
-
# it must only run when the manifest doesn't already exist or it will
|
97
|
+
# it must only run when the manifest doesn't already exist or it will
|
98
98
|
# infinitely recall add_tag_file. Better way of doing this?
|
99
|
-
tagmanifest!
|
100
|
-
elsif not src_path.nil?
|
99
|
+
tagmanifest!
|
100
|
+
elsif not src_path.nil?
|
101
101
|
raise "Tag file already exists, will not overwrite: #{path}\n Use add_tag_file(path) to add an existing tag file."
|
102
102
|
end
|
103
103
|
|
104
|
-
data = open(f) { |io| io.read }
|
104
|
+
data = File.open(f) { |io| io.read }
|
105
105
|
rel_path = Pathname.new(f).relative_path_from(Pathname.new(bag_dir)).to_s
|
106
106
|
|
107
107
|
# sha1
|
108
108
|
sha1 = Digest::SHA1.hexdigest data
|
109
|
-
open(tagmanifest_file(:sha1), 'a') { |io| io.puts "#{sha1} #{rel_path}" }
|
109
|
+
File.open(tagmanifest_file(:sha1), 'a') { |io| io.puts "#{sha1} #{rel_path}" }
|
110
110
|
|
111
111
|
# md5
|
112
112
|
md5 = Digest::MD5.hexdigest data
|
113
|
-
open(tagmanifest_file(:md5), 'a') { |io| io.puts "#{md5} #{rel_path}" }
|
113
|
+
File.open(tagmanifest_file(:md5), 'a') { |io| io.puts "#{md5} #{rel_path}" }
|
114
114
|
tag_files
|
115
115
|
end
|
116
116
|
|
@@ -146,11 +146,11 @@ module BagIt
|
|
146
146
|
|
147
147
|
# check it, an unknown algorithm is always true
|
148
148
|
unless algo == :unknown
|
149
|
-
lines = open(mf) { |io| io.readlines }
|
149
|
+
lines = File.open(mf) { |io| io.readlines }
|
150
150
|
|
151
151
|
lines.all? do |line|
|
152
152
|
manifested_digest, path = line.chomp.split /\s+/, 2
|
153
|
-
actual_digest = open(File.join(@bag_dir, path)) { |io| algo.hexdigest io.read }
|
153
|
+
actual_digest = File.open(File.join(@bag_dir, path)) { |io| algo.hexdigest io.read }
|
154
154
|
actual_digest == manifested_digest
|
155
155
|
end
|
156
156
|
|
data/lib/bagit/valid.rb
CHANGED
@@ -4,8 +4,8 @@ module BagIt
|
|
4
4
|
|
5
5
|
class Bag
|
6
6
|
include Validatable
|
7
|
-
validates_true_for :consistency, :logic => Proc.new {
|
8
|
-
validates_true_for :completeness, :logic => Proc.new {
|
7
|
+
validates_true_for :consistency, :logic => Proc.new { consistent? }
|
8
|
+
validates_true_for :completeness, :logic => Proc.new { complete? }
|
9
9
|
end
|
10
10
|
|
11
11
|
module Validity
|
@@ -24,7 +24,7 @@ module BagIt
|
|
24
24
|
tag_empty_manifests.each do |file|
|
25
25
|
errors.add :completeness, "#{file} is a manifested tag but not present"
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
errors.on(:completeness).nil?
|
29
29
|
end
|
30
30
|
|
@@ -42,7 +42,7 @@ module BagIt
|
|
42
42
|
:unknown
|
43
43
|
end
|
44
44
|
# Check every file in the manifest
|
45
|
-
open(mf) do |io|
|
45
|
+
File.open(mf) do |io|
|
46
46
|
io.each_line do |line|
|
47
47
|
expected, path = line.chomp.split /\s+/, 2
|
48
48
|
file = File.join(bag_dir, path)
|
@@ -55,7 +55,7 @@ module BagIt
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
|
60
60
|
errors.on(:consistency).nil?
|
61
61
|
end
|
@@ -93,7 +93,7 @@ module BagIt
|
|
93
93
|
|
94
94
|
manifest_files.inject([]) do |acc, mf|
|
95
95
|
|
96
|
-
files = open(mf) do |io|
|
96
|
+
files = File.open(mf) do |io|
|
97
97
|
|
98
98
|
io.readlines.map do |line|
|
99
99
|
digest, path = line.chomp.split /\s+/, 2
|
@@ -109,7 +109,7 @@ module BagIt
|
|
109
109
|
# Returns a list of all files in the tag manifest files
|
110
110
|
def tag_manifested_files
|
111
111
|
tagmanifest_files.inject([]) do |acc, mf|
|
112
|
-
files = open(mf) do |io|
|
112
|
+
files = File.open(mf) do |io|
|
113
113
|
io.readlines.map do |line|
|
114
114
|
digest, path = line.chomp.split /\s+/, 2
|
115
115
|
path
|
data/spec/bagit_spec.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# based on v0.96 http://www.cdlib.org/inside/diglib/bagit/bagitspec.html
|
4
|
+
describe BagIt::Bag do
|
5
|
+
describe 'empty bag' do
|
6
|
+
before(:each) do
|
7
|
+
@sandbox = Sandbox.new
|
8
|
+
# make the bag
|
9
|
+
@bag_path = File.join @sandbox.to_s, 'the_bag'
|
10
|
+
@bag = BagIt::Bag.new @bag_path
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:each) do
|
14
|
+
@sandbox.cleanup!
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be empty" do
|
18
|
+
@bag.should be_empty
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
describe 'bag with files' do
|
24
|
+
before(:each) do
|
25
|
+
@sandbox = Sandbox.new
|
26
|
+
|
27
|
+
# make the bag
|
28
|
+
@bag_path = File.join @sandbox.to_s, 'the_bag'
|
29
|
+
@bag = BagIt::Bag.new @bag_path
|
30
|
+
|
31
|
+
# add some files
|
32
|
+
File.open('/dev/urandom') do |rio|
|
33
|
+
10.times do |n|
|
34
|
+
@bag.add_file("file-#{n}") { |io| io.write rio.read(16) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
after(:each) do
|
40
|
+
@sandbox.cleanup!
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should be a directory" do
|
44
|
+
File.directory?(@bag_path).should be_true
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should not be empty" do
|
48
|
+
@bag.should_not be_empty
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should have a sub-directory called data" do
|
52
|
+
data_path = File.join @bag_path, 'data'
|
53
|
+
File.directory?(data_path).should be_true
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#add_file" do
|
57
|
+
it "should allow addition of files via io" do
|
58
|
+
@bag.add_file("foo") { |io| io.puts 'all alone' }
|
59
|
+
File.join(@bag_path, "data", "foo").should exist_on_fs
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should allow addition of files via copy" do
|
63
|
+
src_path = File.join @sandbox.to_s, 'somefile'
|
64
|
+
File.open(src_path, 'w') { |io| io.puts "something" }
|
65
|
+
@bag.add_file("foo", src_path) { |io| io.puts 'all alone' }
|
66
|
+
File.join(@bag_path, "data", "foo").should exist_on_fs
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should allow addition of files with deep paths" do
|
70
|
+
@bag.add_file("deep/dir/structure/file") { |io| io.puts 'all alone' }
|
71
|
+
File.join(@bag_path, "data", "deep/dir/structure/file").should exist_on_fs
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should not allow overwriting of files" do
|
75
|
+
lambda { @bag.add_file("file-0") { |io| io.puts 'overwrite!' } }.should raise_error
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should update payload oxum" do
|
79
|
+
oxum_count = @bag.bag_info["Payload-Oxum"].split('.')[1].to_i
|
80
|
+
@bag.add_file("foo") { |io| io.puts 'all alone' }
|
81
|
+
@bag.bag_info["Payload-Oxum"].split('.')[1].to_i.should == oxum_count + 1
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "#remove_file" do
|
86
|
+
it "should raise an error when deleing non existant files" do
|
87
|
+
lambda { @bag.remove_file("file-x") }.should raise_error
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "#get" do
|
92
|
+
describe "file not in bag" do
|
93
|
+
it "should return nil" do
|
94
|
+
@bag.get('foobar').should be_nil
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "file in bag" do
|
99
|
+
before do
|
100
|
+
@contents = 'all alone'
|
101
|
+
@bag.add_file("foo") { |io| io << 'all alone' }
|
102
|
+
@file = @bag.get("foo")
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should return an IO object for the given path" do
|
106
|
+
@file.should be_a_kind_of(IO)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should have the same content as the file added" do
|
110
|
+
@file.read.should == @contents
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should accept an optional leading slash or ./" do
|
114
|
+
@bag.get("/foo").read.should == @contents
|
115
|
+
@bag.get("./foo").read.should == @contents
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#paths" do
|
121
|
+
before do
|
122
|
+
@paths = @bag.paths
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should return a non-empty Array of Strings" do
|
126
|
+
@paths.should be_a_kind_of(Array)
|
127
|
+
@paths.should_not be_empty
|
128
|
+
@paths.each do |p|
|
129
|
+
p.should be_a_kind_of(String)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should return relative paths to all files in the data directory" do
|
134
|
+
@paths.should =~ (0..9).collect { |x| "file-#{x}" }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "#payload-oxum" do
|
139
|
+
it "should return a valid oxum" do
|
140
|
+
@bag.payload_oxum.should =~ /^[0-9]+\.[0-9]+$/
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should accurately specify the number of payload files" do
|
144
|
+
@bag.add_tag_file('non-payload') { |f| f.puts "I shouldn't count in the oxum" }
|
145
|
+
@bag.payload_oxum.split('.')[1] == @bag.bag_files.count
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "#gc!" do
|
150
|
+
it "should clean up empty directories" do
|
151
|
+
f = File.join "1", "2", "3", "file"
|
152
|
+
@bag.add_file(f) { |io| io.puts 'all alone' }
|
153
|
+
@bag.remove_file f
|
154
|
+
File.exist?(File.dirname(File.join(@bag_path, 'data', f))).should be_true
|
155
|
+
@bag.gc!
|
156
|
+
File.exist?(File.dirname(File.join(@bag_path, 'data', f))).should be_false
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
data/spec/fetch_spec.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "fetch.txt" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
|
7
|
+
@sandbox = Sandbox.new
|
8
|
+
|
9
|
+
# make the bag
|
10
|
+
@bag_path = File.join @sandbox.to_s, 'the_bag'
|
11
|
+
@bag = BagIt::Bag.new @bag_path
|
12
|
+
|
13
|
+
# add some files
|
14
|
+
File.open('/dev/urandom') do |rio|
|
15
|
+
|
16
|
+
10.times do |n|
|
17
|
+
@bag.add_file("file-#{n}") { |io| io.write rio.read(16) }
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
after(:each) do
|
25
|
+
@sandbox.cleanup!
|
26
|
+
end
|
27
|
+
|
28
|
+
before(:each) do
|
29
|
+
@bag.add_remote_file('http://www.gnu.org/graphics/heckert_gnu.small.png', 'gnu.png', 6322,
|
30
|
+
'390c0a30976f899cbdf951eab5cce60fe9743ac9',
|
31
|
+
'a3bd7ab2442028bb91b51d9f6722ec98')
|
32
|
+
|
33
|
+
path = File.join @bag_path, 'fetch.txt'
|
34
|
+
@lines = File.open(path) { |io| io.readlines }
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should not be empty" do
|
38
|
+
@lines.should_not be_empty
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should only contain lines of the format URL LENGTH FILENAME" do
|
42
|
+
@lines.each { |line| line.chomp.should =~ /^[^\s]+\s+(\d+|\-)\s+[^\s]+$/ }
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should contain manifested files" do
|
46
|
+
path = File.join @bag_path, 'manifest-sha1.txt'
|
47
|
+
data = File.open(path) { |io| io.read }
|
48
|
+
data.should include('gnu.png')
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should be gone when fetch is complete" do
|
52
|
+
@bag.fetch!
|
53
|
+
File.exist?(File.join(@bag_path, 'fetch.txt')).should_not be_true
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "BagIt Manifests" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
|
7
|
+
@sandbox = Sandbox.new
|
8
|
+
|
9
|
+
# make the bag
|
10
|
+
@bag_path = File.join @sandbox.to_s, 'the_bag'
|
11
|
+
@bag = BagIt::Bag.new @bag_path
|
12
|
+
|
13
|
+
# add some files
|
14
|
+
File.open('/dev/urandom') do |rio|
|
15
|
+
|
16
|
+
10.times do |n|
|
17
|
+
@bag.add_file("file-#{n}") { |io| io.write rio.read(16) }
|
18
|
+
@bag.add_tag_file("tag-#{n}") { |io| io.write rio.read(16) }
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
after(:each) do
|
26
|
+
@sandbox.cleanup!
|
27
|
+
end
|
28
|
+
|
29
|
+
shared_examples_for "a manifest file" do
|
30
|
+
|
31
|
+
before do
|
32
|
+
pattern = File.join @bag_path, '*manifest-*.txt'
|
33
|
+
@manifest_files = Dir.glob pattern
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should have valid algorithm in the name (at least md5 or sha1)" do
|
37
|
+
algorithms = @manifest_files.map { |mf| mf =~ /manifest-(.*).txt$/; $1 }
|
38
|
+
algorithms.each { |a| a.should be_in('md5', 'sha1') }
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should not be an empty file" do
|
42
|
+
@manifest_files.each { |mf| File.size(mf).should_not == 0 }
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should only contain lines of the format CHECKSUM FILENAME" do
|
46
|
+
@manifest_files.each do |file|
|
47
|
+
File.open(file) do |io|
|
48
|
+
io.each_line { |line| line.chomp.should =~ /^[a-fA-F0-9]+\s+[^\s].+$/ }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should validate after adding a file and remanifesting" do
|
54
|
+
@bag.add_file('newfile.txt') { |io| io.puts("new file to remanifest") }
|
55
|
+
@bag.manifest!
|
56
|
+
@bag.should be_valid
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "bag manifest files" do
|
62
|
+
|
63
|
+
before do
|
64
|
+
@bag.manifest!
|
65
|
+
end
|
66
|
+
|
67
|
+
it_behaves_like "a manifest file"
|
68
|
+
|
69
|
+
it "should have a manifest file" do
|
70
|
+
@bag.manifest_files.should_not be_empty
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should only contain bag files" do
|
74
|
+
@bag.manifest_files.each do |mf|
|
75
|
+
File.open(mf) do |io|
|
76
|
+
io.each_line do |line|
|
77
|
+
line.chomp.should =~ /^[a-f0-9]+\s+data\/[^\s].+$/
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "tag manifest files" do
|
86
|
+
|
87
|
+
before do
|
88
|
+
@bag.add_tag_file("test-tag") { |f| f.puts "all alone" }
|
89
|
+
end
|
90
|
+
|
91
|
+
it_should_behave_like "a manifest file"
|
92
|
+
|
93
|
+
it "should have a tag manifest file" do
|
94
|
+
@bag.tagmanifest_files.should_not be_empty
|
95
|
+
end
|
96
|
+
it "should only contain tag files" do
|
97
|
+
@bag.tagmanifest_files.each do |mf|
|
98
|
+
File.open(mf) do |io|
|
99
|
+
io.each_line do |line|
|
100
|
+
line.chomp.should =~ /^[a-fA-F0-9]+\s+(?!data\/)[^\s].+$/
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
it "should contain manifest and bag info files" do
|
106
|
+
@bag.tagmanifest_files.each do |mf|
|
107
|
+
File.open(mf).read.should include(File.basename(@bag.bag_info_txt_file))
|
108
|
+
File.open(mf).read.should include(File.basename(@bag.bagit_txt_file))
|
109
|
+
@bag.manifest_files.each do |man|
|
110
|
+
File.open(mf).read.should include(man)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
it "should not contain the untracked tag file" do
|
115
|
+
@bag.tagmanifest_files.each do |mf|
|
116
|
+
File.open(mf) do |io|
|
117
|
+
io.read.should_not include "tag-notrack"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
describe "removing tracked files" do
|
122
|
+
before(:each) do
|
123
|
+
@bag.remove_tag_file "tag-1"
|
124
|
+
@bag.delete_tag_file "tag-2"
|
125
|
+
end
|
126
|
+
it "should still have the untracked tag file on the file system" do
|
127
|
+
File.join(@bag_path, "tag-1").should exist_on_fs
|
128
|
+
end
|
129
|
+
it "should not have the deleted tag file on the file system" do
|
130
|
+
File.join(@bag_path, "tag-2").should_not exist_on_fs
|
131
|
+
end
|
132
|
+
it "should not have the removed or deleted tag files in the manifest" do
|
133
|
+
@bag.tagmanifest_files.each do |mf|
|
134
|
+
File.open(mf) do |io|
|
135
|
+
io.read.should_not include "tag-1"
|
136
|
+
io.read.should_not include "tag-2"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.require(:default, :test)
|
4
|
+
|
5
|
+
require File.expand_path('./util/bagit_matchers', File.dirname(__FILE__))
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.include(BagitMatchers)
|
9
|
+
end
|
10
|
+
|
11
|
+
$:.unshift File.expand_path('../lib', File.dirname(__FILE__))
|
12
|
+
require 'bagit'
|
13
|
+
|
14
|
+
require 'tempfile'
|
15
|
+
|
16
|
+
class Sandbox
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
tf = Tempfile.open 'sandbox'
|
20
|
+
@path = tf.path
|
21
|
+
tf.close!
|
22
|
+
FileUtils::mkdir @path
|
23
|
+
end
|
24
|
+
|
25
|
+
def cleanup!
|
26
|
+
FileUtils::rm_rf @path
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
@path
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Tag Info Files" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
|
7
|
+
@sandbox = Sandbox.new
|
8
|
+
|
9
|
+
# make the bag
|
10
|
+
@bag_path = File.join @sandbox.to_s, 'the_bag'
|
11
|
+
@bag = BagIt::Bag.new @bag_path
|
12
|
+
|
13
|
+
# add some files
|
14
|
+
File.open('/dev/urandom') do |rio|
|
15
|
+
10.times do |n|
|
16
|
+
@bag.add_file("file-#{n}") { |io| io.write rio.read(16) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
after(:each) do
|
23
|
+
@sandbox.cleanup!
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "bagit.txt" do
|
27
|
+
|
28
|
+
before do
|
29
|
+
path = File.join @bag_path, 'bagit.txt'
|
30
|
+
@lines = File.open(path) { |io| io.readlines }
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should create a file bagit.txt on bag initialization" do
|
34
|
+
File.join(@bag_path, 'bagit.txt').should exist_on_fs
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have exactly two lines" do
|
38
|
+
@lines.size.should == 2
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have a bagit version" do
|
42
|
+
a = @lines.select { |line| line.chomp =~ /BagIt-Version:\s*\d+\.\d+/ }
|
43
|
+
a.should_not be_empty
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should have a tag file encoding" do
|
47
|
+
a = @lines.select { |line| line.chomp =~ /Tag-File-Character-Encoding:\s*.+/ }
|
48
|
+
a.should_not be_empty
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "bag-info.txt" do
|
54
|
+
|
55
|
+
before(:each) do
|
56
|
+
path = File.join @bag_path, 'bag-info.txt'
|
57
|
+
@lines = File.open(path) { |io| io.readlines }
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should not be empty" do
|
61
|
+
@lines.should_not be_empty
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should contain lines of the format LABEL: VALUE (like an email header)" do
|
65
|
+
@lines.each { |line| line.chomp.should =~ /^[^\s]+\s*:\s+.*$/ }
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should be case insensitive with respect to LABELs" do
|
69
|
+
path = File.join @bag_path, 'bag-info.txt'
|
70
|
+
lambda { @bag.write_bag_info 'foo' => 'lowercase', 'Foo' => 'capital' }.should raise_error(/Multiple labels/)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should fold long VALUEs" do
|
74
|
+
longline = <<LOREM
|
75
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
|
76
|
+
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enimad
|
77
|
+
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
|
78
|
+
aliquip ex ea commodo consequat. Duis aute irure dolor in
|
79
|
+
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
|
80
|
+
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
|
81
|
+
culpa qui officia deserunt mollit anim id est laborum.
|
82
|
+
LOREM
|
83
|
+
@bag.write_bag_info 'Lorem' => longline
|
84
|
+
@bag.bag_info.keys.length.should == 4 # this isn't a great test. Changed it from 1 to 4 because unrelated changes caused failure.
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should specify a bag software agent" do
|
88
|
+
@bag.bag_info.keys.should include("Bag-Software-Agent")
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should contain a valid bagging date" do
|
92
|
+
@bag.bag_info.keys.should include("Bagging-Date")
|
93
|
+
@bag.bag_info["Bagging-Date"] =~ /^^[0-9]{4}-[0-9]{2}-[0-9]{2}$/
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should contain a payload oxum" do
|
97
|
+
@bag.bag_info.keys.should include("Payload-Oxum")
|
98
|
+
end
|
99
|
+
it "should not override any previous values" do
|
100
|
+
path = File.join @bag_path, 'bag-info.txt'
|
101
|
+
@bag.write_bag_info 'Bag-Software-Agent' => 'Some Other Agent'
|
102
|
+
@bag.write_bag_info 'Source-Organization' => 'Awesome Inc.'
|
103
|
+
@bag.write_bag_info 'Bagging-Date' => '1901-01-01'
|
104
|
+
@bag.write_bag_info
|
105
|
+
contents = File.open(path).read
|
106
|
+
contents.should include "Some Other Agent"
|
107
|
+
contents.should include "Awesome Inc."
|
108
|
+
contents.should include "1901-01-01"
|
109
|
+
end
|
110
|
+
it "should override previous tags when they collide with new ones" do
|
111
|
+
path = File.join @bag_path, 'bag-info.txt'
|
112
|
+
@bag.write_bag_info 'Source-Organization' => 'Awesome Inc.'
|
113
|
+
@bag.write_bag_info 'Source-Organization' => 'Awesome LLC.'
|
114
|
+
contents = File.open(path).read
|
115
|
+
contents.should include "Awesome LLC."
|
116
|
+
contents.should_not include "Awesome Inc."
|
117
|
+
end
|
118
|
+
it "should contain values passed to bag" do
|
119
|
+
hash = {"Bag-Software-Agent" => "rspec",
|
120
|
+
"Bagging-Date" => "2012-11-21",
|
121
|
+
"Contact-Name" => "Willis Corto",
|
122
|
+
"Some-Tag" => "Some Value"
|
123
|
+
}
|
124
|
+
bag_with_info = BagIt::Bag.new(@bag_path + '2', hash)
|
125
|
+
hash.each do |key, value|
|
126
|
+
bag_with_info.bag_info[key].should == value
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
data/spec/tag_spec.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Tag Specs" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
|
7
|
+
@sandbox = Sandbox.new
|
8
|
+
|
9
|
+
# make the bag
|
10
|
+
@bag_path = File.join @sandbox.to_s, 'the_bag'
|
11
|
+
@bag = BagIt::Bag.new @bag_path
|
12
|
+
|
13
|
+
# add some files
|
14
|
+
File.open('/dev/urandom') do |rio|
|
15
|
+
|
16
|
+
10.times do |n|
|
17
|
+
@bag.add_file("file-#{n}") { |io| io.write rio.read(16) }
|
18
|
+
@bag.add_tag_file("tag-#{n}") { |io| io.write rio.read(16)}
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
after(:each) do
|
26
|
+
@sandbox.cleanup!
|
27
|
+
end
|
28
|
+
describe "#add_tag_file" do
|
29
|
+
it "should allow addition of tag files via io" do
|
30
|
+
@bag.add_tag_file("foo") { |io| io.puts 'all alone' }
|
31
|
+
File.join(@bag_path, "foo").should exist_on_fs
|
32
|
+
end
|
33
|
+
it "should allow addition of bag files within directories using io" do
|
34
|
+
@bag.add_tag_file("fedora/foo") { |io| io.puts 'all alone' }
|
35
|
+
File.join(@bag_path, "fedora","foo").should exist_on_fs
|
36
|
+
end
|
37
|
+
it "should allow addition of deep tag files" do
|
38
|
+
@bag.add_tag_file("fedora/foo/newfoo/deep") {|io| io.puts "woah that's deep"}
|
39
|
+
File.join(@bag_path,"fedora","foo","newfoo","deep").should exist_on_fs
|
40
|
+
end
|
41
|
+
it "should not allow overwriting of tag files" do
|
42
|
+
lambda { @bag.add_tag_file("tag-0") { |io| io.puts 'overwrite!' } }.should raise_error
|
43
|
+
end
|
44
|
+
it "should allow addition of tag files via copy" do
|
45
|
+
src_path = File.join @sandbox.to_s, 'somefile'
|
46
|
+
File.open(src_path, 'w') { |io| io.puts "something" }
|
47
|
+
@bag.add_tag_file("foo", src_path) { |io| io.puts 'all alone' }
|
48
|
+
File.join(@bag_path, "foo").should exist_on_fs
|
49
|
+
end
|
50
|
+
end
|
51
|
+
describe "#remove_tag_file" do
|
52
|
+
it "should raise an error when removing non existant files" do
|
53
|
+
lambda { @bag.remove_tag_file("file-x") }.should raise_error
|
54
|
+
end
|
55
|
+
end
|
56
|
+
describe "#delete_tag_file" do
|
57
|
+
it "should raise an error when deleting non existant tag files" do
|
58
|
+
lambda { @bag.delete_tag_file("file-x") }.should raise_error
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module BagitMatchers
|
2
|
+
|
3
|
+
class BeIn
|
4
|
+
|
5
|
+
def initialize(*expected_collection)
|
6
|
+
@expected = expected_collection
|
7
|
+
end
|
8
|
+
|
9
|
+
def matches?(target)
|
10
|
+
@target = target
|
11
|
+
@expected.include? @target
|
12
|
+
end
|
13
|
+
|
14
|
+
def failure_message
|
15
|
+
"expected <#{@target}> to be in collection <#{@expected}>"
|
16
|
+
end
|
17
|
+
|
18
|
+
def negative_failure_message
|
19
|
+
"expected <#{@target}> to not be in collection <#{@expected}>"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def be_in(*expected_collection)
|
25
|
+
BeIn.new(*expected_collection)
|
26
|
+
end
|
27
|
+
|
28
|
+
class ExistOnFS
|
29
|
+
|
30
|
+
def matches?(target)
|
31
|
+
@target = target
|
32
|
+
File.exist? target
|
33
|
+
end
|
34
|
+
|
35
|
+
def failure_message
|
36
|
+
"expected <#{@target}> to exist, but it doesn't"
|
37
|
+
end
|
38
|
+
|
39
|
+
def negative_failure_message
|
40
|
+
"expected <#{@target}> to not exist but it does"
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
def exist_on_fs
|
46
|
+
ExistOnFS.new
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "a valid bag" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
|
7
|
+
@sandbox = Sandbox.new
|
8
|
+
|
9
|
+
# make the bag
|
10
|
+
@bag_path = File.join @sandbox.to_s, 'the_bag'
|
11
|
+
@bag = BagIt::Bag.new @bag_path
|
12
|
+
|
13
|
+
# add some files
|
14
|
+
File.open('/dev/urandom') do |rio|
|
15
|
+
|
16
|
+
10.times do |n|
|
17
|
+
@bag.add_file("file-#{n}") { |io| io.write rio.read(16) }
|
18
|
+
@bag.add_tag_file("tag-#{n}") { |io| io.write rio.read(16) }
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
@bag.manifest!
|
24
|
+
end
|
25
|
+
|
26
|
+
after(:each) do
|
27
|
+
@sandbox.cleanup!
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should validate with no errors" do
|
31
|
+
@bag.should be_valid
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not be lewd (some file is not covered by the manifest)" do
|
35
|
+
# add a file into the bag through the back door
|
36
|
+
File.open(File.join(@bag.data_dir, 'not-manifested'), 'w') do |io|
|
37
|
+
io.puts 'nothing to see here, move along'
|
38
|
+
end
|
39
|
+
|
40
|
+
@bag.validate_only('true_for/completeness')
|
41
|
+
@bag.errors.on(:completeness).should_not be_empty
|
42
|
+
@bag.should_not be_valid
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should not be prude (the manifest covers files that do not exist)" do
|
46
|
+
# add a file and then remove it through the back door
|
47
|
+
@bag.add_file("file-k") { |io| io.puts 'time to go' }
|
48
|
+
@bag.manifest!
|
49
|
+
|
50
|
+
FileUtils::rm File.join(@bag.bag_dir, 'data', 'file-k')
|
51
|
+
|
52
|
+
@bag.validate_only('true_for/completeness')
|
53
|
+
@bag.errors.on(:completeness).should_not be_empty
|
54
|
+
@bag.should_not be_valid
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should be consistent (fixity)" do
|
58
|
+
# tweak a file through the back door
|
59
|
+
File.open(@bag.bag_files[0], 'a') { |io| io.puts 'oops!' }
|
60
|
+
|
61
|
+
@bag.validate_only('true_for/consistency')
|
62
|
+
@bag.errors.on(:consistency).should_not be_empty
|
63
|
+
@bag.should_not be_valid
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should calculate sha1 correctly for a big file" do
|
67
|
+
@bag.add_file 'big-data-file' do |fh|
|
68
|
+
count = 0
|
69
|
+
while count < 1024 * 512 do
|
70
|
+
fh.write "1" * 1024
|
71
|
+
count += 1
|
72
|
+
end
|
73
|
+
end
|
74
|
+
@bag.manifest!
|
75
|
+
sha1_manifest = File.join @bag_path, 'manifest-sha1.txt'
|
76
|
+
checksums = {}
|
77
|
+
File.open(sha1_manifest).each_line do |line|
|
78
|
+
fixity, path = line.split(' ')
|
79
|
+
checksums[path] = fixity
|
80
|
+
end
|
81
|
+
expected = checksums['data/big-data-file']
|
82
|
+
expected.should == '12be64c30968bb90136ee695dc58f4b2276968c6'
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should validate by oxum when needed" do
|
86
|
+
@bag.valid_oxum?.should == true
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should validate false by oxum when file count is incorrect" do
|
90
|
+
# tweak oxum through backdoor
|
91
|
+
File.open(@bag.bag_info_txt_file, 'a') { |f| f.write "Payload-Oxum: " + @bag.bag_info["Payload-Oxum"].split('.')[0] + '.0' }
|
92
|
+
@bag.valid_oxum?.should == false
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should validate false by oxum when octetstream size is incorrect" do
|
96
|
+
# tweak oxum through backdoor
|
97
|
+
File.open(@bag.bag_info_txt_file, 'a') { |f| f.write "Payload-Oxum: 1." + @bag.bag_info["Payload-Oxum"].split('.')[1] }
|
98
|
+
@bag.valid_oxum?.should == false
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "tag manifest validation" do
|
102
|
+
it "should be invalid if listed tag file does not exist" do
|
103
|
+
# add a file and then remove it through the back door
|
104
|
+
@bag.add_tag_file("tag-k") { |io| io.puts 'time to go' }
|
105
|
+
@bag.tagmanifest!
|
106
|
+
|
107
|
+
FileUtils::rm File.join(@bag.bag_dir, 'tag-k')
|
108
|
+
|
109
|
+
# @bag.should_not be_valid
|
110
|
+
@bag.should_not be_valid
|
111
|
+
@bag.errors.on(:completeness).should_not be_empty
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bagit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
5
|
-
prerelease:
|
4
|
+
version: 0.3.2.pre
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Tom Johnson, Francesco Lazzarino
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: validatable
|
@@ -43,6 +43,54 @@ dependencies:
|
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: 0.5.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: bundler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.3'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
46
94
|
description: Ruby Library and Command Line tools for bagit
|
47
95
|
email: johnson.tom@gmail.com
|
48
96
|
executables:
|
@@ -50,21 +98,35 @@ executables:
|
|
50
98
|
extensions: []
|
51
99
|
extra_rdoc_files: []
|
52
100
|
files:
|
53
|
-
-
|
54
|
-
-
|
101
|
+
- .gitignore
|
102
|
+
- .rvmrc
|
103
|
+
- .travis.yml
|
104
|
+
- Gemfile
|
55
105
|
- LICENSE.txt
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
56
108
|
- bagit.gemspec
|
109
|
+
- bin/bagit
|
57
110
|
- lib/bagit.rb
|
58
|
-
- lib/bagit/
|
111
|
+
- lib/bagit/bag.rb
|
59
112
|
- lib/bagit/fetch.rb
|
60
|
-
- lib/bagit/manifest.rb
|
61
|
-
- lib/bagit/info.rb
|
62
113
|
- lib/bagit/file.rb
|
114
|
+
- lib/bagit/info.rb
|
115
|
+
- lib/bagit/manifest.rb
|
116
|
+
- lib/bagit/string.rb
|
63
117
|
- lib/bagit/valid.rb
|
64
|
-
- lib/bagit/
|
65
|
-
-
|
118
|
+
- lib/bagit/version.rb
|
119
|
+
- spec/bagit_spec.rb
|
120
|
+
- spec/fetch_spec.rb
|
121
|
+
- spec/manifest_spec.rb
|
122
|
+
- spec/spec_helper.rb
|
123
|
+
- spec/tag_info_spec.rb
|
124
|
+
- spec/tag_spec.rb
|
125
|
+
- spec/util/bagit_matchers.rb
|
126
|
+
- spec/validation_spec.rb
|
66
127
|
homepage: http://github.com/tipr/bagit
|
67
|
-
licenses:
|
128
|
+
licenses:
|
129
|
+
- MIT
|
68
130
|
post_install_message:
|
69
131
|
rdoc_options: []
|
70
132
|
require_paths:
|
@@ -78,13 +140,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
141
|
none: false
|
80
142
|
requirements:
|
81
|
-
- - ! '
|
143
|
+
- - ! '>'
|
82
144
|
- !ruby/object:Gem::Version
|
83
|
-
version:
|
145
|
+
version: 1.3.1
|
84
146
|
requirements: []
|
85
147
|
rubyforge_project:
|
86
148
|
rubygems_version: 1.8.25
|
87
149
|
signing_key:
|
88
150
|
specification_version: 3
|
89
151
|
summary: BagIt package generation and validation
|
90
|
-
test_files:
|
152
|
+
test_files:
|
153
|
+
- spec/bagit_spec.rb
|
154
|
+
- spec/fetch_spec.rb
|
155
|
+
- spec/manifest_spec.rb
|
156
|
+
- spec/spec_helper.rb
|
157
|
+
- spec/tag_info_spec.rb
|
158
|
+
- spec/tag_spec.rb
|
159
|
+
- spec/util/bagit_matchers.rb
|
160
|
+
- spec/validation_spec.rb
|