moab-versioning 2.3.0 → 2.4.0
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 -0
- data/lib/moab/storage_object_validator.rb +180 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2cf042d5123eebc1b9c1b9693e05c45c99912b39
|
4
|
+
data.tar.gz: 6e52763c9a40797606c858e7794eb9014d2fab7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2ee7236ad243d907c51fdd82835c0e12829dc99a2b1a65bc1f9ed2b3c0d70ce396ebe7c58459cfdf0a2c4aa3479363fa80352ce3a343e31a308ba78e2e52652
|
7
|
+
data.tar.gz: 0c61777fa909a4b57563ad3a9a94f1a8c46a6096dc58d97dd8c4ae86370c0e59899ae9dfb6805f3a96d00a20cb4a398e9bb3fc3d7615c5e0ba50d1b0bade36dd
|
data/lib/moab.rb
CHANGED
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'moab'
|
2
|
+
|
3
|
+
module Moab
|
4
|
+
# Given a druid path, are the contents actually a well-formed Moab?
|
5
|
+
# Shameless green: repetitious code included.
|
6
|
+
class StorageObjectValidator
|
7
|
+
|
8
|
+
EXPECTED_DATA_SUB_DIRS = ["content", "metadata"].freeze
|
9
|
+
IMPLICIT_DIRS = ['.', '..'].freeze # unlike Find.find, Dir.entries returns these
|
10
|
+
DATA_DIR_NAME = "data".freeze
|
11
|
+
EXPECTED_VERSION_SUB_DIRS = [DATA_DIR_NAME, "manifests"].freeze
|
12
|
+
MANIFEST_INVENTORY_PATH = 'manifests/manifestInventory.xml'.freeze
|
13
|
+
SIGNATURE_CATALOG_PATH = 'manifests/signatureCatalog.xml'.freeze
|
14
|
+
|
15
|
+
# error codes
|
16
|
+
INCORRECT_DIR = 0
|
17
|
+
MISSING_DIR = 1
|
18
|
+
EXTRA_CHILD_DETECTED = 2
|
19
|
+
VERSION_DIR_BAD_FORMAT = 3
|
20
|
+
NO_SIGNATURE_CATALOG = 4
|
21
|
+
NO_MANIFEST_INVENTORY = 5
|
22
|
+
NO_XML_FILES = 6
|
23
|
+
VERSIONS_NOT_IN_ORDER = 7
|
24
|
+
FILES_IN_VERSION_DIR = 8
|
25
|
+
|
26
|
+
ERROR_CODE_TO_MESSAGES = {
|
27
|
+
INCORRECT_DIR=> "Incorrect items in path",
|
28
|
+
MISSING_DIR => "Missing directory: %{addl}",
|
29
|
+
EXTRA_CHILD_DETECTED => "Unexpected item in path: %{addl}",
|
30
|
+
VERSION_DIR_BAD_FORMAT => "Version directory name not in 'v00xx' format",
|
31
|
+
FILES_IN_VERSION_DIR => "Top level should contain only sequential version directories. Also contains files: %{addl}",
|
32
|
+
NO_SIGNATURE_CATALOG => "Version: %{addl} Missing signatureCatalog.xml",
|
33
|
+
NO_MANIFEST_INVENTORY => "Version: %{addl} Missing manifestInventory.xml",
|
34
|
+
NO_XML_FILES => "Version: %{addl} Missing all required metadata files",
|
35
|
+
VERSIONS_NOT_IN_ORDER => "Should contain only sequential version directories. Current directories: %{addl}"
|
36
|
+
}.freeze
|
37
|
+
|
38
|
+
attr_reader :storage_obj_path
|
39
|
+
|
40
|
+
def initialize(storage_object)
|
41
|
+
@storage_obj_path = storage_object.object_pathname
|
42
|
+
@directory_entries_hash = {}
|
43
|
+
end
|
44
|
+
|
45
|
+
def validation_errors
|
46
|
+
errors = []
|
47
|
+
errors.concat check_correctly_named_version_dirs
|
48
|
+
errors.concat check_sequential_version_dirs if errors.empty?
|
49
|
+
errors.concat check_correctly_formed_moabs if errors.empty?
|
50
|
+
errors
|
51
|
+
end
|
52
|
+
|
53
|
+
# TODO: Figure out which methods should be public
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def version_directories
|
58
|
+
@vdirs ||= sub_dirs(storage_obj_path)
|
59
|
+
end
|
60
|
+
|
61
|
+
def check_correctly_named_version_dirs
|
62
|
+
errors = []
|
63
|
+
version_directories.each do |version_dir|
|
64
|
+
errors << result_hash(VERSION_DIR_BAD_FORMAT) unless version_dir =~ /^[v]\d{4}$/
|
65
|
+
end
|
66
|
+
errors
|
67
|
+
end
|
68
|
+
|
69
|
+
# This method will be called only if the version directories are correctly named
|
70
|
+
def check_sequential_version_dirs
|
71
|
+
errors = []
|
72
|
+
version_directories.each_with_index do |dir_name, index|
|
73
|
+
expected_vers_num = index + 1 # version numbering starts at 1, array indexing starts at 0
|
74
|
+
if dir_name[1..-1].to_i != expected_vers_num
|
75
|
+
errors << result_hash(VERSIONS_NOT_IN_ORDER, version_directories)
|
76
|
+
break
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
errors
|
81
|
+
end
|
82
|
+
|
83
|
+
def check_correctly_formed_moabs
|
84
|
+
errors = []
|
85
|
+
version_directories.each do |version_dir|
|
86
|
+
version_path = "#{storage_obj_path}/#{version_dir}"
|
87
|
+
version_sub_dirs = sub_dirs(version_path)
|
88
|
+
before_result_size = errors.size
|
89
|
+
errors.concat check_sub_dirs(version_sub_dirs, version_dir, EXPECTED_VERSION_SUB_DIRS)
|
90
|
+
after_result_size = errors.size
|
91
|
+
# run the following checks if this version dir passes check_sub_dirs, even if some prior version dirs didn't
|
92
|
+
if before_result_size == after_result_size
|
93
|
+
data_dir_path = "#{version_path}/#{DATA_DIR_NAME}"
|
94
|
+
data_sub_dirs = sub_dirs(data_dir_path)
|
95
|
+
errors.concat check_sub_dirs(data_sub_dirs, version_dir, EXPECTED_DATA_SUB_DIRS)
|
96
|
+
errors.concat check_required_manifest_files(version_path, version_dir)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
errors
|
101
|
+
end
|
102
|
+
|
103
|
+
def check_sub_dirs(sub_dirs, version, required_sub_dirs)
|
104
|
+
errors = []
|
105
|
+
sub_dir_count = sub_dirs.size
|
106
|
+
if sub_dir_count == required_sub_dirs.size
|
107
|
+
errors.concat expected_dirs(sub_dirs, version, required_sub_dirs)
|
108
|
+
elsif sub_dir_count > required_sub_dirs.size
|
109
|
+
errors.concat found_unexpected(sub_dirs, version, required_sub_dirs)
|
110
|
+
elsif sub_dir_count < required_sub_dirs.size
|
111
|
+
errors.concat missing_dir(sub_dirs, version, required_sub_dirs)
|
112
|
+
end
|
113
|
+
errors
|
114
|
+
end
|
115
|
+
|
116
|
+
# This method removes the implicit '.' and '..' directories.
|
117
|
+
# Returns an array of strings.
|
118
|
+
def directory_entries(path)
|
119
|
+
@directory_entries_hash[path] ||=
|
120
|
+
begin
|
121
|
+
dirs = []
|
122
|
+
(Dir.entries(path).sort - IMPLICIT_DIRS).each do |child|
|
123
|
+
dirs << child
|
124
|
+
end
|
125
|
+
dirs
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def sub_dirs(path)
|
130
|
+
directory_entries(path)
|
131
|
+
end
|
132
|
+
|
133
|
+
def found_unexpected(array, version, required_sub_dirs)
|
134
|
+
errors = []
|
135
|
+
unexpected = (array - required_sub_dirs)
|
136
|
+
unexpected = "#{unexpected} Version: #{version}"
|
137
|
+
errors << result_hash(EXTRA_CHILD_DETECTED, unexpected)
|
138
|
+
errors
|
139
|
+
end
|
140
|
+
|
141
|
+
def missing_dir(array, version, required_sub_dirs)
|
142
|
+
errors = []
|
143
|
+
missing = (required_sub_dirs - array)
|
144
|
+
missing ="#{missing} Version: #{version}"
|
145
|
+
errors << result_hash(MISSING_DIR, missing)
|
146
|
+
errors
|
147
|
+
end
|
148
|
+
|
149
|
+
def expected_dirs(array, _version, required_sub_dirs)
|
150
|
+
errors = []
|
151
|
+
errors << result_hash(INCORRECT_DIR) unless array == required_sub_dirs
|
152
|
+
errors
|
153
|
+
end
|
154
|
+
|
155
|
+
def result_hash(response_code, addl=nil)
|
156
|
+
{ response_code => error_code_msg(response_code, addl) }
|
157
|
+
end
|
158
|
+
|
159
|
+
def error_code_msg(response_code, addl=nil)
|
160
|
+
format(ERROR_CODE_TO_MESSAGES[response_code], addl: addl)
|
161
|
+
end
|
162
|
+
|
163
|
+
def check_required_manifest_files(dir, version)
|
164
|
+
errors = []
|
165
|
+
has_manifest_inventory = File.exist?("#{dir}/#{MANIFEST_INVENTORY_PATH}")
|
166
|
+
has_signature_catalog = File.exist?("#{dir}/#{SIGNATURE_CATALOG_PATH}")
|
167
|
+
result = if has_manifest_inventory && has_signature_catalog
|
168
|
+
nil
|
169
|
+
elsif has_manifest_inventory && !has_signature_catalog
|
170
|
+
result_hash(NO_SIGNATURE_CATALOG, version)
|
171
|
+
elsif !has_manifest_inventory && has_signature_catalog
|
172
|
+
result_hash(NO_MANIFEST_INVENTORY, version)
|
173
|
+
else
|
174
|
+
result_hash(NO_XML_FILES, version)
|
175
|
+
end
|
176
|
+
errors << result if result
|
177
|
+
errors
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moab-versioning
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Darren Weber
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2017-11-
|
14
|
+
date: 2017-11-02 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: confstruct
|
@@ -261,6 +261,7 @@ files:
|
|
261
261
|
- lib/moab/signature_catalog_entry.rb
|
262
262
|
- lib/moab/stanford.rb
|
263
263
|
- lib/moab/storage_object.rb
|
264
|
+
- lib/moab/storage_object_validator.rb
|
264
265
|
- lib/moab/storage_object_version.rb
|
265
266
|
- lib/moab/storage_repository.rb
|
266
267
|
- lib/moab/storage_services.rb
|
@@ -296,7 +297,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
296
297
|
requirements:
|
297
298
|
- - ">="
|
298
299
|
- !ruby/object:Gem::Version
|
299
|
-
version:
|
300
|
+
version: '0'
|
300
301
|
requirements: []
|
301
302
|
rubyforge_project:
|
302
303
|
rubygems_version: 2.6.11
|