ocfl 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +158 -3
- data/README.md +16 -2
- data/lib/ocfl/object/directory.rb +19 -10
- data/lib/ocfl/object/directory_builder.rb +25 -16
- data/lib/ocfl/object/draft_version.rb +17 -15
- data/lib/ocfl/object/inventory.rb +11 -4
- data/lib/ocfl/object/inventory_validator.rb +2 -5
- data/lib/ocfl/object/inventory_writer.rb +2 -5
- data/lib/ocfl/object/version.rb +4 -0
- data/lib/ocfl/object.rb +3 -1
- data/lib/ocfl/version.rb +1 -1
- data/lib/ocfl.rb +5 -14
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 734c2a614db8c30eb86ddd0c7a32b6c10d813adb9ae5244d50614f35244c64cd
|
4
|
+
data.tar.gz: 4b5daffdbd581fe38974975a7f9e6dfcef734d078833b0eb030d750aacc7b18e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c67987902f4adc67c8c250af66568872b9f3e9ca9cd9a3df60f26702e4ac16bfb6aea9e44628f427fe910af548ebc534436005e857f15cc3d47e4a31cc667a3
|
7
|
+
data.tar.gz: 857a0a20ee5a57c6b7087ef43264dbe2d3fd9b258175cc9449885a4b0eb1d56823cfe87eccad9bb86c5efc26ce5c2433e0465d6c5b0e425523668a18a7131e6a
|
data/.rubocop.yml
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-performance
|
3
|
+
- rubocop-rake
|
4
|
+
- rubocop-rspec
|
5
|
+
|
1
6
|
AllCops:
|
2
7
|
TargetRubyVersion: 3.1
|
3
8
|
|
@@ -17,8 +22,14 @@ Metrics/BlockLength:
|
|
17
22
|
- describe
|
18
23
|
- context
|
19
24
|
|
20
|
-
|
21
|
-
Enabled: false
|
25
|
+
RSpec/MultipleExpectations:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
RSpec/ExampleLength:
|
29
|
+
Max: 10
|
30
|
+
|
31
|
+
RSpec/NestedGroups:
|
32
|
+
Max: 4
|
22
33
|
|
23
34
|
Gemspec/DeprecatedAttributeAssignment: # new in 1.30
|
24
35
|
Enabled: true
|
@@ -219,4 +230,148 @@ Style/SuperWithArgsParentheses: # new in 1.58
|
|
219
230
|
Style/SwapValues: # new in 1.1
|
220
231
|
Enabled: true
|
221
232
|
Style/YAMLFileRead: # new in 1.53
|
222
|
-
Enabled: true
|
233
|
+
Enabled: true
|
234
|
+
Style/MapIntoArray: # new in 1.63
|
235
|
+
Enabled: true
|
236
|
+
Performance/AncestorsInclude: # new in 1.7
|
237
|
+
Enabled: true
|
238
|
+
Performance/BigDecimalWithNumericArgument: # new in 1.7
|
239
|
+
Enabled: true
|
240
|
+
Performance/BlockGivenWithExplicitBlock: # new in 1.9
|
241
|
+
Enabled: true
|
242
|
+
Performance/CollectionLiteralInLoop: # new in 1.8
|
243
|
+
Enabled: true
|
244
|
+
Performance/ConcurrentMonotonicTime: # new in 1.12
|
245
|
+
Enabled: true
|
246
|
+
Performance/ConstantRegexp: # new in 1.9
|
247
|
+
Enabled: true
|
248
|
+
Performance/MapCompact: # new in 1.11
|
249
|
+
Enabled: true
|
250
|
+
Performance/MapMethodChain: # new in 1.19
|
251
|
+
Enabled: true
|
252
|
+
Performance/MethodObjectAsBlock: # new in 1.9
|
253
|
+
Enabled: true
|
254
|
+
Performance/RedundantEqualityComparisonBlock: # new in 1.10
|
255
|
+
Enabled: true
|
256
|
+
Performance/RedundantSortBlock: # new in 1.7
|
257
|
+
Enabled: true
|
258
|
+
Performance/RedundantSplitRegexpArgument: # new in 1.10
|
259
|
+
Enabled: true
|
260
|
+
Performance/RedundantStringChars: # new in 1.7
|
261
|
+
Enabled: true
|
262
|
+
Performance/ReverseFirst: # new in 1.7
|
263
|
+
Enabled: true
|
264
|
+
Performance/SortReverse: # new in 1.7
|
265
|
+
Enabled: true
|
266
|
+
Performance/Squeeze: # new in 1.7
|
267
|
+
Enabled: true
|
268
|
+
Performance/StringIdentifierArgument: # new in 1.13
|
269
|
+
Enabled: true
|
270
|
+
Performance/StringInclude: # new in 1.7
|
271
|
+
Enabled: true
|
272
|
+
Performance/Sum: # new in 1.8
|
273
|
+
Enabled: true
|
274
|
+
Capybara/ClickLinkOrButtonStyle: # new in 2.19
|
275
|
+
Enabled: true
|
276
|
+
Capybara/MatchStyle: # new in 2.17
|
277
|
+
Enabled: true
|
278
|
+
Capybara/NegationMatcher: # new in 2.14
|
279
|
+
Enabled: true
|
280
|
+
Capybara/RedundantWithinFind: # new in 2.20
|
281
|
+
Enabled: true
|
282
|
+
Capybara/SpecificActions: # new in 2.14
|
283
|
+
Enabled: true
|
284
|
+
Capybara/SpecificFinders: # new in 2.13
|
285
|
+
Enabled: true
|
286
|
+
Capybara/SpecificMatcher: # new in 2.12
|
287
|
+
Enabled: true
|
288
|
+
Capybara/RSpec/HaveSelector: # new in 2.19
|
289
|
+
Enabled: true
|
290
|
+
Capybara/RSpec/PredicateMatcher: # new in 2.19
|
291
|
+
Enabled: true
|
292
|
+
FactoryBot/AssociationStyle: # new in 2.23
|
293
|
+
Enabled: true
|
294
|
+
FactoryBot/ConsistentParenthesesStyle: # new in 2.14
|
295
|
+
Enabled: true
|
296
|
+
FactoryBot/ExcessiveCreateList: # new in 2.25
|
297
|
+
Enabled: true
|
298
|
+
FactoryBot/FactoryAssociationWithStrategy: # new in 2.23
|
299
|
+
Enabled: true
|
300
|
+
FactoryBot/FactoryNameStyle: # new in 2.16
|
301
|
+
Enabled: true
|
302
|
+
FactoryBot/IdSequence: # new in 2.24
|
303
|
+
Enabled: true
|
304
|
+
FactoryBot/RedundantFactoryOption: # new in 2.23
|
305
|
+
Enabled: true
|
306
|
+
FactoryBot/SyntaxMethods: # new in 2.7
|
307
|
+
Enabled: true
|
308
|
+
RSpecRails/AvoidSetupHook: # new in 2.4
|
309
|
+
Enabled: true
|
310
|
+
RSpecRails/HaveHttpStatus: # new in 2.12
|
311
|
+
Enabled: true
|
312
|
+
RSpecRails/InferredSpecType: # new in 2.14
|
313
|
+
Enabled: true
|
314
|
+
RSpecRails/MinitestAssertions: # new in 2.17
|
315
|
+
Enabled: true
|
316
|
+
RSpecRails/NegationBeValid: # new in 2.23
|
317
|
+
Enabled: true
|
318
|
+
RSpecRails/TravelAround: # new in 2.19
|
319
|
+
Enabled: true
|
320
|
+
RSpec/BeEmpty: # new in 2.20
|
321
|
+
Enabled: true
|
322
|
+
RSpec/BeEq: # new in 2.9.0
|
323
|
+
Enabled: true
|
324
|
+
RSpec/BeNil: # new in 2.9.0
|
325
|
+
Enabled: true
|
326
|
+
RSpec/ChangeByZero: # new in 2.11
|
327
|
+
Enabled: true
|
328
|
+
RSpec/ContainExactly: # new in 2.19
|
329
|
+
Enabled: true
|
330
|
+
RSpec/DuplicatedMetadata: # new in 2.16
|
331
|
+
Enabled: true
|
332
|
+
RSpec/EmptyMetadata: # new in 2.24
|
333
|
+
Enabled: true
|
334
|
+
RSpec/EmptyOutput: # new in 2.29
|
335
|
+
Enabled: true
|
336
|
+
RSpec/Eq: # new in 2.24
|
337
|
+
Enabled: true
|
338
|
+
RSpec/ExcessiveDocstringSpacing: # new in 2.5
|
339
|
+
Enabled: true
|
340
|
+
RSpec/IdenticalEqualityAssertion: # new in 2.4
|
341
|
+
Enabled: true
|
342
|
+
RSpec/IndexedLet: # new in 2.20
|
343
|
+
Enabled: true
|
344
|
+
RSpec/IsExpectedSpecify: # new in 2.27
|
345
|
+
Enabled: true
|
346
|
+
RSpec/MatchArray: # new in 2.19
|
347
|
+
Enabled: true
|
348
|
+
RSpec/MetadataStyle: # new in 2.24
|
349
|
+
Enabled: true
|
350
|
+
RSpec/NoExpectationExample: # new in 2.13
|
351
|
+
Enabled: true
|
352
|
+
RSpec/PendingWithoutReason: # new in 2.16
|
353
|
+
Enabled: true
|
354
|
+
RSpec/ReceiveMessages: # new in 2.23
|
355
|
+
Enabled: true
|
356
|
+
RSpec/RedundantAround: # new in 2.19
|
357
|
+
Enabled: true
|
358
|
+
RSpec/RedundantPredicateMatcher: # new in 2.26
|
359
|
+
Enabled: true
|
360
|
+
RSpec/RemoveConst: # new in 2.26
|
361
|
+
Enabled: true
|
362
|
+
RSpec/RepeatedSubjectCall: # new in 2.27
|
363
|
+
Enabled: true
|
364
|
+
RSpec/SkipBlockInsideExample: # new in 2.19
|
365
|
+
Enabled: true
|
366
|
+
RSpec/SortMetadata: # new in 2.14
|
367
|
+
Enabled: true
|
368
|
+
RSpec/SpecFilePathFormat: # new in 2.24
|
369
|
+
Enabled: true
|
370
|
+
RSpec/SpecFilePathSuffix: # new in 2.24
|
371
|
+
Enabled: true
|
372
|
+
RSpec/SubjectDeclaration: # new in 2.5
|
373
|
+
Enabled: true
|
374
|
+
RSpec/UndescriptiveLiteralsDescription: # new in 2.29
|
375
|
+
Enabled: true
|
376
|
+
RSpec/VerifiedDoubleReference: # new in 2.10.0
|
377
|
+
Enabled: true
|
data/README.md
CHANGED
@@ -35,15 +35,29 @@ new_version.save
|
|
35
35
|
directory.head
|
36
36
|
# => 'v2'
|
37
37
|
|
38
|
-
|
38
|
+
# List file names that were part of a given version
|
39
|
+
directory.versions['v2'].file_names
|
40
|
+
# => ["ocfl.rbs"]
|
41
|
+
|
42
|
+
# Get the path of a file in a given version
|
43
|
+
directory.path(filepath: "ocfl.rbs", version: "v2")
|
44
|
+
# => <Pathname:/files/[object_root]/v2/content/ocfl.rbs>
|
45
|
+
|
46
|
+
# Get the path of a file in the head version
|
47
|
+
directory.path(filepath: "ocfl.rbs", version: :head)
|
39
48
|
# => <Pathname:/files/[object_root]/v2/content/ocfl.rbs>
|
40
49
|
|
41
|
-
|
50
|
+
# Get the path of a file from the latest version in which it was changed
|
51
|
+
directory.path(filepath: "ocfl.rbs")
|
42
52
|
# => <Pathname:/files/[object_root]/v2/content/ocfl.rbs>
|
43
53
|
|
44
54
|
new_version = directory.overwrite_current_version
|
45
55
|
new_version.copy_file('sig/ocfl.rbs')
|
46
56
|
new_version.save
|
57
|
+
|
58
|
+
new_version = directory.clone_current_version
|
59
|
+
new_version.copy_file('Gemfile')
|
60
|
+
new_version.save
|
47
61
|
```
|
48
62
|
|
49
63
|
## Development
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "digest"
|
4
|
-
|
5
3
|
module OCFL
|
6
4
|
module Object
|
7
5
|
# An OCFL Directory layout for a particular object.
|
@@ -19,15 +17,22 @@ module OCFL
|
|
19
17
|
|
20
18
|
delegate :head, :versions, :manifest, to: :inventory
|
21
19
|
|
22
|
-
def path(version
|
20
|
+
def path(filepath:, version: nil)
|
23
21
|
version = head if version == :head
|
24
|
-
relative_path =
|
25
|
-
|
22
|
+
relative_path = if version
|
23
|
+
version_inventory(version).path(filepath)
|
24
|
+
else
|
25
|
+
inventory.path(filepath)
|
26
|
+
end
|
27
|
+
|
28
|
+
raise FileNotFound, "Path '#{filepath}' not found in #{version || "object"} inventory" if relative_path.nil?
|
29
|
+
|
30
|
+
object_root / relative_path
|
26
31
|
end
|
27
32
|
|
28
33
|
def inventory
|
29
34
|
@inventory ||= begin
|
30
|
-
data = InventoryLoader.load(object_root
|
35
|
+
data = InventoryLoader.load(object_root / "inventory.json")
|
31
36
|
if data.success?
|
32
37
|
Inventory.new(data: data.value!)
|
33
38
|
else
|
@@ -44,7 +49,7 @@ module OCFL
|
|
44
49
|
|
45
50
|
def version_inventory(version)
|
46
51
|
@version_inventory[version] ||= begin
|
47
|
-
data = InventoryLoader.load(object_root
|
52
|
+
data = InventoryLoader.load(object_root / version / "inventory.json")
|
48
53
|
if data.success?
|
49
54
|
Inventory.new(data: data.value!)
|
50
55
|
else
|
@@ -60,12 +65,17 @@ module OCFL
|
|
60
65
|
@inventory = nil
|
61
66
|
@errors = nil
|
62
67
|
@version_inventory_errors = {}
|
68
|
+
true
|
63
69
|
end
|
64
70
|
|
65
71
|
def begin_new_version
|
66
72
|
DraftVersion.new(object_directory: self)
|
67
73
|
end
|
68
74
|
|
75
|
+
def clone_current_version
|
76
|
+
DraftVersion.new(object_directory: self, state: head_inventory.state)
|
77
|
+
end
|
78
|
+
|
69
79
|
def overwrite_current_version
|
70
80
|
DraftVersion.new(object_directory: self, overwrite_head: true)
|
71
81
|
end
|
@@ -82,7 +92,7 @@ module OCFL
|
|
82
92
|
end
|
83
93
|
|
84
94
|
def head_directory_valid?
|
85
|
-
InventoryValidator.new(directory: object_root
|
95
|
+
InventoryValidator.new(directory: object_root / inventory.head).valid? &&
|
86
96
|
!head_inventory.nil? # Ensures it could be loaded
|
87
97
|
end
|
88
98
|
|
@@ -91,9 +101,8 @@ module OCFL
|
|
91
101
|
end
|
92
102
|
|
93
103
|
def namaste_file
|
94
|
-
object_root
|
104
|
+
object_root / "0=ocfl_object_1.1"
|
95
105
|
end
|
96
106
|
end
|
97
|
-
# rubocop:enable Style/StringConcatenation
|
98
107
|
end
|
99
108
|
end
|
@@ -1,21 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "digest"
|
4
|
-
|
5
3
|
module OCFL
|
6
4
|
module Object
|
7
5
|
# Creates a OCFL Directory layout for a particular object.
|
8
6
|
class DirectoryBuilder
|
9
7
|
class ObjectExists < Error; end
|
10
8
|
|
11
|
-
def initialize(object_root:, id:)
|
9
|
+
def initialize(object_root:, id:, content_directory: nil)
|
12
10
|
@object_root = Pathname.new(object_root)
|
13
11
|
raise ObjectExists, "The directory `#{object_root}' already exists" if @object_root.exist?
|
14
12
|
|
15
13
|
@id = id
|
14
|
+
inventory = Inventory.new(
|
15
|
+
data: Inventory::InventoryStruct.new(
|
16
|
+
new_inventory_attrs.tap { |attrs| attrs[:contentDirectory] = content_directory if content_directory }
|
17
|
+
)
|
18
|
+
)
|
19
|
+
@object_directory = Directory.new(object_root:, inventory:)
|
16
20
|
end
|
17
21
|
|
18
|
-
attr_reader :id, :object_root, :object_directory
|
22
|
+
attr_reader :id, :inventory, :object_root, :object_directory
|
19
23
|
|
20
24
|
def copy_file(...)
|
21
25
|
create_object_directory
|
@@ -33,28 +37,33 @@ module OCFL
|
|
33
37
|
|
34
38
|
# @return [Directory]
|
35
39
|
def save
|
36
|
-
|
37
|
-
FileUtils.
|
38
|
-
|
39
|
-
FileUtils.touch(object_root + "0=ocfl_object_1.1")
|
40
|
+
FileUtils.mkdir_p(object_root)
|
41
|
+
FileUtils.touch(object_directory.namaste_file)
|
40
42
|
write_inventory
|
41
43
|
object_directory
|
42
44
|
end
|
43
45
|
|
44
46
|
def version
|
45
|
-
@version ||=
|
46
|
-
data = Inventory::InventoryStruct.new(id:, version: "v0", type: Inventory::URI_1_1, digestAlgorithm: "sha512",
|
47
|
-
head: "v0", versions: {}, manifest: {})
|
48
|
-
inventory = Inventory.new(data:)
|
49
|
-
@object_directory = Directory.new(object_root: @object_root, inventory:)
|
50
|
-
DraftVersion.new(object_directory:)
|
51
|
-
end
|
47
|
+
@version ||= DraftVersion.new(object_directory:)
|
52
48
|
end
|
53
49
|
|
54
50
|
def write_inventory
|
55
51
|
version.save
|
56
52
|
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def new_inventory_attrs
|
57
|
+
{
|
58
|
+
id:,
|
59
|
+
version: "v0",
|
60
|
+
type: Inventory::URI_1_1,
|
61
|
+
digestAlgorithm: "sha512",
|
62
|
+
head: "v0",
|
63
|
+
versions: {},
|
64
|
+
manifest: {}
|
65
|
+
}
|
66
|
+
end
|
57
67
|
end
|
58
|
-
# rubocop:enable Style/StringConcatenation
|
59
68
|
end
|
60
69
|
end
|
@@ -1,16 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "digest"
|
4
|
-
|
5
3
|
module OCFL
|
6
4
|
module Object
|
7
5
|
# A new OCFL version
|
8
6
|
class DraftVersion
|
9
7
|
# @params [Directory] object_directory
|
10
|
-
def initialize(object_directory:, overwrite_head: false)
|
8
|
+
def initialize(object_directory:, overwrite_head: false, state: {})
|
11
9
|
@object_directory = object_directory
|
12
10
|
@manifest = object_directory.inventory.manifest.dup
|
13
|
-
@state =
|
11
|
+
@state = state
|
14
12
|
|
15
13
|
number = object_directory.head.delete_prefix("v").to_i
|
16
14
|
@version_number = "v#{overwrite_head ? number : number + 1}"
|
@@ -25,13 +23,13 @@ module OCFL
|
|
25
23
|
FileUtils.mv(incoming_path, content_path)
|
26
24
|
end
|
27
25
|
|
28
|
-
def copy_file(incoming_path, destination_path:
|
26
|
+
def copy_file(incoming_path, destination_path: "")
|
29
27
|
prepare_content_directory
|
30
28
|
copy_one(File.basename(incoming_path), incoming_path, destination_path)
|
31
29
|
end
|
32
30
|
|
33
31
|
# Copies files into the object and preserves their relative paths as logical directories in the object
|
34
|
-
def copy_recursive(incoming_path, destination_path:
|
32
|
+
def copy_recursive(incoming_path, destination_path: "")
|
35
33
|
prepare_content_directory
|
36
34
|
incoming_path = incoming_path.delete_suffix("/")
|
37
35
|
Dir.glob("#{incoming_path}/**/*").reject { |fn| File.directory?(fn) }.each do |file|
|
@@ -40,27 +38,31 @@ module OCFL
|
|
40
38
|
end
|
41
39
|
|
42
40
|
def save
|
43
|
-
|
44
|
-
|
45
|
-
FileUtils.cp(path + "inventory.json", object_directory.object_root)
|
46
|
-
FileUtils.cp(path + "inventory.json.sha512", object_directory.object_root)
|
41
|
+
prepare_directory # only necessary if the version has no new content (deletes only)
|
42
|
+
write_inventory(build_inventory)
|
47
43
|
object_directory.reload
|
48
44
|
end
|
49
45
|
|
50
46
|
private
|
51
47
|
|
48
|
+
def write_inventory(inventory)
|
49
|
+
InventoryWriter.new(inventory:, path:).write
|
50
|
+
FileUtils.cp(path / "inventory.json", object_directory.object_root)
|
51
|
+
FileUtils.cp(path / "inventory.json.sha512", object_directory.object_root)
|
52
|
+
end
|
53
|
+
|
52
54
|
def copy_one(logical_file_path, incoming_path, destination_path)
|
53
55
|
logical_file_path = File.join(destination_path, logical_file_path) unless destination_path.empty?
|
54
56
|
add(incoming_path, logical_file_path:)
|
55
|
-
parent_dir = (content_path
|
57
|
+
parent_dir = (content_path / logical_file_path).parent
|
56
58
|
FileUtils.mkdir_p(parent_dir) unless parent_dir == content_path
|
57
|
-
FileUtils.cp(incoming_path, content_path
|
59
|
+
FileUtils.cp(incoming_path, content_path / logical_file_path)
|
58
60
|
end
|
59
61
|
|
60
62
|
def add(incoming_path, logical_file_path: File.basename(incoming_path))
|
61
63
|
digest = Digest::SHA512.file(incoming_path).to_s
|
62
64
|
version_content_path = content_path.relative_path_from(object_directory.object_root)
|
63
|
-
file_path_relative_to_root = (version_content_path
|
65
|
+
file_path_relative_to_root = (version_content_path / logical_file_path).to_s
|
64
66
|
@manifest[digest] = [file_path_relative_to_root]
|
65
67
|
@state[digest] = [logical_file_path]
|
66
68
|
end
|
@@ -81,11 +83,11 @@ module OCFL
|
|
81
83
|
end
|
82
84
|
|
83
85
|
def content_path
|
84
|
-
path
|
86
|
+
path / object_directory.inventory.content_directory
|
85
87
|
end
|
86
88
|
|
87
89
|
def path
|
88
|
-
object_directory.object_root
|
90
|
+
object_directory.object_root / version_number
|
89
91
|
end
|
90
92
|
|
91
93
|
def build_inventory
|
@@ -26,18 +26,25 @@ module OCFL
|
|
26
26
|
attr_reader :errors, :data
|
27
27
|
|
28
28
|
delegate :id, :head, :versions, :manifest, to: :data
|
29
|
+
delegate :state, to: :head_version
|
29
30
|
|
30
31
|
def content_directory
|
31
32
|
data.contentDirectory || "content"
|
32
33
|
end
|
33
34
|
|
34
|
-
# @
|
35
|
+
# @return [String,nil] the path to the file relative to the object root. (e.g. v2/content/image.tiff)
|
35
36
|
def path(logical_path)
|
36
|
-
|
37
|
+
matching_paths = manifest.values.flatten.select do |path|
|
38
|
+
path.match(%r{\Av\d+/#{content_directory}/#{logical_path}\z})
|
39
|
+
end
|
37
40
|
|
38
|
-
return
|
41
|
+
return if matching_paths.empty?
|
39
42
|
|
40
|
-
|
43
|
+
matching_paths.max_by { |path| path[/\d+/].to_i }
|
44
|
+
end
|
45
|
+
|
46
|
+
def head_version
|
47
|
+
versions[head]
|
41
48
|
end
|
42
49
|
end
|
43
50
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "digest"
|
4
|
-
|
5
3
|
module OCFL
|
6
4
|
module Object
|
7
5
|
# Checks to see that the inventory.json and it's checksum in a direcotory are valid
|
@@ -29,7 +27,7 @@ module OCFL
|
|
29
27
|
end
|
30
28
|
|
31
29
|
def inventory_checksum_file
|
32
|
-
directory
|
30
|
+
directory / "inventory.json.sha512"
|
33
31
|
end
|
34
32
|
|
35
33
|
def inventory_file_checksum
|
@@ -37,9 +35,8 @@ module OCFL
|
|
37
35
|
end
|
38
36
|
|
39
37
|
def inventory_file
|
40
|
-
directory
|
38
|
+
directory / "inventory.json"
|
41
39
|
end
|
42
40
|
end
|
43
|
-
# rubocop:enable Style/StringConcatenation
|
44
41
|
end
|
45
42
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "digest"
|
4
|
-
|
5
3
|
module OCFL
|
6
4
|
module Object
|
7
5
|
# Writes a OCFL Inventory to json on disk
|
@@ -23,11 +21,11 @@ module OCFL
|
|
23
21
|
end
|
24
22
|
|
25
23
|
def inventory_file
|
26
|
-
path
|
24
|
+
path / "inventory.json"
|
27
25
|
end
|
28
26
|
|
29
27
|
def checksum_file
|
30
|
-
path
|
28
|
+
path / "inventory.json.sha512"
|
31
29
|
end
|
32
30
|
|
33
31
|
def update_inventory_checksum
|
@@ -35,6 +33,5 @@ module OCFL
|
|
35
33
|
File.write(checksum_file, "#{digest} inventory.json")
|
36
34
|
end
|
37
35
|
end
|
38
|
-
# rubocop:enable Style/StringConcatenation
|
39
36
|
end
|
40
37
|
end
|
data/lib/ocfl/object/version.rb
CHANGED
data/lib/ocfl/object.rb
CHANGED
data/lib/ocfl/version.rb
CHANGED
data/lib/ocfl.rb
CHANGED
@@ -1,25 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "ocfl/version"
|
4
3
|
require "zeitwerk"
|
5
|
-
require "
|
4
|
+
require "active_support"
|
5
|
+
require "active_support/core_ext/module/delegation"
|
6
|
+
require "digest"
|
6
7
|
require "dry/monads"
|
7
8
|
require "dry-schema"
|
8
9
|
require "dry-struct"
|
9
|
-
require "
|
10
|
-
require "active_support/core_ext/module/delegation"
|
11
|
-
|
12
|
-
# Custom zeitwerk inflector for OCFL
|
13
|
-
class OCFLInflector < Zeitwerk::Inflector
|
14
|
-
def camelize(basename, _abspath)
|
15
|
-
return "OCFL" if basename == "ocfl"
|
16
|
-
|
17
|
-
super
|
18
|
-
end
|
19
|
-
end
|
10
|
+
require "json"
|
20
11
|
|
21
12
|
loader = Zeitwerk::Loader.for_gem
|
22
|
-
loader.inflector
|
13
|
+
loader.inflector.inflect("ocfl" => "OCFL")
|
23
14
|
loader.setup
|
24
15
|
|
25
16
|
module OCFL
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ocfl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Coyne
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -125,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
125
|
- !ruby/object:Gem::Version
|
126
126
|
version: '0'
|
127
127
|
requirements: []
|
128
|
-
rubygems_version: 3.5.
|
128
|
+
rubygems_version: 3.5.10
|
129
129
|
signing_key:
|
130
130
|
specification_version: 4
|
131
131
|
summary: A ruby library for interacting with the Oxford Common File Layout (OCFL)
|