moab-versioning 4.3.0 → 5.0.0.beta1
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/bagger.rb +7 -2
- data/lib/moab/config.rb +40 -7
- data/lib/moab/exceptions.rb +6 -0
- data/lib/moab/file_group.rb +12 -9
- data/lib/moab/file_group_difference.rb +26 -23
- data/lib/moab/file_group_difference_subset.rb +5 -3
- data/lib/moab/file_instance.rb +4 -1
- data/lib/moab/file_instance_difference.rb +5 -3
- data/lib/moab/file_inventory.rb +13 -9
- data/lib/moab/file_inventory_difference.rb +8 -6
- data/lib/moab/file_manifestation.rb +5 -2
- data/lib/moab/file_signature.rb +12 -7
- data/lib/moab/signature_catalog.rb +13 -13
- data/lib/moab/signature_catalog_entry.rb +6 -4
- data/lib/moab/stanford.rb +2 -10
- data/lib/moab/storage_object.rb +11 -5
- data/lib/moab/storage_object_validator.rb +24 -10
- data/lib/moab/storage_object_version.rb +19 -12
- data/lib/moab/storage_repository.rb +49 -7
- data/lib/moab/storage_services.rb +12 -9
- data/lib/moab/utc_time.rb +2 -0
- data/lib/moab/verification_result.rb +4 -3
- data/lib/moab/version_metadata_entry.rb +6 -4
- data/lib/moab.rb +2 -9
- data/lib/serializer/manifest.rb +4 -2
- data/lib/serializer/serializable.rb +6 -1
- data/lib/serializer.rb +2 -0
- data/lib/stanford/content_inventory.rb +23 -19
- data/lib/stanford/storage_object_validator.rb +2 -0
- data/lib/stanford/storage_repository.rb +6 -2
- data/lib/stanford/storage_services.rb +2 -0
- metadata +22 -42
- data/lib/moab/deposit_bag_validator.rb +0 -323
- data/lib/moab/version_metadata.rb +0 -32
- data/lib/moab/version_metadata_event.rb +0 -40
- data/lib/stanford/active_fedora_object.rb +0 -28
- data/lib/stanford/dor_metadata.rb +0 -41
- data/lib/stanford/moab_storage_directory.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d109f89af3228b70fe8e8b8cf394830b9397f4815a8c2324bb7e09e849432d6
|
4
|
+
data.tar.gz: 9695c1dfb048663ff1b56084597b8ece2973966704a07d610dd7e537da8be61b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85be7b541e0056fd50296092448b01c4d83195529c00bd4aaa244cce6596336b0ae7b41ba855f54b618666bf265a9986844eaf6a0f7a78eb811b6ccdaf1329ae
|
7
|
+
data.tar.gz: 72dc3ada7f22d891e883ce08fe55c7c783689f73b8868e6c29bb5040c2bcc45197c044a3b5823a94f3e8ade7de6b16ccc291902ee142ab0e68036824623c6695
|
data/lib/moab/bagger.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# A class used to create a BagIt package from a version inventory and a set of source files.
|
3
5
|
# The {#fill_bag} method is called with a package_mode parameter that specifies
|
@@ -141,6 +143,7 @@ module Moab
|
|
141
143
|
def deposit_group(group_id, source_dir)
|
142
144
|
group = bag_inventory.group(group_id)
|
143
145
|
return nil? if group.nil? || group.files.empty?
|
146
|
+
|
144
147
|
target_dir = bag_pathname.join('data', group_id)
|
145
148
|
group.path_list.each do |relative_path|
|
146
149
|
source = source_dir.join(relative_path)
|
@@ -158,6 +161,7 @@ module Moab
|
|
158
161
|
def reconstuct_group(group_id, storage_object_dir)
|
159
162
|
group = bag_inventory.group(group_id)
|
160
163
|
return nil? if group.nil? || group.files.empty?
|
164
|
+
|
161
165
|
target_dir = bag_pathname.join('data', group_id)
|
162
166
|
group.files.each do |file|
|
163
167
|
catalog_entry = signature_catalog.signature_hash[file.signature]
|
@@ -165,7 +169,7 @@ module Moab
|
|
165
169
|
file.instances.each do |instance|
|
166
170
|
target = target_dir.join(instance.path)
|
167
171
|
target.parent.mkpath
|
168
|
-
FileUtils.symlink source, target
|
172
|
+
FileUtils.symlink source, target unless target.exist?
|
169
173
|
end
|
170
174
|
end
|
171
175
|
true
|
@@ -260,6 +264,7 @@ module Moab
|
|
260
264
|
shell_execute(tar_cmd.sub('--force-local', ''))
|
261
265
|
end
|
262
266
|
raise(MoabRuntimeError, "Unable to create tarfile #{tar_pathname}") unless tar_pathname.exist?
|
267
|
+
|
263
268
|
true
|
264
269
|
end
|
265
270
|
|
@@ -273,7 +278,7 @@ module Moab
|
|
273
278
|
stdout
|
274
279
|
else
|
275
280
|
msg = "Shell command failed: [#{command}] caused by <STDERR = #{stderr}>"
|
276
|
-
msg << " STDOUT = #{stdout}" if stdout
|
281
|
+
msg << " STDOUT = #{stdout}" if stdout&.length&.positive?
|
277
282
|
raise(MoabStandardError, msg)
|
278
283
|
end
|
279
284
|
rescue SystemCallError => e
|
data/lib/moab/config.rb
CHANGED
@@ -1,10 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
|
-
#
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
# A place to store configuration for the gem
|
5
|
+
class Configuration
|
6
|
+
def initialize
|
7
|
+
@path_method = :druid_tree
|
8
|
+
@checksum_algos = [:md5, :sha1, :sha256]
|
9
|
+
end
|
10
|
+
|
11
|
+
def configure(&block)
|
12
|
+
instance_eval(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def storage_roots(new_value = nil)
|
16
|
+
@storage_roots = new_value if new_value
|
17
|
+
@storage_roots
|
18
|
+
end
|
19
|
+
|
20
|
+
def storage_trunk(new_value = nil)
|
21
|
+
@storage_trunk = new_value if new_value
|
22
|
+
@storage_trunk
|
23
|
+
end
|
24
|
+
|
25
|
+
def deposit_trunk(new_value = nil)
|
26
|
+
@deposit_trunk = new_value if new_value
|
27
|
+
@deposit_trunk
|
28
|
+
end
|
29
|
+
|
30
|
+
def path_method(new_value = nil)
|
31
|
+
@path_method = new_value if new_value
|
32
|
+
@path_method
|
33
|
+
end
|
34
|
+
|
35
|
+
def checksum_algos(new_value = nil)
|
36
|
+
@checksum_algos = new_value if new_value
|
37
|
+
@checksum_algos
|
38
|
+
end
|
9
39
|
end
|
40
|
+
|
41
|
+
# @return [Moab::Configuration] the configuration data
|
42
|
+
Config = Configuration.new
|
10
43
|
end
|
data/lib/moab/exceptions.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
class MoabRuntimeError < RuntimeError; end
|
5
|
+
|
3
6
|
class MoabStandardError < StandardError; end
|
4
7
|
|
5
8
|
class FileNotFoundException < MoabRuntimeError; end
|
9
|
+
|
6
10
|
class InvalidMetadataException < MoabRuntimeError; end
|
11
|
+
|
7
12
|
class InvalidSuriSyntaxError < MoabRuntimeError; end
|
13
|
+
|
8
14
|
class ObjectNotFoundException < MoabRuntimeError; end
|
9
15
|
end
|
data/lib/moab/file_group.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# A container for a standard subset of a digital objects {FileManifestation} objects
|
3
5
|
# Used to segregate depositor content from repository metadata files
|
@@ -28,15 +30,15 @@ module Moab
|
|
28
30
|
|
29
31
|
# @attribute
|
30
32
|
# @return [String] The name of the file group
|
31
|
-
attribute :group_id, String, :
|
33
|
+
attribute :group_id, String, tag: 'groupId', key: true
|
32
34
|
|
33
35
|
# @attribute
|
34
36
|
# @return [String] The directory location or other source of this groups file data
|
35
|
-
attribute :data_source, String, :
|
37
|
+
attribute :data_source, String, tag: 'dataSource'
|
36
38
|
|
37
39
|
# @attribute
|
38
40
|
# @return [Integer] The total number of data files (dynamically calculated)
|
39
|
-
attribute :file_count, Integer, :
|
41
|
+
attribute :file_count, Integer, tag: 'fileCount', on_save: proc { |i| i.to_s }
|
40
42
|
|
41
43
|
def file_count
|
42
44
|
files.inject(0) { |sum, manifestation| sum + manifestation.file_count }
|
@@ -44,7 +46,7 @@ module Moab
|
|
44
46
|
|
45
47
|
# @attribute
|
46
48
|
# @return [Integer] The total size (in bytes) of all data files (dynamically calculated)
|
47
|
-
attribute :byte_count, Integer, :
|
49
|
+
attribute :byte_count, Integer, tag: 'byteCount', on_save: proc { |i| i.to_s }
|
48
50
|
|
49
51
|
def byte_count
|
50
52
|
files.inject(0) { |sum, manifestation| sum + manifestation.byte_count }
|
@@ -52,7 +54,7 @@ module Moab
|
|
52
54
|
|
53
55
|
# @attribute
|
54
56
|
# @return [Integer] The total disk usage (in 1 kB blocks) of all data files (estimating du -k result) (dynamically calculated)
|
55
|
-
attribute :block_count, Integer, :
|
57
|
+
attribute :block_count, Integer, tag: 'blockCount', on_save: proc { |i| i.to_s }
|
56
58
|
|
57
59
|
def block_count
|
58
60
|
files.inject(0) { |sum, manifestation| sum + manifestation.block_count }
|
@@ -65,7 +67,7 @@ module Moab
|
|
65
67
|
|
66
68
|
# @attribute
|
67
69
|
# @return [Array<FileManifestation>] The set of files comprising the group
|
68
|
-
has_many :files, FileManifestation, :
|
70
|
+
has_many :files, FileManifestation, tag: 'file'
|
69
71
|
|
70
72
|
def files
|
71
73
|
signature_hash.values
|
@@ -161,9 +163,11 @@ module Moab
|
|
161
163
|
# @return [Boolean] Test whether the given path is contained within the {#base_directory}
|
162
164
|
def is_descendent_of_base?(pathname)
|
163
165
|
raise(MoabRuntimeError, "base_directory has not been set") if @base_directory.nil?
|
166
|
+
|
164
167
|
is_descendent = false
|
165
168
|
pathname.expand_path.ascend { |ancestor| is_descendent ||= (ancestor == @base_directory) }
|
166
169
|
raise(MoabRuntimeError, "#{pathname} is not a descendent of #{@base_directory}") unless is_descendent
|
170
|
+
|
167
171
|
is_descendent
|
168
172
|
end
|
169
173
|
|
@@ -203,6 +207,7 @@ module Moab
|
|
203
207
|
validated ||= is_descendent_of_base?(pathname)
|
204
208
|
pathname.children.sort.each do |child|
|
205
209
|
next if child.basename.to_s == '.DS_Store'
|
210
|
+
|
206
211
|
if child.directory?
|
207
212
|
harvest_directory(child, recursive, validated) if recursive
|
208
213
|
else
|
@@ -222,9 +227,7 @@ module Moab
|
|
222
227
|
instance = FileInstance.new.instance_from_file(pathname, @base_directory)
|
223
228
|
if @signatures_from_bag && @signatures_from_bag[pathname]
|
224
229
|
signature = @signatures_from_bag[pathname]
|
225
|
-
unless signature.complete?
|
226
|
-
signature = signature.normalized_signature(pathname)
|
227
|
-
end
|
230
|
+
signature = signature.normalized_signature(pathname) unless signature.complete?
|
228
231
|
else
|
229
232
|
signature = FileSignature.new.signature_from_file(pathname)
|
230
233
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# Performs analysis and reports the differences between two matching {FileGroup} objects.
|
3
5
|
# The descending elements of the report hold a detailed breakdown of file-level differences, organized by change type.
|
@@ -51,18 +53,18 @@ module Moab
|
|
51
53
|
|
52
54
|
# (see Serializable#initialize)
|
53
55
|
def initialize(opts = {})
|
54
|
-
@subset_hash = Hash.new { |hash, key| hash[key] = FileGroupDifferenceSubset.new(:
|
56
|
+
@subset_hash = Hash.new { |hash, key| hash[key] = FileGroupDifferenceSubset.new(change: key.to_s) }
|
55
57
|
super(opts)
|
56
58
|
end
|
57
59
|
|
58
60
|
# @attribute
|
59
61
|
# @return [String] The name of the file group
|
60
|
-
attribute :group_id, String, :
|
62
|
+
attribute :group_id, String, tag: 'groupId', key: true
|
61
63
|
|
62
64
|
# @attribute
|
63
65
|
# @return [Integer] the total number of differences found between the two inventories that were
|
64
66
|
# compared (dynamically calculated)
|
65
|
-
attribute :difference_count, Integer, :
|
67
|
+
attribute :difference_count, Integer, tag: 'differenceCount', on_save: proc { |i| i.to_s }
|
66
68
|
|
67
69
|
def difference_count
|
68
70
|
count = 0
|
@@ -74,49 +76,49 @@ module Moab
|
|
74
76
|
|
75
77
|
# @attribute
|
76
78
|
# @return [Integer] How many files were unchanged
|
77
|
-
attribute :identical, Integer, :
|
79
|
+
attribute :identical, Integer, on_save: proc { |n| n.to_s }
|
78
80
|
def identical
|
79
81
|
subset_hash[:identical].count
|
80
82
|
end
|
81
83
|
|
82
84
|
# @attribute
|
83
85
|
# @return [Integer] How many duplicate copies of files were added
|
84
|
-
attribute :copyadded, Integer, :
|
86
|
+
attribute :copyadded, Integer, on_save: proc { |n| n.to_s }
|
85
87
|
def copyadded
|
86
88
|
subset_hash[:copyadded].count
|
87
89
|
end
|
88
90
|
|
89
91
|
# @attribute
|
90
92
|
# @return [Integer] How many duplicate copies of files were deleted
|
91
|
-
attribute :copydeleted, Integer, :
|
93
|
+
attribute :copydeleted, Integer, on_save: proc { |n| n.to_s }
|
92
94
|
def copydeleted
|
93
95
|
subset_hash[:copydeleted].count
|
94
96
|
end
|
95
97
|
|
96
98
|
# @attribute
|
97
99
|
# @return [Integer] How many files were renamed
|
98
|
-
attribute :renamed, Integer, :
|
100
|
+
attribute :renamed, Integer, on_save: proc { |n| n.to_s }
|
99
101
|
def renamed
|
100
102
|
subset_hash[:renamed].count
|
101
103
|
end
|
102
104
|
|
103
105
|
# @attribute
|
104
106
|
# @return [Integer] How many files were modified
|
105
|
-
attribute :modified, Integer, :
|
107
|
+
attribute :modified, Integer, on_save: proc { |n| n.to_s }
|
106
108
|
def modified
|
107
109
|
subset_hash[:modified].count
|
108
110
|
end
|
109
111
|
|
110
112
|
# @attribute
|
111
113
|
# @return [Integer] How many files were added
|
112
|
-
attribute :added, Integer, :
|
114
|
+
attribute :added, Integer, on_save: proc { |n| n.to_s }
|
113
115
|
def added
|
114
116
|
subset_hash[:added].count
|
115
117
|
end
|
116
118
|
|
117
119
|
# @attribute
|
118
120
|
# @return [Integer] How many files were deleted
|
119
|
-
attribute :deleted, Integer, :
|
121
|
+
attribute :deleted, Integer, on_save: proc { |n| n.to_s }
|
120
122
|
def deleted
|
121
123
|
subset_hash[:deleted].count
|
122
124
|
end
|
@@ -124,7 +126,7 @@ module Moab
|
|
124
126
|
# @attribute
|
125
127
|
# @return [Array<FileGroupDifferenceSubset>] A set of Arrays (one for each change type),
|
126
128
|
# each of which contains an collection of file-level differences having that change type.
|
127
|
-
has_many :subsets, FileGroupDifferenceSubset, :
|
129
|
+
has_many :subsets, FileGroupDifferenceSubset, tag: 'subset'
|
128
130
|
|
129
131
|
def subsets
|
130
132
|
subset_hash.values
|
@@ -132,6 +134,7 @@ module Moab
|
|
132
134
|
|
133
135
|
def subsets=(array)
|
134
136
|
return unless array
|
137
|
+
|
135
138
|
array.each { |subset| subset_hash[subset.change.to_sym] = subset }
|
136
139
|
end
|
137
140
|
|
@@ -144,14 +147,14 @@ module Moab
|
|
144
147
|
# @return [FileGroupDifference] Clone just this element for inclusion in a versionMetadata structure
|
145
148
|
def summary
|
146
149
|
FileGroupDifference.new(
|
147
|
-
:
|
148
|
-
:
|
149
|
-
:
|
150
|
-
:
|
151
|
-
:
|
152
|
-
:
|
153
|
-
:
|
154
|
-
:
|
150
|
+
group_id: group_id,
|
151
|
+
identical: identical,
|
152
|
+
copyadded: copyadded,
|
153
|
+
copydeleted: copydeleted,
|
154
|
+
renamed: renamed,
|
155
|
+
modified: modified,
|
156
|
+
added: added,
|
157
|
+
deleted: deleted
|
155
158
|
)
|
156
159
|
end
|
157
160
|
|
@@ -228,7 +231,7 @@ module Moab
|
|
228
231
|
other_paths = other_signature_hash[signature].paths
|
229
232
|
matching_paths = basis_paths & other_paths
|
230
233
|
matching_paths.each do |path|
|
231
|
-
fid = FileInstanceDifference.new(:
|
234
|
+
fid = FileInstanceDifference.new(change: 'identical')
|
232
235
|
fid.basis_path = path
|
233
236
|
fid.other_path = "same"
|
234
237
|
fid.signatures << signature
|
@@ -281,7 +284,7 @@ module Moab
|
|
281
284
|
# Container for reporting the set of file-level differences of type 'modified'
|
282
285
|
def tabulate_modified_files(basis_path_hash, other_path_hash)
|
283
286
|
matching_keys(basis_path_hash, other_path_hash).each do |path|
|
284
|
-
fid = FileInstanceDifference.new(:
|
287
|
+
fid = FileInstanceDifference.new(change: 'modified')
|
285
288
|
fid.basis_path = path
|
286
289
|
fid.other_path = "same"
|
287
290
|
fid.signatures << basis_path_hash[path]
|
@@ -300,7 +303,7 @@ module Moab
|
|
300
303
|
# Container for reporting the set of file-level differences of type 'added'
|
301
304
|
def tabulate_added_files(basis_path_hash, other_path_hash)
|
302
305
|
other_only_keys(basis_path_hash, other_path_hash).each do |path|
|
303
|
-
fid = FileInstanceDifference.new(:
|
306
|
+
fid = FileInstanceDifference.new(change: 'added')
|
304
307
|
fid.basis_path = ""
|
305
308
|
fid.other_path = path
|
306
309
|
fid.signatures << other_path_hash[path]
|
@@ -318,7 +321,7 @@ module Moab
|
|
318
321
|
# Container for reporting the set of file-level differences of type 'deleted'
|
319
322
|
def tabulate_deleted_files(basis_path_hash, other_path_hash)
|
320
323
|
basis_only_keys(basis_path_hash, other_path_hash).each do |path|
|
321
|
-
fid = FileInstanceDifference.new(:
|
324
|
+
fid = FileInstanceDifference.new(change: 'deleted')
|
322
325
|
fid.basis_path = path
|
323
326
|
fid.other_path = ""
|
324
327
|
fid.signatures << basis_path_hash[path]
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# A container for reporting a set of file-level differences of the type specified by the change attribute
|
3
5
|
#
|
@@ -24,11 +26,11 @@ module Moab
|
|
24
26
|
|
25
27
|
# @attribute
|
26
28
|
# @return [String] The type of change (identical|renamed|modified|deleted|added)
|
27
|
-
attribute :change, String, :
|
29
|
+
attribute :change, String, key: true
|
28
30
|
|
29
31
|
# @attribute
|
30
32
|
# @return [Integer] How many files were changed
|
31
|
-
attribute :count, Integer, :
|
33
|
+
attribute :count, Integer, on_save: proc { |n| n.to_s }
|
32
34
|
|
33
35
|
def count
|
34
36
|
files.size
|
@@ -36,6 +38,6 @@ module Moab
|
|
36
38
|
|
37
39
|
# @attribute
|
38
40
|
# @return [Array<FileInstanceDifference>] The set of file instances having this type of change
|
39
|
-
has_many :files, FileInstanceDifference, :
|
41
|
+
has_many :files, FileInstanceDifference, tag: 'file'
|
40
42
|
end
|
41
43
|
end
|
data/lib/moab/file_instance.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# The file path and last modification date properties of a file
|
3
5
|
#
|
@@ -23,7 +25,7 @@ module Moab
|
|
23
25
|
|
24
26
|
# @attribute
|
25
27
|
# @return [String] The id is the filename path, relative to the file group's base directory
|
26
|
-
attribute :path, String, :
|
28
|
+
attribute :path, String, key: true
|
27
29
|
|
28
30
|
# @attribute
|
29
31
|
# @return [String] gsub(/\n/,' ')
|
@@ -52,6 +54,7 @@ module Moab
|
|
52
54
|
# @return [Boolean] Returns true if self and other have the same path.
|
53
55
|
def eql?(other)
|
54
56
|
return false unless other.respond_to?(:path) # Cannot equal an incomparable type!
|
57
|
+
|
55
58
|
path == other.path
|
56
59
|
end
|
57
60
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# A container for recording difference information at the file level
|
3
5
|
# * If there was no change, the change type is set to <i>identical</i>
|
@@ -36,14 +38,14 @@ module Moab
|
|
36
38
|
|
37
39
|
# @attribute
|
38
40
|
# @return [String] The file's path in the basis inventory (usually for an old version)
|
39
|
-
attribute :basis_path, String, :
|
41
|
+
attribute :basis_path, String, tag: 'basisPath', on_save: proc { |s| s.to_s }
|
40
42
|
|
41
43
|
# @attribute
|
42
44
|
# @return [String] The file's path in the other inventory (usually for an new version) compared against the basis
|
43
|
-
attribute :other_path, String, :
|
45
|
+
attribute :other_path, String, tag: 'otherPath', on_save: proc { |s| s.to_s }
|
44
46
|
|
45
47
|
# @attribute
|
46
48
|
# @return [Array<FileSignature>] The fixity data of the file manifestation(s) (plural if change was a content modification)
|
47
|
-
has_many :signatures, FileSignature, :
|
49
|
+
has_many :signatures, FileSignature, tag: 'fileSignature'
|
48
50
|
end
|
49
51
|
end
|
data/lib/moab/file_inventory.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# A structured container for recording information about a collection of related files.
|
3
5
|
#
|
@@ -44,20 +46,20 @@ module Moab
|
|
44
46
|
|
45
47
|
# @attribute
|
46
48
|
# @return [String] The digital object identifier (druid)
|
47
|
-
attribute :digital_object_id, String, :
|
49
|
+
attribute :digital_object_id, String, tag: 'objectId'
|
48
50
|
|
49
51
|
# @attribute
|
50
52
|
# @return [Integer] The ordinal version number
|
51
|
-
attribute :version_id, Integer, :
|
53
|
+
attribute :version_id, Integer, tag: 'versionId', key: true, on_save: proc { |n| n.to_s }
|
52
54
|
|
53
55
|
# @return [String] The unique identifier concatenating digital object id with version id
|
54
56
|
def composite_key
|
55
|
-
digital_object_id
|
57
|
+
"#{digital_object_id}-#{StorageObject.version_dirname(version_id)}"
|
56
58
|
end
|
57
59
|
|
58
60
|
# @attribute
|
59
61
|
# @return [String] The datetime at which the inventory was created
|
60
|
-
attribute :inventory_datetime, String, :
|
62
|
+
attribute :inventory_datetime, String, tag: 'inventoryDatetime'
|
61
63
|
|
62
64
|
def inventory_datetime=(datetime)
|
63
65
|
@inventory_datetime = Moab::UtcTime.input(datetime)
|
@@ -69,7 +71,7 @@ module Moab
|
|
69
71
|
|
70
72
|
# @attribute
|
71
73
|
# @return [Integer] The total number of data files in the inventory (dynamically calculated)
|
72
|
-
attribute :file_count, Integer, :
|
74
|
+
attribute :file_count, Integer, tag: 'fileCount', on_save: proc { |t| t.to_s }
|
73
75
|
|
74
76
|
def file_count
|
75
77
|
groups.inject(0) { |sum, group| sum + group.file_count }
|
@@ -77,7 +79,7 @@ module Moab
|
|
77
79
|
|
78
80
|
# @attribute
|
79
81
|
# @return [Integer] The total size (in bytes) in all files of all files in the inventory (dynamically calculated)
|
80
|
-
attribute :byte_count, Integer, :
|
82
|
+
attribute :byte_count, Integer, tag: 'byteCount', on_save: proc { |t| t.to_s }
|
81
83
|
|
82
84
|
def byte_count
|
83
85
|
groups.inject(0) { |sum, group| sum + group.byte_count }
|
@@ -85,7 +87,7 @@ module Moab
|
|
85
87
|
|
86
88
|
# @attribute
|
87
89
|
# @return [Integer] The total disk usage (in 1 kB blocks) of all data files (estimating du -k result) (dynamically calculated)
|
88
|
-
attribute :block_count, Integer, :
|
90
|
+
attribute :block_count, Integer, tag: 'blockCount', on_save: proc { |t| t.to_s }
|
89
91
|
|
90
92
|
def block_count
|
91
93
|
groups.inject(0) { |sum, group| sum + group.block_count }
|
@@ -93,7 +95,7 @@ module Moab
|
|
93
95
|
|
94
96
|
# @attribute
|
95
97
|
# @return [Array<FileGroup>] The set of data groups comprising the version
|
96
|
-
has_many :groups, FileGroup, :
|
98
|
+
has_many :groups, FileGroup, tag: 'fileGroup'
|
97
99
|
|
98
100
|
# @return [Array<FileGroup] The set of data groups that contain files
|
99
101
|
def non_empty_groups
|
@@ -132,9 +134,11 @@ module Moab
|
|
132
134
|
file_group = group(group_id)
|
133
135
|
errmsg = "group #{group_id} not found for #{digital_object_id} - #{version_id}"
|
134
136
|
raise FileNotFoundException, errmsg if file_group.nil?
|
137
|
+
|
135
138
|
file_signature = file_group.path_hash[file_id]
|
136
139
|
errmsg = "#{group_id} file #{file_id} not found for #{digital_object_id} - #{version_id}"
|
137
140
|
raise FileNotFoundException, errmsg if file_signature.nil?
|
141
|
+
|
138
142
|
file_signature
|
139
143
|
end
|
140
144
|
|
@@ -190,7 +194,7 @@ module Moab
|
|
190
194
|
signatures_from_bag = signatures_from_bagit_manifests(bag_pathname)
|
191
195
|
bag_data_subdirs = bag_pathname.join('data').children
|
192
196
|
bag_data_subdirs.each do |subdir|
|
193
|
-
groups << FileGroup.new(:
|
197
|
+
groups << FileGroup.new(group_id: subdir.basename.to_s).group_from_bagit_subdir(subdir, signatures_from_bag)
|
194
198
|
end
|
195
199
|
self
|
196
200
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# Compares two {FileInventory} instances based primarily on file signatures and secondarily on file pathnames.
|
3
5
|
# Although the usual use will be to compare the content of 2 different temporal versions of the same object,
|
@@ -28,11 +30,11 @@ module Moab
|
|
28
30
|
|
29
31
|
# @attribute
|
30
32
|
# @return [String] The digital object ID (druid)
|
31
|
-
attribute :digital_object_id, String, :
|
33
|
+
attribute :digital_object_id, String, tag: 'objectId'
|
32
34
|
|
33
35
|
# @attribute
|
34
36
|
# @return [Integer] the number of differences found between the two inventories that were compared (dynamically calculated)
|
35
|
-
attribute :difference_count, Integer, :
|
37
|
+
attribute :difference_count, Integer, tag: 'differenceCount', on_save: proc { |i| i.to_s }
|
36
38
|
|
37
39
|
def difference_count
|
38
40
|
@group_differences.inject(0) { |sum, group| sum + group.difference_count }
|
@@ -48,7 +50,7 @@ module Moab
|
|
48
50
|
|
49
51
|
# @attribute
|
50
52
|
# @return [String] The datetime at which the report was run
|
51
|
-
attribute :report_datetime, String, :
|
53
|
+
attribute :report_datetime, String, tag: 'reportDatetime'
|
52
54
|
|
53
55
|
def report_datetime=(datetime)
|
54
56
|
@report_datetime = Moab::UtcTime.input(datetime)
|
@@ -60,7 +62,7 @@ module Moab
|
|
60
62
|
|
61
63
|
# @attribute
|
62
64
|
# @return [Array<FileGroupDifference>] The set of data groups comprising the version
|
63
|
-
has_many :group_differences, FileGroupDifference, :
|
65
|
+
has_many :group_differences, FileGroupDifference, tag: 'fileGroupDifference'
|
64
66
|
|
65
67
|
# @return [Array<String>] The data fields to include in summary reports
|
66
68
|
def summary_fields
|
@@ -87,8 +89,8 @@ module Moab
|
|
87
89
|
group_ids = basis_inventory.group_ids | other_inventory.group_ids
|
88
90
|
group_ids.each do |group_id|
|
89
91
|
# get a pair of groups to compare, creating a empty group if not present in the inventory
|
90
|
-
basis_group = basis_inventory.group(group_id) || FileGroup.new(:
|
91
|
-
other_group = other_inventory.group(group_id) || FileGroup.new(:
|
92
|
+
basis_group = basis_inventory.group(group_id) || FileGroup.new(group_id: group_id)
|
93
|
+
other_group = other_inventory.group(group_id) || FileGroup.new(group_id: group_id)
|
92
94
|
@group_differences << FileGroupDifference.new.compare_file_groups(basis_group, other_group)
|
93
95
|
end
|
94
96
|
self
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# A container for a file signature and all the physical file instances that have that signature
|
3
5
|
# This element has one child {FileSignature} element, and one or more {FileInstance} elements
|
@@ -28,7 +30,7 @@ module Moab
|
|
28
30
|
|
29
31
|
# @attribute
|
30
32
|
# @return [FileSignature] The fixity data of the file instance
|
31
|
-
element :signature, FileSignature, :
|
33
|
+
element :signature, FileSignature, tag: 'fileSignature'
|
32
34
|
|
33
35
|
def signature
|
34
36
|
@signature.is_a?(Array) ? @signature[0] : @signature
|
@@ -40,7 +42,7 @@ module Moab
|
|
40
42
|
|
41
43
|
# @attribute
|
42
44
|
# @return [Array<FileInstance>] The location(s) of the file manifestation's file instances
|
43
|
-
has_many :instances, FileInstance, :
|
45
|
+
has_many :instances, FileInstance, tag: 'fileInstance'
|
44
46
|
|
45
47
|
# @api internal
|
46
48
|
# @return [Array<String>] Create an array from all the file paths of the child {FileInstance} objects
|
@@ -75,6 +77,7 @@ module Moab
|
|
75
77
|
# @return [Boolean] True if {FileManifestation} objects have same content
|
76
78
|
def ==(other)
|
77
79
|
return false unless other.respond_to?(:signature) && other.respond_to?(:instances) # Cannot equal an incomparable type!
|
80
|
+
|
78
81
|
(signature == other.signature) && (instances == other.instances)
|
79
82
|
end
|
80
83
|
end
|