moab-versioning 4.2.1 → 4.4.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 +5 -5
- data/lib/moab.rb +3 -2
- data/lib/moab/bagger.rb +25 -20
- data/lib/moab/config.rb +39 -8
- data/lib/moab/deposit_bag_validator.rb +22 -17
- data/lib/moab/exceptions.rb +10 -8
- data/lib/moab/file_group.rb +23 -22
- data/lib/moab/file_group_difference.rb +35 -35
- data/lib/moab/file_group_difference_subset.rb +5 -5
- data/lib/moab/file_instance.rb +4 -3
- data/lib/moab/file_instance_difference.rb +5 -5
- data/lib/moab/file_inventory.rb +25 -31
- data/lib/moab/file_inventory_difference.rb +11 -11
- data/lib/moab/file_manifestation.rb +8 -7
- data/lib/moab/file_signature.rb +35 -41
- data/lib/moab/signature_catalog.rb +19 -21
- data/lib/moab/signature_catalog_entry.rb +5 -5
- data/lib/moab/stanford.rb +2 -0
- data/lib/moab/storage_object.rb +23 -24
- data/lib/moab/storage_object_validator.rb +44 -16
- data/lib/moab/storage_object_version.rb +45 -40
- data/lib/moab/storage_repository.rb +59 -24
- data/lib/moab/storage_services.rb +17 -10
- data/lib/moab/utc_time.rb +3 -3
- data/lib/moab/verification_result.rb +3 -4
- data/lib/moab/version_metadata.rb +4 -4
- data/lib/moab/version_metadata_entry.rb +6 -6
- data/lib/moab/version_metadata_event.rb +1 -1
- data/lib/serializer.rb +2 -0
- data/lib/serializer/manifest.rb +9 -7
- data/lib/serializer/serializable.rb +41 -35
- data/lib/stanford/active_fedora_object.rb +1 -1
- data/lib/stanford/content_inventory.rb +40 -34
- data/lib/stanford/dor_metadata.rb +4 -3
- data/lib/stanford/moab_storage_directory.rb +4 -2
- data/lib/stanford/storage_object_validator.rb +1 -1
- data/lib/stanford/storage_repository.rb +9 -6
- data/lib/stanford/storage_services.rb +6 -6
- metadata +23 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4b576c73187205ae4548c6460bac2b68cedab5dc7c3b94a66a5d8ec13729c6ae
|
4
|
+
data.tar.gz: e714a158d2e1388dec94482c1fa858a2ee29a6eca6e0f9004658446801088476
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 251925f9e4c45f20f6ae4270fc73adfe9f4645689bda08ebd42c2b707909177ab575e0427c83e321c2ebc039c735f9bc141b29037f28cb65249c25bd9e76d520
|
7
|
+
data.tar.gz: '053391d53a3a3a46bbfedce8e7a04ea0f28a7f5c43689c2bde3c1901f9303eae7356d507904ec1892d9da61f2d4c9c6e58ed3fec894985e19b9ab85dd5fa65fd'
|
data/lib/moab.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Moab is a module that provides a distintive namespace for the collection of classes it contains.
|
2
4
|
#
|
3
5
|
# ====Data Model
|
@@ -29,11 +31,10 @@
|
|
29
31
|
# @note Copyright (c) 2012 by The Board of Trustees of the Leland Stanford Junior University.
|
30
32
|
# All rights reserved. See {file:LICENSE.rdoc} for details.
|
31
33
|
module Moab
|
32
|
-
DEFAULT_CHECKSUM_TYPES = [
|
34
|
+
DEFAULT_CHECKSUM_TYPES = %i[md5 sha1 sha256].freeze
|
33
35
|
end
|
34
36
|
|
35
37
|
require 'serializer'
|
36
|
-
require 'confstruct/configuration'
|
37
38
|
require 'moab/config'
|
38
39
|
require 'moab/utc_time'
|
39
40
|
require 'moab/file_signature'
|
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
|
@@ -25,7 +27,7 @@ module Moab
|
|
25
27
|
@version_inventory = version_inventory
|
26
28
|
@signature_catalog = signature_catalog
|
27
29
|
@bag_pathname = Pathname.new(bag_pathname)
|
28
|
-
create_bagit_txt
|
30
|
+
create_bagit_txt
|
29
31
|
end
|
30
32
|
|
31
33
|
# @return [FileInventory] The complete inventory of the files comprising a digital object version
|
@@ -54,7 +56,7 @@ module Moab
|
|
54
56
|
|
55
57
|
# @api internal
|
56
58
|
# @return [void] Generate the bagit.txt tag file
|
57
|
-
def create_bagit_txt
|
59
|
+
def create_bagit_txt
|
58
60
|
bag_pathname.mkpath
|
59
61
|
bag_pathname.join("bagit.txt").open('w') do |f|
|
60
62
|
f.puts "Tag-File-Character-Encoding: UTF-8"
|
@@ -63,13 +65,13 @@ module Moab
|
|
63
65
|
end
|
64
66
|
|
65
67
|
# @return [NilClass] Delete the bagit files
|
66
|
-
def delete_bag
|
68
|
+
def delete_bag
|
67
69
|
# make sure this looks like a bag before deleting
|
68
70
|
if bag_pathname.join('bagit.txt').exist?
|
69
71
|
if bag_pathname.join('data').exist?
|
70
72
|
bag_pathname.rmtree
|
71
73
|
else
|
72
|
-
bag_pathname.children.each
|
74
|
+
bag_pathname.children.each(&:delete)
|
73
75
|
bag_pathname.rmdir
|
74
76
|
end
|
75
77
|
end
|
@@ -77,7 +79,7 @@ module Moab
|
|
77
79
|
end
|
78
80
|
|
79
81
|
# @param tar_pathname [Pathname] The location of the tar file (default is based on bag location)
|
80
|
-
def delete_tarfile
|
82
|
+
def delete_tarfile
|
81
83
|
bag_name = bag_pathname.basename
|
82
84
|
bag_parent = bag_pathname.parent
|
83
85
|
tar_pathname = bag_parent.join("#{bag_name}.tar")
|
@@ -140,7 +142,8 @@ module Moab
|
|
140
142
|
# Return true if successful or nil if the group was not found in the inventory
|
141
143
|
def deposit_group(group_id, source_dir)
|
142
144
|
group = bag_inventory.group(group_id)
|
143
|
-
return nil? if group.nil?
|
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)
|
@@ -157,7 +160,8 @@ module Moab
|
|
157
160
|
# Return true if successful or nil if the group was not found in the inventory
|
158
161
|
def reconstuct_group(group_id, storage_object_dir)
|
159
162
|
group = bag_inventory.group(group_id)
|
160
|
-
return nil? if group.nil?
|
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
|
@@ -183,8 +187,8 @@ module Moab
|
|
183
187
|
# @api internal
|
184
188
|
# @return [void] Using the checksum information from the inventory, create BagIt manifest files for the payload
|
185
189
|
def create_payload_manifests
|
186
|
-
manifest_pathname =
|
187
|
-
manifest_file =
|
190
|
+
manifest_pathname = {}
|
191
|
+
manifest_file = {}
|
188
192
|
DEFAULT_CHECKSUM_TYPES.each do |type|
|
189
193
|
manifest_pathname[type] = bag_pathname.join("manifest-#{type}.txt")
|
190
194
|
manifest_file[type] = manifest_pathname[type].open('w')
|
@@ -205,7 +209,7 @@ module Moab
|
|
205
209
|
if manifest_file[type]
|
206
210
|
manifest_file[type].close
|
207
211
|
manifest_pathname[type].delete if
|
208
|
-
manifest_pathname[type].exist?
|
212
|
+
manifest_pathname[type].exist? && manifest_pathname[type].size == 0
|
209
213
|
end
|
210
214
|
end
|
211
215
|
end
|
@@ -222,9 +226,9 @@ module Moab
|
|
222
226
|
|
223
227
|
# @api internal
|
224
228
|
# @return [void] create BagIt tag manifest files containing checksums for all files in the bag's root directory
|
225
|
-
def create_tagfile_manifests
|
226
|
-
manifest_pathname =
|
227
|
-
manifest_file =
|
229
|
+
def create_tagfile_manifests
|
230
|
+
manifest_pathname = {}
|
231
|
+
manifest_file = {}
|
228
232
|
DEFAULT_CHECKSUM_TYPES.each do |type|
|
229
233
|
manifest_pathname[type] = bag_pathname.join("tagmanifest-#{type}.txt")
|
230
234
|
manifest_file[type] = manifest_pathname[type].open('w')
|
@@ -243,7 +247,7 @@ module Moab
|
|
243
247
|
if manifest_file[type]
|
244
248
|
manifest_file[type].close
|
245
249
|
manifest_pathname[type].delete if
|
246
|
-
manifest_pathname[type].exist?
|
250
|
+
manifest_pathname[type].exist? && manifest_pathname[type].size == 0
|
247
251
|
end
|
248
252
|
end
|
249
253
|
end
|
@@ -259,8 +263,9 @@ module Moab
|
|
259
263
|
rescue
|
260
264
|
shell_execute(tar_cmd.sub('--force-local', ''))
|
261
265
|
end
|
262
|
-
raise "Unable to create tarfile #{tar_pathname}" unless tar_pathname.exist?
|
263
|
-
|
266
|
+
raise(MoabRuntimeError, "Unable to create tarfile #{tar_pathname}") unless tar_pathname.exist?
|
267
|
+
|
268
|
+
true
|
264
269
|
end
|
265
270
|
|
266
271
|
# Executes a system command in a subprocess
|
@@ -273,12 +278,12 @@ 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
|
277
|
-
raise(
|
281
|
+
msg << " STDOUT = #{stdout}" if stdout&.length&.positive?
|
282
|
+
raise(MoabStandardError, msg)
|
278
283
|
end
|
279
284
|
rescue SystemCallError => e
|
280
285
|
msg = "Shell command failed: [#{command}] caused by #{e.inspect}"
|
281
|
-
raise(
|
286
|
+
raise(MoabStandardError, msg)
|
282
287
|
end
|
283
288
|
end
|
284
289
|
end
|
data/lib/moab/config.rb
CHANGED
@@ -1,12 +1,43 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Moab
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
11
39
|
end
|
40
|
+
|
41
|
+
# @return [Moab::Configuration] the configuration data
|
42
|
+
Config = Configuration.new
|
12
43
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# Given a deposit bag, ensures the contents valid for becoming a StorageObjectVersion
|
3
5
|
# this is a Shameless Green implementation, combining code from:
|
@@ -30,23 +32,23 @@ module Moab
|
|
30
32
|
VERSION_MISSING_FROM_FILE => "Version xml file %{version_file} missing data at %{xpath} containing version id"
|
31
33
|
}.freeze
|
32
34
|
|
33
|
-
REQUIRED_MANIFEST_CHECKSUM_TYPE = 'sha256'
|
34
|
-
RECOGNIZED_CHECKSUM_ALGORITHMS = [
|
35
|
+
REQUIRED_MANIFEST_CHECKSUM_TYPE = 'sha256'
|
36
|
+
RECOGNIZED_CHECKSUM_ALGORITHMS = %i[md5 sha1 sha256 sha384 sha512].freeze
|
35
37
|
|
36
|
-
TAGMANIFEST = 'tagmanifest'
|
37
|
-
MANIFEST = 'manifest'
|
38
|
-
DATA_DIR_BASENAME = 'data'
|
39
|
-
BAG_INFO_TXT_BASENAME = 'bag-info.txt'
|
40
|
-
VERSION_ADDITIONS_BASENAME = 'versionAdditions.xml'
|
41
|
-
VERSION_INVENTORY_BASENAME = 'versionInventory.xml'
|
42
|
-
VERSION_METADATA_PATH = "#{DATA_DIR_BASENAME}/metadata/versionMetadata.xml"
|
38
|
+
TAGMANIFEST = 'tagmanifest'
|
39
|
+
MANIFEST = 'manifest'
|
40
|
+
DATA_DIR_BASENAME = 'data'
|
41
|
+
BAG_INFO_TXT_BASENAME = 'bag-info.txt'
|
42
|
+
VERSION_ADDITIONS_BASENAME = 'versionAdditions.xml'
|
43
|
+
VERSION_INVENTORY_BASENAME = 'versionInventory.xml'
|
44
|
+
VERSION_METADATA_PATH = "#{DATA_DIR_BASENAME}/metadata/versionMetadata.xml"
|
43
45
|
|
44
46
|
REQUIRED_BAG_FILES = [
|
45
47
|
DATA_DIR_BASENAME,
|
46
|
-
'bagit.txt'
|
48
|
+
'bagit.txt',
|
47
49
|
BAG_INFO_TXT_BASENAME,
|
48
|
-
"#{MANIFEST}-#{REQUIRED_MANIFEST_CHECKSUM_TYPE}.txt"
|
49
|
-
"#{TAGMANIFEST}-#{REQUIRED_MANIFEST_CHECKSUM_TYPE}.txt"
|
50
|
+
"#{MANIFEST}-#{REQUIRED_MANIFEST_CHECKSUM_TYPE}.txt",
|
51
|
+
"#{TAGMANIFEST}-#{REQUIRED_MANIFEST_CHECKSUM_TYPE}.txt",
|
50
52
|
VERSION_ADDITIONS_BASENAME,
|
51
53
|
VERSION_INVENTORY_BASENAME,
|
52
54
|
VERSION_METADATA_PATH
|
@@ -64,6 +66,7 @@ module Moab
|
|
64
66
|
def validation_errors
|
65
67
|
return [single_error_hash(BAG_DIR_NOT_FOUND, bag_dir: deposit_bag_pathname)] unless deposit_bag_pathname.exist?
|
66
68
|
return result_array unless required_bag_files_exist?
|
69
|
+
|
67
70
|
verify_version
|
68
71
|
verify_tagmanifests
|
69
72
|
verify_payload_size
|
@@ -112,6 +115,7 @@ module Moab
|
|
112
115
|
doc = Nokogiri::XML(File.open(pathname.to_s), &:strict)
|
113
116
|
version_id = doc.xpath(xpath).last.text unless doc.xpath(xpath).empty?
|
114
117
|
return version_id.to_i if version_id
|
118
|
+
|
115
119
|
err_data = {
|
116
120
|
version_file: pathname,
|
117
121
|
xpath: xpath
|
@@ -129,6 +133,7 @@ module Moab
|
|
129
133
|
|
130
134
|
def verify_version_from_xml_file(file_pathname, found)
|
131
135
|
return if found == expected_new_version
|
136
|
+
|
132
137
|
err_data = {
|
133
138
|
file_pathname: file_pathname,
|
134
139
|
new_version: expected_new_version,
|
@@ -186,7 +191,7 @@ module Moab
|
|
186
191
|
home_dir_pathnames = deposit_bag_pathname.children.reject { |file| file.basename.to_s.start_with?(TAGMANIFEST) }
|
187
192
|
hash_with_full_pathnames = generate_checksums_hash(home_dir_pathnames, types_to_generate)
|
188
193
|
# return hash keys as basenames only
|
189
|
-
hash_with_full_pathnames.
|
194
|
+
hash_with_full_pathnames.transform_keys { |k| Pathname.new(k).basename.to_s }
|
190
195
|
end
|
191
196
|
|
192
197
|
# generate hash of checksums by file name for bag data dir files
|
@@ -194,7 +199,7 @@ module Moab
|
|
194
199
|
data_pathnames = deposit_bag_pathname.join(DATA_DIR_BASENAME).find
|
195
200
|
hash_with_full_pathnames = generate_checksums_hash(data_pathnames, types_to_generate)
|
196
201
|
# return hash keys beginning with 'data/'
|
197
|
-
hash_with_full_pathnames.
|
202
|
+
hash_with_full_pathnames.transform_keys { |k| Pathname.new(k).relative_path_from(deposit_bag_pathname).to_s }
|
198
203
|
end
|
199
204
|
|
200
205
|
def generate_checksums_hash(pathnames, types_to_generate)
|
@@ -251,6 +256,7 @@ module Moab
|
|
251
256
|
end
|
252
257
|
end
|
253
258
|
return if diff_hash.empty?
|
259
|
+
|
254
260
|
err_data = {
|
255
261
|
manifest_type: manifest_type,
|
256
262
|
diffs: diff_hash
|
@@ -266,9 +272,7 @@ module Moab
|
|
266
272
|
checksum_types_to_compare.each do |type|
|
267
273
|
left_checksum = left_checksums[type]
|
268
274
|
right_checksum = right_checksums[type]
|
269
|
-
if left_checksum != right_checksum
|
270
|
-
diff_hash[type] = { left_label => left_checksum, right_label => right_checksum }
|
271
|
-
end
|
275
|
+
diff_hash[type] = { left_label => left_checksum, right_label => right_checksum } if left_checksum != right_checksum
|
272
276
|
end
|
273
277
|
diff_hash.empty? ? nil : diff_hash
|
274
278
|
end
|
@@ -277,6 +281,7 @@ module Moab
|
|
277
281
|
sizes_from_bag_info_file = bag_info_payload_size
|
278
282
|
generated_sizes = generated_payload_size
|
279
283
|
return if sizes_from_bag_info_file == generated_sizes
|
284
|
+
|
280
285
|
err_data = {
|
281
286
|
bag_info_sizes: sizes_from_bag_info_file,
|
282
287
|
generated_sizes: generated_sizes
|
data/lib/moab/exceptions.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
|
-
class
|
3
|
-
|
4
|
+
class MoabRuntimeError < RuntimeError; end
|
5
|
+
|
6
|
+
class MoabStandardError < StandardError; end
|
7
|
+
|
8
|
+
class FileNotFoundException < MoabRuntimeError; end
|
4
9
|
|
5
|
-
class
|
6
|
-
end
|
10
|
+
class InvalidMetadataException < MoabRuntimeError; end
|
7
11
|
|
8
|
-
class
|
9
|
-
end
|
12
|
+
class InvalidSuriSyntaxError < MoabRuntimeError; end
|
10
13
|
|
11
|
-
class
|
12
|
-
end
|
14
|
+
class ObjectNotFoundException < MoabRuntimeError; end
|
13
15
|
end
|
data/lib/moab/file_group.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Moab
|
4
4
|
# A container for a standard subset of a digital objects {FileManifestation} objects
|
@@ -22,22 +22,23 @@ module Moab
|
|
22
22
|
|
23
23
|
# (see Serializable#initialize)
|
24
24
|
def initialize(opts = {})
|
25
|
-
@signature_hash =
|
25
|
+
@signature_hash = {}
|
26
26
|
@data_source = ""
|
27
|
+
@signatures_from_bag = nil # prevents later warning: instance variable @signatures_from_bag not initialized
|
27
28
|
super(opts)
|
28
29
|
end
|
29
30
|
|
30
31
|
# @attribute
|
31
32
|
# @return [String] The name of the file group
|
32
|
-
attribute :group_id, String, :
|
33
|
+
attribute :group_id, String, tag: 'groupId', key: true
|
33
34
|
|
34
35
|
# @attribute
|
35
36
|
# @return [String] The directory location or other source of this groups file data
|
36
|
-
attribute :data_source, String, :
|
37
|
+
attribute :data_source, String, tag: 'dataSource'
|
37
38
|
|
38
39
|
# @attribute
|
39
40
|
# @return [Integer] The total number of data files (dynamically calculated)
|
40
|
-
attribute :file_count, Integer, :
|
41
|
+
attribute :file_count, Integer, tag: 'fileCount', on_save: proc { |i| i.to_s }
|
41
42
|
|
42
43
|
def file_count
|
43
44
|
files.inject(0) { |sum, manifestation| sum + manifestation.file_count }
|
@@ -45,7 +46,7 @@ module Moab
|
|
45
46
|
|
46
47
|
# @attribute
|
47
48
|
# @return [Integer] The total size (in bytes) of all data files (dynamically calculated)
|
48
|
-
attribute :byte_count, Integer, :
|
49
|
+
attribute :byte_count, Integer, tag: 'byteCount', on_save: proc { |i| i.to_s }
|
49
50
|
|
50
51
|
def byte_count
|
51
52
|
files.inject(0) { |sum, manifestation| sum + manifestation.byte_count }
|
@@ -53,7 +54,7 @@ module Moab
|
|
53
54
|
|
54
55
|
# @attribute
|
55
56
|
# @return [Integer] The total disk usage (in 1 kB blocks) of all data files (estimating du -k result) (dynamically calculated)
|
56
|
-
attribute :block_count, Integer, :
|
57
|
+
attribute :block_count, Integer, tag: 'blockCount', on_save: proc { |i| i.to_s }
|
57
58
|
|
58
59
|
def block_count
|
59
60
|
files.inject(0) { |sum, manifestation| sum + manifestation.block_count }
|
@@ -61,12 +62,12 @@ module Moab
|
|
61
62
|
|
62
63
|
# @return [Array<String>] The data fields to include in summary reports
|
63
64
|
def summary_fields
|
64
|
-
%w
|
65
|
+
%w[group_id file_count byte_count block_count]
|
65
66
|
end
|
66
67
|
|
67
68
|
# @attribute
|
68
69
|
# @return [Array<FileManifestation>] The set of files comprising the group
|
69
|
-
has_many :files, FileManifestation, :
|
70
|
+
has_many :files, FileManifestation, tag: 'file'
|
70
71
|
|
71
72
|
def files
|
72
73
|
signature_hash.values
|
@@ -80,7 +81,7 @@ module Moab
|
|
80
81
|
# @return [Hash<String,FileSignature>] An index of file paths,
|
81
82
|
# used to test for existence of a filename in this file group
|
82
83
|
def path_hash
|
83
|
-
path_hash =
|
84
|
+
path_hash = {}
|
84
85
|
signature_hash.each do |signature, manifestation|
|
85
86
|
manifestation.instances.each do |instance|
|
86
87
|
path_hash[instance.path] = signature
|
@@ -91,14 +92,14 @@ module Moab
|
|
91
92
|
|
92
93
|
# @return [Array<String>] The list of file paths in this group
|
93
94
|
def path_list
|
94
|
-
files.collect { |file| file.instances.collect
|
95
|
+
files.collect { |file| file.instances.collect(&:path) }.flatten
|
95
96
|
end
|
96
97
|
|
97
98
|
# @api internal
|
98
99
|
# @param signature_subset [Array<FileSignature>] The signatures used to select the entries to return
|
99
100
|
# @return [Hash<String,FileSignature>] A pathname,signature hash containing a subset of the filenames in this file group
|
100
101
|
def path_hash_subset(signature_subset)
|
101
|
-
path_hash =
|
102
|
+
path_hash = {}
|
102
103
|
signature_subset.each do |signature|
|
103
104
|
manifestation = signature_hash[signature]
|
104
105
|
manifestation.instances.each do |instance|
|
@@ -132,7 +133,7 @@ module Moab
|
|
132
133
|
# @return [void] Add a single {FileSignature},{FileInstance} key/value pair to this group.
|
133
134
|
# Data is actually stored in the {#signature_hash}
|
134
135
|
def add_file_instance(signature, instance)
|
135
|
-
if signature_hash.
|
136
|
+
if signature_hash.key?(signature)
|
136
137
|
manifestation = signature_hash[signature]
|
137
138
|
else
|
138
139
|
manifestation = FileManifestation.new
|
@@ -146,7 +147,7 @@ module Moab
|
|
146
147
|
# @return [void] Remove a file from the inventory
|
147
148
|
# for example, the manifest inventory does not contain a file entry for itself
|
148
149
|
def remove_file_having_path(path)
|
149
|
-
signature =
|
150
|
+
signature = path_hash[path]
|
150
151
|
signature_hash.delete(signature)
|
151
152
|
end
|
152
153
|
|
@@ -161,10 +162,12 @@ module Moab
|
|
161
162
|
# @param pathname [Pathname] The file path to be tested
|
162
163
|
# @return [Boolean] Test whether the given path is contained within the {#base_directory}
|
163
164
|
def is_descendent_of_base?(pathname)
|
164
|
-
raise("base_directory has not been set") if @base_directory.nil?
|
165
|
+
raise(MoabRuntimeError, "base_directory has not been set") if @base_directory.nil?
|
166
|
+
|
165
167
|
is_descendent = false
|
166
168
|
pathname.expand_path.ascend { |ancestor| is_descendent ||= (ancestor == @base_directory) }
|
167
|
-
raise("#{pathname} is not a descendent of #{@base_directory}") unless is_descendent
|
169
|
+
raise(MoabRuntimeError, "#{pathname} is not a descendent of #{@base_directory}") unless is_descendent
|
170
|
+
|
168
171
|
is_descendent
|
169
172
|
end
|
170
173
|
|
@@ -203,9 +206,9 @@ module Moab
|
|
203
206
|
pathname = Pathname.new(path).expand_path
|
204
207
|
validated ||= is_descendent_of_base?(pathname)
|
205
208
|
pathname.children.sort.each do |child|
|
206
|
-
if child.basename.to_s ==
|
207
|
-
|
208
|
-
|
209
|
+
next if child.basename.to_s == '.DS_Store'
|
210
|
+
|
211
|
+
if child.directory?
|
209
212
|
harvest_directory(child, recursive, validated) if recursive
|
210
213
|
else
|
211
214
|
add_physical_file(child, validated)
|
@@ -224,9 +227,7 @@ module Moab
|
|
224
227
|
instance = FileInstance.new.instance_from_file(pathname, @base_directory)
|
225
228
|
if @signatures_from_bag && @signatures_from_bag[pathname]
|
226
229
|
signature = @signatures_from_bag[pathname]
|
227
|
-
unless signature.complete?
|
228
|
-
signature = signature.normalized_signature(pathname)
|
229
|
-
end
|
230
|
+
signature = signature.normalized_signature(pathname) unless signature.complete?
|
230
231
|
else
|
231
232
|
signature = FileSignature.new.signature_from_file(pathname)
|
232
233
|
end
|