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.
Files changed (39) hide show
  1. checksums.yaml +5 -5
  2. data/lib/moab.rb +3 -2
  3. data/lib/moab/bagger.rb +25 -20
  4. data/lib/moab/config.rb +39 -8
  5. data/lib/moab/deposit_bag_validator.rb +22 -17
  6. data/lib/moab/exceptions.rb +10 -8
  7. data/lib/moab/file_group.rb +23 -22
  8. data/lib/moab/file_group_difference.rb +35 -35
  9. data/lib/moab/file_group_difference_subset.rb +5 -5
  10. data/lib/moab/file_instance.rb +4 -3
  11. data/lib/moab/file_instance_difference.rb +5 -5
  12. data/lib/moab/file_inventory.rb +25 -31
  13. data/lib/moab/file_inventory_difference.rb +11 -11
  14. data/lib/moab/file_manifestation.rb +8 -7
  15. data/lib/moab/file_signature.rb +35 -41
  16. data/lib/moab/signature_catalog.rb +19 -21
  17. data/lib/moab/signature_catalog_entry.rb +5 -5
  18. data/lib/moab/stanford.rb +2 -0
  19. data/lib/moab/storage_object.rb +23 -24
  20. data/lib/moab/storage_object_validator.rb +44 -16
  21. data/lib/moab/storage_object_version.rb +45 -40
  22. data/lib/moab/storage_repository.rb +59 -24
  23. data/lib/moab/storage_services.rb +17 -10
  24. data/lib/moab/utc_time.rb +3 -3
  25. data/lib/moab/verification_result.rb +3 -4
  26. data/lib/moab/version_metadata.rb +4 -4
  27. data/lib/moab/version_metadata_entry.rb +6 -6
  28. data/lib/moab/version_metadata_event.rb +1 -1
  29. data/lib/serializer.rb +2 -0
  30. data/lib/serializer/manifest.rb +9 -7
  31. data/lib/serializer/serializable.rb +41 -35
  32. data/lib/stanford/active_fedora_object.rb +1 -1
  33. data/lib/stanford/content_inventory.rb +40 -34
  34. data/lib/stanford/dor_metadata.rb +4 -3
  35. data/lib/stanford/moab_storage_directory.rb +4 -2
  36. data/lib/stanford/storage_object_validator.rb +1 -1
  37. data/lib/stanford/storage_repository.rb +9 -6
  38. data/lib/stanford/storage_services.rb +6 -6
  39. metadata +23 -38
@@ -1,4 +1,4 @@
1
- require 'moab'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Moab
4
4
  # Performs analysis and reports the differences between two matching {FileGroup} objects.
@@ -53,18 +53,18 @@ module Moab
53
53
 
54
54
  # (see Serializable#initialize)
55
55
  def initialize(opts = {})
56
- @subset_hash = Hash.new { |hash, key| hash[key] = FileGroupDifferenceSubset.new(:change => key.to_s) }
56
+ @subset_hash = Hash.new { |hash, key| hash[key] = FileGroupDifferenceSubset.new(change: key.to_s) }
57
57
  super(opts)
58
58
  end
59
59
 
60
60
  # @attribute
61
61
  # @return [String] The name of the file group
62
- attribute :group_id, String, :tag => 'groupId', :key => true
62
+ attribute :group_id, String, tag: 'groupId', key: true
63
63
 
64
64
  # @attribute
65
65
  # @return [Integer] the total number of differences found between the two inventories that were
66
66
  # compared (dynamically calculated)
67
- attribute :difference_count, Integer, :tag => 'differenceCount', :on_save => Proc.new { |i| i.to_s }
67
+ attribute :difference_count, Integer, tag: 'differenceCount', on_save: proc { |i| i.to_s }
68
68
 
69
69
  def difference_count
70
70
  count = 0
@@ -76,49 +76,49 @@ module Moab
76
76
 
77
77
  # @attribute
78
78
  # @return [Integer] How many files were unchanged
79
- attribute :identical, Integer, :on_save => Proc.new { |n| n.to_s }
79
+ attribute :identical, Integer, on_save: proc { |n| n.to_s }
80
80
  def identical
81
81
  subset_hash[:identical].count
82
82
  end
83
83
 
84
84
  # @attribute
85
85
  # @return [Integer] How many duplicate copies of files were added
86
- attribute :copyadded, Integer, :on_save => Proc.new { |n| n.to_s }
86
+ attribute :copyadded, Integer, on_save: proc { |n| n.to_s }
87
87
  def copyadded
88
88
  subset_hash[:copyadded].count
89
89
  end
90
90
 
91
91
  # @attribute
92
92
  # @return [Integer] How many duplicate copies of files were deleted
93
- attribute :copydeleted, Integer, :on_save => Proc.new { |n| n.to_s }
93
+ attribute :copydeleted, Integer, on_save: proc { |n| n.to_s }
94
94
  def copydeleted
95
95
  subset_hash[:copydeleted].count
96
96
  end
97
97
 
98
98
  # @attribute
99
99
  # @return [Integer] How many files were renamed
100
- attribute :renamed, Integer, :on_save => Proc.new { |n| n.to_s }
100
+ attribute :renamed, Integer, on_save: proc { |n| n.to_s }
101
101
  def renamed
102
102
  subset_hash[:renamed].count
103
103
  end
104
104
 
105
105
  # @attribute
106
106
  # @return [Integer] How many files were modified
107
- attribute :modified, Integer, :on_save => Proc.new { |n| n.to_s }
107
+ attribute :modified, Integer, on_save: proc { |n| n.to_s }
108
108
  def modified
109
109
  subset_hash[:modified].count
110
110
  end
111
111
 
112
112
  # @attribute
113
113
  # @return [Integer] How many files were added
114
- attribute :added, Integer, :on_save => Proc.new { |n| n.to_s }
114
+ attribute :added, Integer, on_save: proc { |n| n.to_s }
115
115
  def added
116
116
  subset_hash[:added].count
117
117
  end
118
118
 
119
119
  # @attribute
120
120
  # @return [Integer] How many files were deleted
121
- attribute :deleted, Integer, :on_save => Proc.new { |n| n.to_s }
121
+ attribute :deleted, Integer, on_save: proc { |n| n.to_s }
122
122
  def deleted
123
123
  subset_hash[:deleted].count
124
124
  end
@@ -126,35 +126,35 @@ module Moab
126
126
  # @attribute
127
127
  # @return [Array<FileGroupDifferenceSubset>] A set of Arrays (one for each change type),
128
128
  # each of which contains an collection of file-level differences having that change type.
129
- has_many :subsets, FileGroupDifferenceSubset, :tag => 'subset'
129
+ has_many :subsets, FileGroupDifferenceSubset, tag: 'subset'
130
130
 
131
131
  def subsets
132
132
  subset_hash.values
133
133
  end
134
134
 
135
135
  def subsets=(array)
136
- if array
137
- array.each { |subset| subset_hash[subset.change.to_sym] = subset }
138
- end
136
+ return unless array
137
+
138
+ array.each { |subset| subset_hash[subset.change.to_sym] = subset }
139
139
  end
140
140
 
141
141
  # @return [Array<String>] The data fields to include in summary reports
142
142
  def summary_fields
143
- %w{group_id difference_count identical copyadded copydeleted renamed modified deleted added}
143
+ %w[group_id difference_count identical copyadded copydeleted renamed modified deleted added]
144
144
  end
145
145
 
146
146
  # @api internal
147
147
  # @return [FileGroupDifference] Clone just this element for inclusion in a versionMetadata structure
148
- def summary()
148
+ def summary
149
149
  FileGroupDifference.new(
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
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
158
158
  )
159
159
  end
160
160
 
@@ -231,7 +231,7 @@ module Moab
231
231
  other_paths = other_signature_hash[signature].paths
232
232
  matching_paths = basis_paths & other_paths
233
233
  matching_paths.each do |path|
234
- fid = FileInstanceDifference.new(:change => 'identical')
234
+ fid = FileInstanceDifference.new(change: 'identical')
235
235
  fid.basis_path = path
236
236
  fid.other_path = "same"
237
237
  fid.signatures << signature
@@ -257,7 +257,7 @@ module Moab
257
257
  other_only_paths = other_paths - basis_paths
258
258
  maxsize = [basis_only_paths.size, other_only_paths.size].max
259
259
  (0..maxsize - 1).each do |n|
260
- fid = FileInstanceDifference.new()
260
+ fid = FileInstanceDifference.new
261
261
  fid.basis_path = basis_only_paths[n]
262
262
  fid.other_path = other_only_paths[n]
263
263
  fid.signatures << signature
@@ -284,7 +284,7 @@ module Moab
284
284
  # Container for reporting the set of file-level differences of type 'modified'
285
285
  def tabulate_modified_files(basis_path_hash, other_path_hash)
286
286
  matching_keys(basis_path_hash, other_path_hash).each do |path|
287
- fid = FileInstanceDifference.new(:change => 'modified')
287
+ fid = FileInstanceDifference.new(change: 'modified')
288
288
  fid.basis_path = path
289
289
  fid.other_path = "same"
290
290
  fid.signatures << basis_path_hash[path]
@@ -303,7 +303,7 @@ module Moab
303
303
  # Container for reporting the set of file-level differences of type 'added'
304
304
  def tabulate_added_files(basis_path_hash, other_path_hash)
305
305
  other_only_keys(basis_path_hash, other_path_hash).each do |path|
306
- fid = FileInstanceDifference.new(:change => 'added')
306
+ fid = FileInstanceDifference.new(change: 'added')
307
307
  fid.basis_path = ""
308
308
  fid.other_path = path
309
309
  fid.signatures << other_path_hash[path]
@@ -321,7 +321,7 @@ module Moab
321
321
  # Container for reporting the set of file-level differences of type 'deleted'
322
322
  def tabulate_deleted_files(basis_path_hash, other_path_hash)
323
323
  basis_only_keys(basis_path_hash, other_path_hash).each do |path|
324
- fid = FileInstanceDifference.new(:change => 'deleted')
324
+ fid = FileInstanceDifference.new(change: 'deleted')
325
325
  fid.basis_path = path
326
326
  fid.other_path = ""
327
327
  fid.signatures << basis_path_hash[path]
@@ -331,20 +331,20 @@ module Moab
331
331
  end
332
332
 
333
333
  # @return [Hash<Symbol,Array>] Sets of filenames grouped by change type for use in performing file or metadata operations
334
- def file_deltas()
334
+ def file_deltas
335
335
  # The hash to be returned
336
336
  deltas = Hash.new { |hash, key| hash[key] = [] }
337
337
  # case where other_path is empty or 'same'. (create array of strings)
338
- [:identical, :modified, :deleted, :copydeleted].each do |change|
339
- deltas[change].concat(subset_hash[change].files.collect { |file| file.basis_path })
338
+ %i[identical modified deleted copydeleted].each do |change|
339
+ deltas[change].concat(subset_hash[change].files.collect(&:basis_path))
340
340
  end
341
341
  # case where basis_path and other_path are both present. (create array of arrays)
342
- [:copyadded, :renamed].each do |change|
342
+ %i[copyadded renamed].each do |change|
343
343
  deltas[change].concat(subset_hash[change].files.collect { |file| [file.basis_path, file.other_path] })
344
344
  end
345
345
  # case where basis_path is empty. (create array of strings)
346
346
  [:added].each do |change|
347
- deltas[change].concat(subset_hash[change].files.collect { |file| file.other_path })
347
+ deltas[change].concat(subset_hash[change].files.collect(&:other_path))
348
348
  end
349
349
  deltas
350
350
  end
@@ -1,4 +1,4 @@
1
- require 'moab'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Moab
4
4
  # A container for reporting a set of file-level differences of the type specified by the change attribute
@@ -20,17 +20,17 @@ module Moab
20
20
 
21
21
  # (see Serializable#initialize)
22
22
  def initialize(opts = {})
23
- @files = Array.new
23
+ @files = []
24
24
  super(opts)
25
25
  end
26
26
 
27
27
  # @attribute
28
28
  # @return [String] The type of change (identical|renamed|modified|deleted|added)
29
- attribute :change, String, :key => true
29
+ attribute :change, String, key: true
30
30
 
31
31
  # @attribute
32
32
  # @return [Integer] How many files were changed
33
- attribute :count, Integer, :on_save => Proc.new { |n| n.to_s }
33
+ attribute :count, Integer, on_save: proc { |n| n.to_s }
34
34
 
35
35
  def count
36
36
  files.size
@@ -38,6 +38,6 @@ module Moab
38
38
 
39
39
  # @attribute
40
40
  # @return [Array<FileInstanceDifference>] The set of file instances having this type of change
41
- has_many :files, FileInstanceDifference, :tag => 'file'
41
+ has_many :files, FileInstanceDifference, tag: 'file'
42
42
  end
43
43
  end
@@ -1,4 +1,4 @@
1
- require 'moab'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Moab
4
4
  # The file path and last modification date properties of a file
@@ -25,7 +25,7 @@ module Moab
25
25
 
26
26
  # @attribute
27
27
  # @return [String] The id is the filename path, relative to the file group's base directory
28
- attribute :path, String, :key => true
28
+ attribute :path, String, key: true
29
29
 
30
30
  # @attribute
31
31
  # @return [String] gsub(/\n/,' ')
@@ -54,7 +54,8 @@ module Moab
54
54
  # @return [Boolean] Returns true if self and other have the same path.
55
55
  def eql?(other)
56
56
  return false unless other.respond_to?(:path) # Cannot equal an incomparable type!
57
- self.path == other.path
57
+
58
+ path == other.path
58
59
  end
59
60
 
60
61
  # @api internal
@@ -1,4 +1,4 @@
1
- require 'moab'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Moab
4
4
  # A container for recording difference information at the file level
@@ -28,7 +28,7 @@ module Moab
28
28
 
29
29
  # (see Serializable#initialize)
30
30
  def initialize(opts = {})
31
- @signatures = Array.new
31
+ @signatures = []
32
32
  super(opts)
33
33
  end
34
34
 
@@ -38,14 +38,14 @@ module Moab
38
38
 
39
39
  # @attribute
40
40
  # @return [String] The file's path in the basis inventory (usually for an old version)
41
- attribute :basis_path, String, :tag => 'basisPath', :on_save => Proc.new { |s| s.to_s }
41
+ attribute :basis_path, String, tag: 'basisPath', on_save: proc { |s| s.to_s }
42
42
 
43
43
  # @attribute
44
44
  # @return [String] The file's path in the other inventory (usually for an new version) compared against the basis
45
- attribute :other_path, String, :tag => 'otherPath', :on_save => Proc.new { |s| s.to_s }
45
+ attribute :other_path, String, tag: 'otherPath', on_save: proc { |s| s.to_s }
46
46
 
47
47
  # @attribute
48
48
  # @return [Array<FileSignature>] The fixity data of the file manifestation(s) (plural if change was a content modification)
49
- has_many :signatures, FileSignature, :tag => 'fileSignature'
49
+ has_many :signatures, FileSignature, tag: 'fileSignature'
50
50
  end
51
51
  end
@@ -1,4 +1,4 @@
1
- require 'moab'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Moab
4
4
  # A structured container for recording information about a collection of related files.
@@ -35,7 +35,7 @@ module Moab
35
35
 
36
36
  # (see Serializable#initialize)
37
37
  def initialize(opts = {})
38
- @groups = Array.new
38
+ @groups = []
39
39
  @inventory_datetime = Time.now
40
40
  super(opts)
41
41
  end
@@ -46,20 +46,20 @@ module Moab
46
46
 
47
47
  # @attribute
48
48
  # @return [String] The digital object identifier (druid)
49
- attribute :digital_object_id, String, :tag => 'objectId'
49
+ attribute :digital_object_id, String, tag: 'objectId'
50
50
 
51
51
  # @attribute
52
52
  # @return [Integer] The ordinal version number
53
- attribute :version_id, Integer, :tag => 'versionId', :key => true, :on_save => Proc.new { |n| n.to_s }
53
+ attribute :version_id, Integer, tag: 'versionId', key: true, on_save: proc { |n| n.to_s }
54
54
 
55
55
  # @return [String] The unique identifier concatenating digital object id with version id
56
56
  def composite_key
57
- digital_object_id + '-' + StorageObject.version_dirname(version_id)
57
+ "#{digital_object_id}-#{StorageObject.version_dirname(version_id)}"
58
58
  end
59
59
 
60
60
  # @attribute
61
61
  # @return [String] The datetime at which the inventory was created
62
- attribute :inventory_datetime, String, :tag => 'inventoryDatetime'
62
+ attribute :inventory_datetime, String, tag: 'inventoryDatetime'
63
63
 
64
64
  def inventory_datetime=(datetime)
65
65
  @inventory_datetime = Moab::UtcTime.input(datetime)
@@ -71,7 +71,7 @@ module Moab
71
71
 
72
72
  # @attribute
73
73
  # @return [Integer] The total number of data files in the inventory (dynamically calculated)
74
- attribute :file_count, Integer, :tag => 'fileCount', :on_save => Proc.new { |t| t.to_s }
74
+ attribute :file_count, Integer, tag: 'fileCount', on_save: proc { |t| t.to_s }
75
75
 
76
76
  def file_count
77
77
  groups.inject(0) { |sum, group| sum + group.file_count }
@@ -79,7 +79,7 @@ module Moab
79
79
 
80
80
  # @attribute
81
81
  # @return [Integer] The total size (in bytes) in all files of all files in the inventory (dynamically calculated)
82
- attribute :byte_count, Integer, :tag => 'byteCount', :on_save => Proc.new { |t| t.to_s }
82
+ attribute :byte_count, Integer, tag: 'byteCount', on_save: proc { |t| t.to_s }
83
83
 
84
84
  def byte_count
85
85
  groups.inject(0) { |sum, group| sum + group.byte_count }
@@ -87,7 +87,7 @@ module Moab
87
87
 
88
88
  # @attribute
89
89
  # @return [Integer] The total disk usage (in 1 kB blocks) of all data files (estimating du -k result) (dynamically calculated)
90
- attribute :block_count, Integer, :tag => 'blockCount', :on_save => Proc.new { |t| t.to_s }
90
+ attribute :block_count, Integer, tag: 'blockCount', on_save: proc { |t| t.to_s }
91
91
 
92
92
  def block_count
93
93
  groups.inject(0) { |sum, group| sum + group.block_count }
@@ -95,18 +95,18 @@ module Moab
95
95
 
96
96
  # @attribute
97
97
  # @return [Array<FileGroup>] The set of data groups comprising the version
98
- has_many :groups, FileGroup, :tag => 'fileGroup'
98
+ has_many :groups, FileGroup, tag: 'fileGroup'
99
99
 
100
100
  # @return [Array<FileGroup] The set of data groups that contain files
101
101
  def non_empty_groups
102
- groups.select { |group| !group.files.empty? }
102
+ groups.reject { |group| group.files.empty? }
103
103
  end
104
104
 
105
105
  # @param non_empty [Boolean] if true, return group_id's only for groups having files
106
106
  # @return [Array<String>] group identifiers contained in this file inventory
107
107
  def group_ids(non_empty = nil)
108
- my_groups = non_empty ? self.non_empty_groups : groups
109
- my_groups.map { |g| g.group_id }
108
+ my_groups = non_empty ? non_empty_groups : groups
109
+ my_groups.map(&:group_id)
110
110
  end
111
111
 
112
112
  # @param [String] group_id The identifer of the group to be selected
@@ -119,12 +119,12 @@ module Moab
119
119
  # @return [Boolean] true if the group is missing or empty
120
120
  def group_empty?(group_id)
121
121
  group = self.group(group_id)
122
- group.nil? or group.files.empty?
122
+ group.nil? || group.files.empty?
123
123
  end
124
124
 
125
125
  # @return [Array<String>] The data fields to include in summary reports
126
126
  def summary_fields
127
- %w{type digital_object_id version_id inventory_datetime file_count byte_count block_count groups}
127
+ %w[type digital_object_id version_id inventory_datetime file_count byte_count block_count groups]
128
128
  end
129
129
 
130
130
  # @param [String] group_id The identifer of the group to be selected
@@ -134,9 +134,11 @@ module Moab
134
134
  file_group = group(group_id)
135
135
  errmsg = "group #{group_id} not found for #{digital_object_id} - #{version_id}"
136
136
  raise FileNotFoundException, errmsg if file_group.nil?
137
+
137
138
  file_signature = file_group.path_hash[file_id]
138
139
  errmsg = "#{group_id} file #{file_id} not found for #{digital_object_id} - #{version_id}"
139
140
  raise FileNotFoundException, errmsg if file_signature.nil?
141
+
140
142
  file_signature
141
143
  end
142
144
 
@@ -161,17 +163,9 @@ module Moab
161
163
  def data_source
162
164
  data_source = (groups.collect { |g| g.data_source.to_s }).join('|')
163
165
  if data_source.start_with?('contentMetadata')
164
- if version_id
165
- "v#{version_id}-#{data_source}"
166
- else
167
- "new-#{data_source}"
168
- end
166
+ version_id ? "v#{version_id}-#{data_source}" : "new-#{data_source}"
169
167
  else
170
- if version_id
171
- "v#{version_id}"
172
- else
173
- data_source
174
- end
168
+ version_id ? "v#{version_id}" : data_source
175
169
  end
176
170
  end
177
171
 
@@ -185,7 +179,7 @@ module Moab
185
179
  if group_id
186
180
  groups << FileGroup.new(group_id: group_id).group_from_directory(data_dir)
187
181
  else
188
- ['content', 'metadata'].each do |gid|
182
+ %w[content metadata].each do |gid|
189
183
  groups << FileGroup.new(group_id: gid).group_from_directory(Pathname(data_dir).join(gid))
190
184
  end
191
185
  end
@@ -200,7 +194,7 @@ module Moab
200
194
  signatures_from_bag = signatures_from_bagit_manifests(bag_pathname)
201
195
  bag_data_subdirs = bag_pathname.join('data').children
202
196
  bag_data_subdirs.each do |subdir|
203
- groups << FileGroup.new(:group_id => subdir.basename.to_s).group_from_bagit_subdir(subdir, signatures_from_bag)
197
+ groups << FileGroup.new(group_id: subdir.basename.to_s).group_from_bagit_subdir(subdir, signatures_from_bag)
204
198
  end
205
199
  self
206
200
  end
@@ -208,7 +202,7 @@ module Moab
208
202
  # @param bag_pathname [Pathname] The location of the BagIt bag to be inventoried
209
203
  # @return [Hash<Pathname,FileSignature>] The fixity data present in the bag's manifest files
210
204
  def signatures_from_bagit_manifests(bag_pathname)
211
- manifest_pathname = Hash.new
205
+ manifest_pathname = {}
212
206
  DEFAULT_CHECKSUM_TYPES.each do |type|
213
207
  manifest_pathname[type] = bag_pathname.join("manifest-#{type}.txt")
214
208
  end
@@ -235,14 +229,14 @@ module Moab
235
229
  def human_size
236
230
  count = 0
237
231
  size = byte_count
238
- while size >= 1024 and count < 4
232
+ while (size >= 1024) && (count < 4)
239
233
  size /= 1024.0
240
234
  count += 1
241
235
  end
242
236
  if count == 0
243
- sprintf("%d B", size)
237
+ format("%d B", size)
244
238
  else
245
- sprintf("%.2f %s", size, %w[B KB MB GB TB][count])
239
+ format("%.2f %s", size, %w[B KB MB GB TB][count])
246
240
  end
247
241
  end
248
242