bagit 0.3.5 → 0.4.4
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 +5 -5
- data/.gitignore +2 -1
- data/.travis.yml +1 -2
- data/Gemfile +4 -2
- data/README.md +1 -1
- data/Rakefile +11 -8
- data/bagit.gemspec +25 -21
- data/bin/bagit +59 -63
- data/lib/bagit.rb +8 -6
- data/lib/bagit/bag.rb +43 -47
- data/lib/bagit/fetch.rb +23 -27
- data/lib/bagit/file.rb +11 -14
- data/lib/bagit/info.rb +39 -51
- data/lib/bagit/manifest.rb +72 -49
- data/lib/bagit/string.rb +6 -6
- data/lib/bagit/valid.rb +51 -57
- data/lib/bagit/version.rb +3 -1
- data/spec/bagit_spec.rb +59 -54
- data/spec/fetch_spec.rb +33 -38
- data/spec/manifest_spec.rb +107 -111
- data/spec/spec_helper.rb +12 -12
- data/spec/tag_info_spec.rb +101 -108
- data/spec/tag_spec.rb +47 -49
- data/spec/util/bagit_matchers.rb +5 -14
- data/spec/validation_spec.rb +108 -110
- metadata +50 -9
data/spec/tag_spec.rb
CHANGED
@@ -1,62 +1,60 @@
|
|
1
|
-
#
|
2
|
-
require 'spec_helper'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
require "spec_helper"
|
5
4
|
|
6
|
-
|
5
|
+
describe BagIt::Bag do
|
6
|
+
describe "Tag Specs" do
|
7
|
+
before do
|
8
|
+
@sandbox = Sandbox.new
|
7
9
|
|
8
|
-
|
10
|
+
# make the bag
|
11
|
+
@bag_path = File.join @sandbox.to_s, "the_bag"
|
12
|
+
@bag = described_class.new(@bag_path)
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
10.times do |n|
|
18
|
-
@bag.add_file("file-#{n}-💩
|
19
|
-
@bag.add_tag_file("tag-#{n}") { |io| io.write rio.read(16)}
|
14
|
+
# add some files
|
15
|
+
File.open("/dev/urandom") do |rio|
|
16
|
+
10.times do |n|
|
17
|
+
@bag.add_file("file-#{n}-💩
|
18
|
+
@bag.add_tag_file("tag-#{n}") { |io| io.write rio.read(16) }
|
19
|
+
end
|
20
20
|
end
|
21
|
-
|
22
21
|
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
after(:each) do
|
27
|
-
@sandbox.cleanup!
|
28
|
-
end
|
29
|
-
describe "#add_tag_file" do
|
30
|
-
it "should allow addition of tag files via io" do
|
31
|
-
@bag.add_tag_file("foo") { |io| io.puts 'all alone' }
|
32
|
-
expect(File.join(@bag_path, "foo")).to exist_on_fs
|
33
|
-
end
|
34
|
-
it "should allow addition of bag files within directories using io" do
|
35
|
-
@bag.add_tag_file("fedora/foo") { |io| io.puts 'all alone' }
|
36
|
-
expect(File.join(@bag_path, "fedora","foo")).to exist_on_fs
|
23
|
+
after do
|
24
|
+
@sandbox.cleanup!
|
37
25
|
end
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
26
|
+
describe "#add_tag_file" do
|
27
|
+
it "allows addition of tag files via io" do
|
28
|
+
@bag.add_tag_file("foo") { |io| io.puts "all alone" }
|
29
|
+
expect(File.join(@bag_path, "foo")).to exist_on_fs
|
30
|
+
end
|
31
|
+
it "allows addition of bag files within directories using io" do
|
32
|
+
@bag.add_tag_file("fedora/foo") { |io| io.puts "all alone" }
|
33
|
+
expect(File.join(@bag_path, "fedora", "foo")).to exist_on_fs
|
34
|
+
end
|
35
|
+
it "allows addition of deep tag files" do
|
36
|
+
@bag.add_tag_file("fedora/foo/newfoo/deep") { |io| io.puts "woah that's deep" }
|
37
|
+
expect(File.join(@bag_path, "fedora", "foo", "newfoo", "deep")).to exist_on_fs
|
38
|
+
end
|
39
|
+
it "does not allow overwriting of tag files" do
|
40
|
+
expect { @bag.add_tag_file("tag-0") { |io| io.puts "overwrite!" } }.to raise_error(RuntimeError)
|
41
|
+
end
|
42
|
+
it "allows addition of tag files via copy" do
|
43
|
+
src_path = File.join @sandbox.to_s, "somefile"
|
44
|
+
File.open(src_path, "w") { |io| io.puts "something" }
|
45
|
+
@bag.add_tag_file("foo", src_path) { |io| io.puts "all alone" }
|
46
|
+
expect(File.join(@bag_path, "foo")).to exist_on_fs
|
47
|
+
end
|
44
48
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
expect(File.join(@bag_path, "foo")).to exist_on_fs
|
49
|
+
describe "#remove_tag_file" do
|
50
|
+
it "raises an error when removing non existant files" do
|
51
|
+
expect { @bag.remove_tag_file("file-x") }.to raise_error(RuntimeError)
|
52
|
+
end
|
50
53
|
end
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
54
|
+
describe "#delete_tag_file" do
|
55
|
+
it "raises an error when deleting non existant tag files" do
|
56
|
+
expect { @bag.delete_tag_file("file-x") }.to raise_error(RuntimeError)
|
57
|
+
end
|
55
58
|
end
|
56
59
|
end
|
57
|
-
describe "#delete_tag_file" do
|
58
|
-
it "should raise an error when deleting non existant tag files" do
|
59
|
-
expect { @bag.delete_tag_file("file-x") }.to raise_error(RuntimeError)
|
60
|
-
end
|
61
|
-
end
|
62
60
|
end
|
data/spec/util/bagit_matchers.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class BeIn
|
4
|
-
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
3
|
+
module BagitMatchers
|
4
|
+
class BeIn
|
6
5
|
def initialize(*expected_collection)
|
7
6
|
@expected = expected_collection
|
8
7
|
end
|
@@ -20,16 +19,13 @@ module BagitMatchers
|
|
20
19
|
"expected <#{@target}> to not be in collection <#{@expected}>"
|
21
20
|
end
|
22
21
|
alias negative_failure_message failure_message_when_negated
|
23
|
-
|
24
22
|
end
|
25
23
|
|
26
24
|
def be_in(*expected_collection)
|
27
25
|
BeIn.new(*expected_collection)
|
28
26
|
end
|
29
27
|
|
30
|
-
class ExistOnFS
|
31
|
-
|
32
|
-
|
28
|
+
class ExistOnFS
|
33
29
|
def matches?(target)
|
34
30
|
@target = target
|
35
31
|
File.exist? target
|
@@ -43,14 +39,9 @@ module BagitMatchers
|
|
43
39
|
"expected <#{@target}> to not exist but it does"
|
44
40
|
end
|
45
41
|
alias negative_failure_message failure_message_when_negated
|
46
|
-
|
47
42
|
end
|
48
43
|
|
49
|
-
def exist_on_fs
|
44
|
+
def exist_on_fs
|
50
45
|
ExistOnFS.new
|
51
46
|
end
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
47
|
end
|
data/spec/validation_spec.rb
CHANGED
@@ -1,144 +1,142 @@
|
|
1
|
-
#
|
2
|
-
require 'spec_helper'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
require "spec_helper"
|
5
4
|
|
6
|
-
|
5
|
+
describe BagIt::Bag do
|
6
|
+
describe "a valid bag" do
|
7
|
+
before do
|
8
|
+
@sandbox = Sandbox.new
|
7
9
|
|
8
|
-
|
10
|
+
# make the bag
|
11
|
+
@bag_path = File.join @sandbox.to_s, "the_bag"
|
12
|
+
@bag = described_class.new @bag_path
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
# add some files
|
15
|
-
File.open('/dev/urandom') do |rio|
|
16
|
-
|
17
|
-
10.times do |n|
|
18
|
-
@bag.add_file("file-#{n}-💩
|
14
|
+
# add some files
|
15
|
+
File.open("/dev/urandom") do |rio|
|
16
|
+
10.times do |n|
|
17
|
+
@bag.add_file("file-#{n}-💩
|
19
18
|
") { |io| io.write rio.read(16) }
|
20
|
-
|
19
|
+
@bag.add_tag_file("tag-#{n}") { |io| io.write rio.read(16) }
|
20
|
+
end
|
21
21
|
end
|
22
22
|
|
23
|
+
@bag.manifest!
|
23
24
|
end
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
after do
|
27
|
+
@sandbox.cleanup!
|
28
|
+
end
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
30
|
+
it "validates with no errors" do
|
31
|
+
expect(@bag).to be_valid
|
32
|
+
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
34
|
+
it "is invalid if there is a file that's in the bag, but not in 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
|
35
39
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
io.puts 'nothing to see here, move along'
|
40
|
+
@bag.validate_only("true_for/completeness")
|
41
|
+
expect(@bag.errors.on(:completeness)).not_to be_empty
|
42
|
+
expect(@bag).not_to be_valid
|
40
43
|
end
|
41
44
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
it "should be invalid if there are files that are in the manifest but not in the bag" do
|
48
|
-
# add a file and then remove it through the back door
|
49
|
-
@bag.add_file("file-k") { |io| io.puts 'time to go' }
|
50
|
-
@bag.manifest!
|
45
|
+
it "is invalid if there are files that are in the manifest but not in the bag" 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!
|
51
49
|
|
52
|
-
|
50
|
+
FileUtils.rm File.join(@bag.bag_dir, "data", "file-k")
|
53
51
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
52
|
+
@bag.validate_only("true_for/completeness")
|
53
|
+
expect(@bag.errors.on(:completeness)).not_to be_empty
|
54
|
+
expect(@bag).not_to be_valid
|
55
|
+
end
|
58
56
|
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
it "is invalid if there is a fixity problem" do
|
58
|
+
# tweak a file through the back door
|
59
|
+
File.open(@bag.bag_files[0], "a") { |io| io.puts "oops!" }
|
62
60
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
61
|
+
@bag.validate_only("true_for/consistency")
|
62
|
+
expect(@bag.errors.on(:consistency)).not_to be_empty
|
63
|
+
expect(@bag).not_to be_valid
|
64
|
+
end
|
67
65
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
66
|
+
it "calculates sha1 correctly for a big file" do
|
67
|
+
@bag.add_file "big-data-file" do |fh|
|
68
|
+
count = 0
|
69
|
+
while count < 1024 * 512
|
70
|
+
fh.write "1" * 1024
|
71
|
+
count += 1
|
72
|
+
end
|
74
73
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
fixity, path = line.split(' ')
|
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(" ")
|
81
79
|
checksums[path] = fixity
|
80
|
+
end
|
81
|
+
expected = checksums["data/big-data-file"]
|
82
|
+
expect(expected).to eq("12be64c30968bb90136ee695dc58f4b2276968c6")
|
82
83
|
end
|
83
|
-
expected = checksums['data/big-data-file']
|
84
|
-
expect(expected).to eq('12be64c30968bb90136ee695dc58f4b2276968c6')
|
85
|
-
end
|
86
84
|
|
87
|
-
|
88
|
-
|
89
|
-
|
85
|
+
it "validates by oxum when needed" do
|
86
|
+
expect(@bag.valid_oxum?).to eq(true)
|
87
|
+
end
|
90
88
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
it "should validate false by oxum when file count is incorrect" do
|
100
|
-
# tweak oxum through backdoor
|
101
|
-
File.open(@bag.bag_info_txt_file, 'a') { |f| f.write "Payload-Oxum: " + @bag.bag_info["Payload-Oxum"].split('.')[0] + '.0' }
|
102
|
-
expect(@bag.valid_oxum?).to eq(false)
|
103
|
-
end
|
89
|
+
it "raises a sensible error when the manifest algorithm is unknown" do
|
90
|
+
# add a manifest with an unsupported algorithm
|
91
|
+
File.open(File.join(@bag.bag_dir, "manifest-sha999.txt"), "w") do |io|
|
92
|
+
io.puts "digest-does-not-matter data/file-0\n"
|
93
|
+
end
|
94
|
+
expect { @bag.valid? }.to raise_error ArgumentError
|
95
|
+
end
|
104
96
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
97
|
+
it "validates false by oxum when file count is incorrect" do
|
98
|
+
# tweak oxum through backdoor
|
99
|
+
File.open(@bag.bag_info_txt_file, "a") { |f| f.write "Payload-Oxum: " + @bag.bag_info["Payload-Oxum"].split(".")[0] + ".0" }
|
100
|
+
expect(@bag.valid_oxum?).to eq(false)
|
101
|
+
end
|
110
102
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
@bag.
|
115
|
-
|
116
|
-
end
|
117
|
-
@bag.tag_files.each do |tag_file|
|
118
|
-
FileUtils::rm tag_file
|
119
|
-
end
|
120
|
-
@bag.tagmanifest_files.each do |tagmanifest_file|
|
121
|
-
FileUtils::rm tagmanifest_file
|
122
|
-
end
|
103
|
+
it "validates false by oxum when octetstream size is incorrect" do
|
104
|
+
# tweak oxum through backdoor
|
105
|
+
File.open(@bag.bag_info_txt_file, "a") { |f| f.write "Payload-Oxum: 1." + @bag.bag_info["Payload-Oxum"].split(".")[1] }
|
106
|
+
expect(@bag.valid_oxum?).to eq(false)
|
107
|
+
end
|
123
108
|
|
124
|
-
|
125
|
-
|
126
|
-
|
109
|
+
describe "tag manifest validation" do
|
110
|
+
it "is invalid if there are no manifest files at all even when there are no files" do
|
111
|
+
# remove all files, tag/manifest files & tagmanifest files through the back door
|
112
|
+
@bag.bag_files.each do |bag_file|
|
113
|
+
FileUtils.rm bag_file
|
114
|
+
end
|
115
|
+
@bag.tag_files.each do |tag_file|
|
116
|
+
FileUtils.rm tag_file
|
117
|
+
end
|
118
|
+
@bag.tagmanifest_files.each do |tagmanifest_file|
|
119
|
+
FileUtils.rm tagmanifest_file
|
120
|
+
end
|
121
|
+
|
122
|
+
# @bag.should_not be_valid
|
123
|
+
expect(@bag).not_to be_valid
|
124
|
+
expect(@bag.errors.on(:completeness)).not_to be_empty
|
125
|
+
end
|
127
126
|
end
|
128
|
-
end
|
129
127
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
128
|
+
describe "tag manifest validation" do
|
129
|
+
it "is invalid if listed tag file does not exist" do
|
130
|
+
# add a file and then remove it through the back door
|
131
|
+
@bag.add_tag_file("tag-k") { |io| io.puts "time to go" }
|
132
|
+
@bag.tagmanifest!
|
135
133
|
|
136
|
-
|
134
|
+
FileUtils.rm File.join(@bag.bag_dir, "tag-k")
|
137
135
|
|
138
|
-
|
139
|
-
|
140
|
-
|
136
|
+
# @bag.should_not be_valid
|
137
|
+
expect(@bag).not_to be_valid
|
138
|
+
expect(@bag.errors.on(:completeness)).not_to be_empty
|
139
|
+
end
|
141
140
|
end
|
142
141
|
end
|
143
|
-
|
144
142
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bagit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Johnson, Francesco Lazzarino, Jamie Little
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: validatable
|
@@ -52,20 +52,62 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: coveralls
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry-byebug
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
55
97
|
- !ruby/object:Gem::Dependency
|
56
98
|
name: rake
|
57
99
|
requirement: !ruby/object:Gem::Requirement
|
58
100
|
requirements:
|
59
|
-
- - "
|
101
|
+
- - ">="
|
60
102
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
103
|
+
version: 12.3.3
|
62
104
|
type: :development
|
63
105
|
prerelease: false
|
64
106
|
version_requirements: !ruby/object:Gem::Requirement
|
65
107
|
requirements:
|
66
|
-
- - "
|
108
|
+
- - ">="
|
67
109
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
110
|
+
version: 12.3.3
|
69
111
|
- !ruby/object:Gem::Dependency
|
70
112
|
name: rspec
|
71
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,7 +123,7 @@ dependencies:
|
|
81
123
|
- !ruby/object:Gem::Version
|
82
124
|
version: '3'
|
83
125
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
126
|
+
name: standard
|
85
127
|
requirement: !ruby/object:Gem::Requirement
|
86
128
|
requirements:
|
87
129
|
- - ">="
|
@@ -146,8 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
188
|
- !ruby/object:Gem::Version
|
147
189
|
version: '0'
|
148
190
|
requirements: []
|
149
|
-
|
150
|
-
rubygems_version: 2.5.1
|
191
|
+
rubygems_version: 3.0.8
|
151
192
|
signing_key:
|
152
193
|
specification_version: 4
|
153
194
|
summary: BagIt package generation and validation
|