moab-versioning 4.2.1 → 4.2.2
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 +4 -4
- data/lib/moab.rb +1 -1
- data/lib/moab/bagger.rb +15 -15
- data/lib/moab/config.rb +0 -2
- data/lib/moab/deposit_bag_validator.rb +1 -1
- data/lib/moab/file_group.rb +13 -15
- data/lib/moab/file_group_difference.rb +18 -21
- data/lib/moab/file_group_difference_subset.rb +2 -4
- data/lib/moab/file_instance.rb +1 -3
- data/lib/moab/file_instance_difference.rb +3 -5
- data/lib/moab/file_inventory.rb +17 -27
- data/lib/moab/file_inventory_difference.rb +5 -7
- data/lib/moab/file_manifestation.rb +4 -6
- data/lib/moab/file_signature.rb +29 -40
- data/lib/moab/signature_catalog.rb +11 -13
- data/lib/moab/signature_catalog_entry.rb +1 -3
- data/lib/moab/storage_object.rb +12 -19
- data/lib/moab/storage_object_validator.rb +22 -8
- data/lib/moab/storage_object_version.rb +25 -27
- data/lib/moab/storage_repository.rb +6 -13
- data/lib/moab/storage_services.rb +6 -8
- data/lib/moab/utc_time.rb +0 -2
- data/lib/moab/verification_result.rb +0 -2
- data/lib/moab/version_metadata.rb +1 -3
- data/lib/moab/version_metadata_entry.rb +2 -4
- data/lib/moab/version_metadata_event.rb +0 -2
- data/lib/serializer/manifest.rb +5 -5
- data/lib/serializer/serializable.rb +34 -34
- data/lib/stanford/active_fedora_object.rb +0 -2
- data/lib/stanford/content_inventory.rb +22 -20
- data/lib/stanford/dor_metadata.rb +0 -2
- data/lib/stanford/storage_object_validator.rb +0 -2
- data/lib/stanford/storage_repository.rb +1 -2
- data/lib/stanford/storage_services.rb +5 -7
- metadata +3 -3
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'moab'
|
2
|
-
|
3
1
|
module Moab
|
4
2
|
# Compares two {FileInventory} instances based primarily on file signatures and secondarily on file pathnames.
|
5
3
|
# Although the usual use will be to compare the content of 2 different temporal versions of the same object,
|
@@ -24,7 +22,7 @@ module Moab
|
|
24
22
|
|
25
23
|
# (see Serializable#initialize)
|
26
24
|
def initialize(opts = {})
|
27
|
-
@group_differences =
|
25
|
+
@group_differences = []
|
28
26
|
super(opts)
|
29
27
|
end
|
30
28
|
|
@@ -34,7 +32,7 @@ module Moab
|
|
34
32
|
|
35
33
|
# @attribute
|
36
34
|
# @return [Integer] the number of differences found between the two inventories that were compared (dynamically calculated)
|
37
|
-
attribute :difference_count, Integer, :tag => 'differenceCount', :on_save =>
|
35
|
+
attribute :difference_count, Integer, :tag => 'differenceCount', :on_save => proc { |i| i.to_s }
|
38
36
|
|
39
37
|
def difference_count
|
40
38
|
@group_differences.inject(0) { |sum, group| sum + group.difference_count }
|
@@ -66,7 +64,7 @@ module Moab
|
|
66
64
|
|
67
65
|
# @return [Array<String>] The data fields to include in summary reports
|
68
66
|
def summary_fields
|
69
|
-
%w
|
67
|
+
%w[digital_object_id difference_count basis other report_datetime group_differences]
|
70
68
|
end
|
71
69
|
|
72
70
|
# @param [String] group_id The identifer of the group to be selected
|
@@ -110,11 +108,11 @@ module Moab
|
|
110
108
|
# @return [Hash] Serializes the data and then filters it to report only the changes
|
111
109
|
def differences_detail
|
112
110
|
#return self.summary if difference_count == 0
|
113
|
-
inv_diff =
|
111
|
+
inv_diff = to_hash
|
114
112
|
inv_diff["group_differences"].each_value do |group_diff|
|
115
113
|
delete_subsets = []
|
116
114
|
group_diff["subsets"].each do |change_type, subset|
|
117
|
-
delete_subsets << change_type if change_type == "identical"
|
115
|
+
delete_subsets << change_type if (change_type == "identical") || (subset["count"] == 0)
|
118
116
|
end
|
119
117
|
delete_subsets.each do |change_type|
|
120
118
|
group_diff["subsets"].delete(change_type)
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'moab'
|
2
|
-
|
3
1
|
module Moab
|
4
2
|
# A container for a file signature and all the physical file instances that have that signature
|
5
3
|
# This element has one child {FileSignature} element, and one or more {FileInstance} elements
|
@@ -24,7 +22,7 @@ module Moab
|
|
24
22
|
|
25
23
|
# (see Serializable#initialize)
|
26
24
|
def initialize(opts = {})
|
27
|
-
@instances =
|
25
|
+
@instances = []
|
28
26
|
super(opts)
|
29
27
|
end
|
30
28
|
|
@@ -47,7 +45,7 @@ module Moab
|
|
47
45
|
# @api internal
|
48
46
|
# @return [Array<String>] Create an array from all the file paths of the child {FileInstance} objects
|
49
47
|
def paths
|
50
|
-
instances.collect
|
48
|
+
instances.collect(&:path)
|
51
49
|
end
|
52
50
|
|
53
51
|
# @api internal
|
@@ -76,8 +74,8 @@ module Moab
|
|
76
74
|
# @param other [FileManifestation] The {FileManifestation} object to compare with self
|
77
75
|
# @return [Boolean] True if {FileManifestation} objects have same content
|
78
76
|
def ==(other)
|
79
|
-
return false unless
|
80
|
-
(
|
77
|
+
return false unless other.respond_to?(:signature) && other.respond_to?(:instances) # Cannot equal an incomparable type!
|
78
|
+
(signature == other.signature) && (instances == other.instances)
|
81
79
|
end
|
82
80
|
end
|
83
81
|
end
|
data/lib/moab/file_signature.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'moab'
|
2
|
-
|
3
1
|
module Moab
|
4
2
|
# The fixity properties of a file, used to determine file content equivalence regardless of filename.
|
5
3
|
# Placing this data in a class by itself facilitates using file size together with the MD5 and SHA1 checksums
|
@@ -46,19 +44,19 @@ module Moab
|
|
46
44
|
|
47
45
|
# @attribute
|
48
46
|
# @return [Integer] The size of the file in bytes
|
49
|
-
attribute :size, Integer, :on_save =>
|
47
|
+
attribute :size, Integer, :on_save => proc { |n| n.to_s }
|
50
48
|
|
51
49
|
# @attribute
|
52
50
|
# @return [String] The MD5 checksum value of the file
|
53
|
-
attribute :md5, String, :on_save =>
|
51
|
+
attribute :md5, String, :on_save => proc { |n| n.nil? ? "" : n.to_s }
|
54
52
|
|
55
53
|
# @attribute
|
56
54
|
# @return [String] The SHA1 checksum value of the file
|
57
|
-
attribute :sha1, String, :on_save =>
|
55
|
+
attribute :sha1, String, :on_save => proc { |n| n.nil? ? "" : n.to_s }
|
58
56
|
|
59
57
|
# @attribute
|
60
58
|
# @return [String] The SHA256 checksum value of the file
|
61
|
-
attribute :sha256, String, :on_save =>
|
59
|
+
attribute :sha256, String, :on_save => proc { |n| n.nil? ? "" : n.to_s }
|
62
60
|
|
63
61
|
KNOWN_ALGOS = {
|
64
62
|
md5: proc { Digest::MD5.new },
|
@@ -106,12 +104,11 @@ module Moab
|
|
106
104
|
|
107
105
|
# @return [Hash<Symbol,String>] A hash of the checksum data
|
108
106
|
def checksums
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
checksum_hash
|
107
|
+
{
|
108
|
+
md5: md5,
|
109
|
+
sha1: sha1,
|
110
|
+
sha256: sha256
|
111
|
+
}.reject { |_key, value| value.nil? || value.empty? }
|
115
112
|
end
|
116
113
|
|
117
114
|
# @return [Boolean] The signature contains all of the 3 desired checksums
|
@@ -120,24 +117,21 @@ module Moab
|
|
120
117
|
end
|
121
118
|
|
122
119
|
# @api internal
|
123
|
-
# @return [Hash<Symbol
|
120
|
+
# @return [Hash<Symbol => String>] A hash of fixity data from this signataure object
|
124
121
|
def fixity
|
125
|
-
|
126
|
-
fixity_hash[:size] = @size.to_s
|
127
|
-
fixity_hash.merge!(checksums)
|
128
|
-
fixity_hash
|
122
|
+
{ size: size.to_s }.merge(checksums)
|
129
123
|
end
|
130
124
|
|
131
125
|
# @api internal
|
132
126
|
# @param other [FileSignature] The other file signature being compared to this signature
|
133
127
|
# @return [Boolean] Returns true if self and other have comparable fixity data.
|
134
128
|
def eql?(other)
|
135
|
-
return false unless
|
136
|
-
return false if
|
137
|
-
self_checksums =
|
129
|
+
return false unless other.respond_to?(:size) && other.respond_to?(:checksums)
|
130
|
+
return false if size.to_i != other.size.to_i
|
131
|
+
self_checksums = checksums
|
138
132
|
other_checksums = other.checksums
|
139
133
|
matching_keys = self_checksums.keys & other_checksums.keys
|
140
|
-
return false if matching_keys.
|
134
|
+
return false if matching_keys.empty?
|
141
135
|
matching_keys.each do |key|
|
142
136
|
return false if self_checksums[key] != other_checksums[key]
|
143
137
|
end
|
@@ -181,31 +175,26 @@ module Moab
|
|
181
175
|
# @return [FileSignature] The full signature derived from the file, unless the fixity is inconsistent with current values
|
182
176
|
def normalized_signature(pathname)
|
183
177
|
sig_from_file = FileSignature.new.signature_from_file(pathname)
|
184
|
-
if
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
# One or more of the fixity values is inconsistent, so raise an exception
|
189
|
-
raise "Signature inconsistent between inventory and file for #{pathname}: #{self.diff(sig_from_file).inspect}"
|
190
|
-
end
|
178
|
+
return sig_from_file if eql?(sig_from_file)
|
179
|
+
# The full signature from file is consistent with current values, or...
|
180
|
+
# One or more of the fixity values is inconsistent, so raise an exception
|
181
|
+
raise "Signature inconsistent between inventory and file for #{pathname}: #{diff(sig_from_file).inspect}"
|
191
182
|
end
|
192
183
|
|
193
184
|
# @return [Hash<Symbol,String>] Key is type (e.g. :sha1), value is checksum names (e.g. ['SHA-1', 'SHA1'])
|
194
|
-
def
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
185
|
+
def self.checksum_names_for_type
|
186
|
+
{
|
187
|
+
md5: ['MD5'],
|
188
|
+
sha1: ['SHA-1', 'SHA1'],
|
189
|
+
sha256: ['SHA-256', 'SHA256']
|
190
|
+
}
|
200
191
|
end
|
201
192
|
|
202
193
|
# @return [Hash<String, Symbol>] Key is checksum name (e.g. MD5), value is checksum type (e.g. :md5)
|
203
|
-
def
|
204
|
-
type_for_name =
|
205
|
-
|
206
|
-
names.each
|
207
|
-
type_for_name[name] = type
|
208
|
-
end
|
194
|
+
def self.checksum_type_for_name
|
195
|
+
type_for_name = {}
|
196
|
+
checksum_names_for_type.each do |type, names|
|
197
|
+
names.each { |name| type_for_name[name] = type }
|
209
198
|
end
|
210
199
|
type_for_name
|
211
200
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'moab'
|
2
|
-
|
3
1
|
module Moab
|
4
2
|
# A digital object's Signature Catalog is derived from an filtered aggregation of the file inventories
|
5
3
|
# of a digital object's set of versions. (see {#update})
|
@@ -32,8 +30,8 @@ module Moab
|
|
32
30
|
|
33
31
|
# (see Serializable#initialize)
|
34
32
|
def initialize(opts = {})
|
35
|
-
@entries =
|
36
|
-
@signature_hash =
|
33
|
+
@entries = []
|
34
|
+
@signature_hash = {}
|
37
35
|
super(opts)
|
38
36
|
end
|
39
37
|
|
@@ -43,7 +41,7 @@ module Moab
|
|
43
41
|
|
44
42
|
# @attribute
|
45
43
|
# @return [Integer] The ordinal version number
|
46
|
-
attribute :version_id, Integer, :tag => 'versionId', :key => true, :on_save =>
|
44
|
+
attribute :version_id, Integer, :tag => 'versionId', :key => true, :on_save => proc { |n| n.to_s }
|
47
45
|
|
48
46
|
# @return [String] The unique identifier concatenating digital object id with version id
|
49
47
|
def composite_key
|
@@ -64,7 +62,7 @@ module Moab
|
|
64
62
|
|
65
63
|
# @attribute
|
66
64
|
# @return [Integer] The total number of data files (dynamically calculated)
|
67
|
-
attribute :file_count, Integer, :tag => 'fileCount', :on_save =>
|
65
|
+
attribute :file_count, Integer, :tag => 'fileCount', :on_save => proc { |t| t.to_s }
|
68
66
|
|
69
67
|
def file_count
|
70
68
|
entries.size
|
@@ -72,7 +70,7 @@ module Moab
|
|
72
70
|
|
73
71
|
# @attribute
|
74
72
|
# @return [Integer] The total size (in bytes) of all data files (dynamically calculated)
|
75
|
-
attribute :byte_count, Integer, :tag => 'byteCount', :on_save =>
|
73
|
+
attribute :byte_count, Integer, :tag => 'byteCount', :on_save => proc { |t| t.to_s }
|
76
74
|
|
77
75
|
def byte_count
|
78
76
|
entries.inject(0) { |sum, entry| sum + entry.signature.size.to_i }
|
@@ -80,7 +78,7 @@ module Moab
|
|
80
78
|
|
81
79
|
# @attribute
|
82
80
|
# @return [Integer] The total disk usage (in 1 kB blocks) of all data files (estimating du -k result) (dynamically calculated)
|
83
|
-
attribute :block_count, Integer, :tag => 'blockCount', :on_save =>
|
81
|
+
attribute :block_count, Integer, :tag => 'blockCount', :on_save => proc { |t| t.to_s }
|
84
82
|
|
85
83
|
def block_count
|
86
84
|
block_size = 1024
|
@@ -89,7 +87,7 @@ module Moab
|
|
89
87
|
|
90
88
|
# @return [Array<String>] The data fields to include in summary reports
|
91
89
|
def summary_fields
|
92
|
-
%w
|
90
|
+
%w[digital_object_id version_id catalog_datetime file_count byte_count block_count]
|
93
91
|
end
|
94
92
|
|
95
93
|
# @attribute
|
@@ -134,7 +132,7 @@ module Moab
|
|
134
132
|
end
|
135
133
|
group.files.each do |file|
|
136
134
|
unless file.signature.complete?
|
137
|
-
if @signature_hash.
|
135
|
+
if @signature_hash.key?(file.signature)
|
138
136
|
file.signature = @signature_hash.find { |k, _v| k == file.signature }[0]
|
139
137
|
elsif group_pathname
|
140
138
|
file_pathname = group_pathname.join(file.instances[0].path)
|
@@ -153,7 +151,7 @@ module Moab
|
|
153
151
|
def update(version_inventory, data_pathname)
|
154
152
|
version_inventory.groups.each do |group|
|
155
153
|
group.files.each do |file|
|
156
|
-
unless @signature_hash.
|
154
|
+
unless @signature_hash.key?(file.signature)
|
157
155
|
entry = SignatureCatalogEntry.new
|
158
156
|
entry.version_id = version_inventory.version_id
|
159
157
|
entry.group_id = group.group_id
|
@@ -183,11 +181,11 @@ module Moab
|
|
183
181
|
version_inventory.groups.each do |group|
|
184
182
|
group_addtions = FileGroup.new(:group_id => group.group_id)
|
185
183
|
group.files.each do |file|
|
186
|
-
unless @signature_hash.
|
184
|
+
unless @signature_hash.key?(file.signature)
|
187
185
|
group_addtions.add_file_instance(file.signature, file.instances[0])
|
188
186
|
end
|
189
187
|
end
|
190
|
-
version_additions.groups << group_addtions
|
188
|
+
version_additions.groups << group_addtions unless group_addtions.files.empty?
|
191
189
|
end
|
192
190
|
version_additions
|
193
191
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'moab'
|
2
|
-
|
3
1
|
module Moab
|
4
2
|
# A file-level entry in a digital object's {SignatureCatalog}.
|
5
3
|
# It has a child {FileSignature} element that identifies the file's contents (the bytestream)
|
@@ -25,7 +23,7 @@ module Moab
|
|
25
23
|
|
26
24
|
# @attribute
|
27
25
|
# @return [Integer] The ordinal version number
|
28
|
-
attribute :version_id, Integer, :tag => 'originalVersion', :key => true, :on_save =>
|
26
|
+
attribute :version_id, Integer, :tag => 'originalVersion', :key => true, :on_save => proc { |n| n.to_s }
|
29
27
|
|
30
28
|
# @attribute
|
31
29
|
# @return [String] The name of the file group
|
data/lib/moab/storage_object.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'moab'
|
2
|
-
|
3
1
|
module Moab
|
4
2
|
# A class to represent a digital object's repository storage location
|
5
3
|
# and methods for
|
@@ -122,27 +120,25 @@ module Moab
|
|
122
120
|
# @param version_id [Integer] The version identifier of an object version
|
123
121
|
# @return [String] The directory name of the version, relative to the digital object home directory (e.g v0002)
|
124
122
|
def self.version_dirname(version_id)
|
125
|
-
("v%04d"
|
123
|
+
format("v%04d", version_id)
|
126
124
|
end
|
127
125
|
|
128
126
|
# @return [Array<Integer>] The list of all version ids for this object
|
129
127
|
def version_id_list
|
130
|
-
list =
|
128
|
+
list = []
|
131
129
|
return list unless @object_pathname.exist?
|
132
130
|
@object_pathname.children.each do |dirname|
|
133
131
|
vnum = dirname.basename.to_s
|
134
|
-
if vnum =~ /^v(\d+)$/
|
135
|
-
list << vnum[1..-1].to_i
|
136
|
-
end
|
132
|
+
list << vnum[1..-1].to_i if vnum =~ /^v(\d+)$/
|
137
133
|
end
|
138
134
|
list.sort
|
139
135
|
end
|
140
136
|
|
141
137
|
# @return [Array<StorageObjectVersion>] The list of all versions in this storage object
|
142
138
|
def version_list
|
143
|
-
version_id_list.collect { |id|
|
139
|
+
version_id_list.collect { |id| storage_object_version(id) }
|
144
140
|
end
|
145
|
-
alias
|
141
|
+
alias versions version_list
|
146
142
|
|
147
143
|
# @return [Boolean] true if there are no versions yet in this object
|
148
144
|
def empty?
|
@@ -152,12 +148,12 @@ module Moab
|
|
152
148
|
# @api external
|
153
149
|
# @return [Integer] The identifier of the latest version of this object, or 0 if no versions exist
|
154
150
|
def current_version_id
|
155
|
-
@current_version_id ||=
|
151
|
+
@current_version_id ||= version_id_list.last || 0
|
156
152
|
end
|
157
153
|
|
158
154
|
# @return [StorageObjectVersion] The most recent version in the storage object
|
159
155
|
def current_version
|
160
|
-
|
156
|
+
storage_object_version(current_version_id)
|
161
157
|
end
|
162
158
|
|
163
159
|
# @api internal
|
@@ -191,21 +187,18 @@ module Moab
|
|
191
187
|
# * Version 0 is a special case used to generate empty manifests
|
192
188
|
# * Current version + 1 is used for creation of a new version
|
193
189
|
def storage_object_version(version_id)
|
194
|
-
|
195
|
-
|
196
|
-
else
|
197
|
-
raise "Version ID not specified"
|
198
|
-
end
|
190
|
+
raise "Version ID not specified" unless version_id
|
191
|
+
StorageObjectVersion.new(self, version_id)
|
199
192
|
end
|
200
193
|
|
201
194
|
# @return [VerificationResult] Return result of storage verification
|
202
195
|
def verify_object_storage
|
203
196
|
result = VerificationResult.new(digital_object_id)
|
204
|
-
|
197
|
+
version_list.each do |version|
|
205
198
|
result.subentities << version.verify_version_storage
|
206
199
|
end
|
207
200
|
result.subentities << current_version.verify_signature_catalog
|
208
|
-
result.verified = result.subentities.all?
|
201
|
+
result.verified = result.subentities.all?(&:verified)
|
209
202
|
result
|
210
203
|
end
|
211
204
|
|
@@ -216,7 +209,7 @@ module Moab
|
|
216
209
|
recovery_object = StorageObject.new(@digital_object_id, recovery_path, false)
|
217
210
|
recovery_object.versions.each do |recovery_version|
|
218
211
|
version_id = recovery_version.version_id
|
219
|
-
storage_version =
|
212
|
+
storage_version = storage_object_version(version_id)
|
220
213
|
# rename/save the original
|
221
214
|
storage_version.deactivate(timestamp)
|
222
215
|
# copy the recovered version into place
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'moab'
|
2
1
|
require 'set'
|
3
2
|
|
4
3
|
module Moab
|
@@ -59,11 +58,11 @@ module Moab
|
|
59
58
|
NO_SIGNATURE_CATALOG => "Version %{addl}: Missing signatureCatalog.xml",
|
60
59
|
NO_MANIFEST_INVENTORY => "Version %{addl}: Missing manifestInventory.xml",
|
61
60
|
NO_FILES_IN_MANIFEST_DIR => "Version %{addl}: No files present in manifest dir",
|
62
|
-
METADATA_SUB_DIRS_DETECTED => "Version %{
|
61
|
+
METADATA_SUB_DIRS_DETECTED => "Version %{version}: metadata directory should only contain files, not directories. Found directory: %{dir}",
|
63
62
|
VERSIONS_NOT_IN_ORDER => "Should contain only sequential version directories. Current directories: %{addl}",
|
64
63
|
NO_FILES_IN_METADATA_DIR => "Version %{addl}: No files present in metadata dir",
|
65
64
|
NO_FILES_IN_CONTENT_DIR => "Version %{addl}: No files present in content dir",
|
66
|
-
CONTENT_SUB_DIRS_DETECTED => "Version %{
|
65
|
+
CONTENT_SUB_DIRS_DETECTED => "Version %{version}: content directory should only contain files, not directories. Found directory: %{dir}",
|
67
66
|
BAD_SUB_DIR_IN_CONTENT_DIR => "Version %{addl}: content directory has forbidden sub-directory name: vnnnn or #{FORBIDDEN_CONTENT_SUB_DIRS}"
|
68
67
|
}.freeze
|
69
68
|
end
|
@@ -139,7 +138,8 @@ module Moab
|
|
139
138
|
errors = []
|
140
139
|
content_dir_path = File.join(version_path, DATA_DIR, CONTENT_DIR)
|
141
140
|
errors << result_hash(NO_FILES_IN_CONTENT_DIR, basename(version_path)) if directory_entries(content_dir_path).empty?
|
142
|
-
|
141
|
+
content_sub_dir = contains_sub_dir?(content_dir_path)
|
142
|
+
errors << result_hash(CONTENT_SUB_DIRS_DETECTED, version: basename(version_path), dir: content_sub_dir) if content_sub_dir && !allow_content_subdirs
|
143
143
|
if allow_content_subdirs && contains_sub_dir?(content_dir_path) && contains_forbidden_content_sub_dir?(content_dir_path)
|
144
144
|
errors << result_hash(BAD_SUB_DIR_IN_CONTENT_DIR, basename(version_path))
|
145
145
|
end
|
@@ -158,7 +158,8 @@ module Moab
|
|
158
158
|
errors = []
|
159
159
|
metadata_dir_path = File.join(version_path, DATA_DIR, METADATA_DIR)
|
160
160
|
errors << result_hash(NO_FILES_IN_METADATA_DIR, basename(version_path)) if directory_entries(metadata_dir_path).empty?
|
161
|
-
|
161
|
+
metadata_sub_dir = contains_sub_dir?(metadata_dir_path)
|
162
|
+
errors << result_hash(METADATA_SUB_DIRS_DETECTED, version: basename(version_path), dir: metadata_sub_dir) if metadata_sub_dir
|
162
163
|
errors
|
163
164
|
end
|
164
165
|
|
@@ -204,12 +205,25 @@ module Moab
|
|
204
205
|
path.split(File::SEPARATOR)[-1]
|
205
206
|
end
|
206
207
|
|
207
|
-
|
208
|
-
|
208
|
+
# @param [Integer] response_code one of the recognized values in error_code_to_messages
|
209
|
+
# @param [Hash<Symbol => String>, String] msg_args Value(s) folded into the error message
|
210
|
+
# @return [Hash<Integer => String>] single key/value Hash
|
211
|
+
# @example Usage
|
212
|
+
# sov.result_hash(10, '/some/dir')
|
213
|
+
# sov.result_hash(10, addl: '/some/dir') # equivalent
|
214
|
+
# sov.result_hash(8, version: '3', dir: '/other/dir')
|
215
|
+
def result_hash(response_code, msg_args = nil)
|
216
|
+
{ response_code => error_code_msg(response_code, msg_args) }
|
209
217
|
end
|
210
218
|
|
211
219
|
def error_code_msg(response_code, addl = nil)
|
212
|
-
|
220
|
+
arg_hash = {}
|
221
|
+
if addl.is_a?(Hash)
|
222
|
+
arg_hash.merge!(addl)
|
223
|
+
else
|
224
|
+
arg_hash[:addl] = addl
|
225
|
+
end
|
226
|
+
self.class.error_code_to_messages[response_code] % arg_hash
|
213
227
|
end
|
214
228
|
|
215
229
|
def check_required_manifest_files(dir, version)
|