ocfl 0.5.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 734c2a614db8c30eb86ddd0c7a32b6c10d813adb9ae5244d50614f35244c64cd
4
- data.tar.gz: 4b5daffdbd581fe38974975a7f9e6dfcef734d078833b0eb030d750aacc7b18e
3
+ metadata.gz: 04033b37955d5ee76f304558abce0d860317fbd019e4a84ac033e2e4b4a89b49
4
+ data.tar.gz: 24aa1a8705a985d88900f30fd59c2e19be305edb3b710293330cfb6607fb6e46
5
5
  SHA512:
6
- metadata.gz: 8c67987902f4adc67c8c250af66568872b9f3e9ca9cd9a3df60f26702e4ac16bfb6aea9e44628f427fe910af548ebc534436005e857f15cc3d47e4a31cc667a3
7
- data.tar.gz: 857a0a20ee5a57c6b7087ef43264dbe2d3fd9b258175cc9449885a4b0eb1d56823cfe87eccad9bb86c5efc26ce5c2433e0465d6c5b0e425523668a18a7131e6a
6
+ metadata.gz: ae4c04c535047ff07f7123787cc08efa6cf2f56c5bf53f2a21366bf81f0474dfcbc35c48802c52c920c1a36d8f1bd77bc7558c4f0ac75e17afba0c131fd9dd45
7
+ data.tar.gz: cf9d0d5037ecb46946c9f8eab7407097cc0330f26d45566077ce83e61371cf1ebf8d906e13ee8ee003b40f9e2fb6b11b31d70e6de194a3f895503ccfc3947466
data/.rubocop.yml CHANGED
@@ -28,6 +28,9 @@ RSpec/MultipleExpectations:
28
28
  RSpec/ExampleLength:
29
29
  Max: 10
30
30
 
31
+ RSpec/MultipleMemoizedHelpers:
32
+ Max: 8
33
+
31
34
  RSpec/NestedGroups:
32
35
  Max: 4
33
36
 
data/README.md CHANGED
@@ -27,14 +27,39 @@ directory.exists?
27
27
  # => true
28
28
  directory.valid?
29
29
  # => true
30
+ ```
31
+
32
+ ### Versions
33
+
34
+ There are three ways to get a version with an existing object directory.
30
35
 
36
+ #### Start a new version
37
+ ```
31
38
  new_version = directory.begin_new_version
32
39
  new_version.copy_file('sig/ocfl.rbs')
33
40
  new_version.save
34
41
 
35
42
  directory.head
36
43
  # => 'v2'
44
+ ```
45
+
46
+ #### Re-open the existing head version
47
+ ```
48
+ new_version = directory.reopen_head_version
49
+ new_version.delete_file('cb6c8557fc724c636929775212c5194984d68cb1508a1')
50
+ new_version.copy_file('sig/ocfl.rbs')
51
+ new_version.save
52
+ ```
53
+
54
+ #### Overwrite the existing head version
55
+ ```
56
+ new_version = directory.overwrite_current_version
57
+ new_version.copy_file('sig/ocfl.rbs')
58
+ new_version.save
59
+ ```
37
60
 
61
+ ### File paths
62
+ ```
38
63
  # List file names that were part of a given version
39
64
  directory.versions['v2'].file_names
40
65
  # => ["ocfl.rbs"]
@@ -44,20 +69,9 @@ directory.path(filepath: "ocfl.rbs", version: "v2")
44
69
  # => <Pathname:/files/[object_root]/v2/content/ocfl.rbs>
45
70
 
46
71
  # Get the path of a file in the head version
47
- directory.path(filepath: "ocfl.rbs", version: :head)
48
- # => <Pathname:/files/[object_root]/v2/content/ocfl.rbs>
49
-
50
- # Get the path of a file from the latest version in which it was changed
51
72
  directory.path(filepath: "ocfl.rbs")
52
73
  # => <Pathname:/files/[object_root]/v2/content/ocfl.rbs>
53
74
 
54
- new_version = directory.overwrite_current_version
55
- new_version.copy_file('sig/ocfl.rbs')
56
- new_version.save
57
-
58
- new_version = directory.clone_current_version
59
- new_version.copy_file('Gemfile')
60
- new_version.save
61
75
  ```
62
76
 
63
77
  ## Development
@@ -18,14 +18,10 @@ module OCFL
18
18
  delegate :head, :versions, :manifest, to: :inventory
19
19
 
20
20
  def path(filepath:, version: nil)
21
- version = head if version == :head
22
- relative_path = if version
23
- version_inventory(version).path(filepath)
24
- else
25
- inventory.path(filepath)
26
- end
21
+ version ||= head
22
+ relative_path = version_inventory(version).path(filepath)
27
23
 
28
- raise FileNotFound, "Path '#{filepath}' not found in #{version || "object"} inventory" if relative_path.nil?
24
+ raise FileNotFound, "Path '#{filepath}' not found in #{version} inventory" if relative_path.nil?
29
25
 
30
26
  object_root / relative_path
31
27
  end
@@ -68,14 +64,17 @@ module OCFL
68
64
  true
69
65
  end
70
66
 
67
+ # Start a completely new version
71
68
  def begin_new_version
72
- DraftVersion.new(object_directory: self)
69
+ DraftVersion.new(object_directory: self, state: head_inventory.state)
73
70
  end
74
71
 
75
- def clone_current_version
76
- DraftVersion.new(object_directory: self, state: head_inventory.state)
72
+ # Get a handle for the head version
73
+ def reopen_head_version
74
+ DraftVersion.new(object_directory: self, overwrite_head: true, state: head_inventory.state)
77
75
  end
78
76
 
77
+ # Get a handle that will replace the existing head version
79
78
  def overwrite_current_version
80
79
  DraftVersion.new(object_directory: self, overwrite_head: true)
81
80
  end
@@ -28,6 +28,16 @@ module OCFL
28
28
  copy_one(File.basename(incoming_path), incoming_path, destination_path)
29
29
  end
30
30
 
31
+ # Note, this only removes the file from this version. Previous versions may still use it.
32
+ def delete_file(sha512_digest)
33
+ state.delete(sha512_digest)
34
+ # If the manifest points at the current content directory, then we can delete it.
35
+ file_paths = manifest[sha512_digest]
36
+ return unless file_paths.all? { |path| path.start_with?("#{version_number}/") }
37
+
38
+ File.unlink (object_directory.object_root + file_paths.first).to_s
39
+ end
40
+
31
41
  # Copies files into the object and preserves their relative paths as logical directories in the object
32
42
  def copy_recursive(incoming_path, destination_path: "")
33
43
  prepare_content_directory
@@ -93,8 +103,8 @@ module OCFL
93
103
  def build_inventory
94
104
  old_data = object_directory.inventory.data
95
105
  versions = versions(old_data.versions)
96
- # Prune items from manifest if they are not part of any version
97
106
 
107
+ # Prune items from manifest if they are not part of any version
98
108
  Inventory::InventoryStruct.new(old_data.to_h.merge(manifest: filtered_manifest(versions),
99
109
  head: version_number, versions:))
100
110
  end
@@ -108,7 +118,8 @@ module OCFL
108
118
  # The manifest after unused SHAs have been filtered out.
109
119
  def filtered_manifest(versions)
110
120
  shas_in_versions = versions.values.flat_map { |v| v.state.keys }.uniq
111
- manifest.slice(*shas_in_versions)
121
+ manifest.slice!(*shas_in_versions)
122
+ manifest
112
123
  end
113
124
  end
114
125
  end
@@ -34,13 +34,11 @@ module OCFL
34
34
 
35
35
  # @return [String,nil] the path to the file relative to the object root. (e.g. v2/content/image.tiff)
36
36
  def path(logical_path)
37
- matching_paths = manifest.values.flatten.select do |path|
38
- path.match(%r{\Av\d+/#{content_directory}/#{logical_path}\z})
39
- end
37
+ digest, = state.find { |_, logical_paths| logical_paths.include?(logical_path) }
40
38
 
41
- return if matching_paths.empty?
39
+ return unless digest
42
40
 
43
- matching_paths.max_by { |path| path[/\d+/].to_i }
41
+ manifest[digest].find { |content_path| content_path.match(%r{\Av\d+/#{content_directory}/#{logical_path}\z}) }
44
42
  end
45
43
 
46
44
  def head_version
data/lib/ocfl/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OCFL
4
- VERSION = "0.5.0"
4
+ VERSION = "0.7.0"
5
5
  end
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.5.0
4
+ version: 0.7.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-05-23 00:00:00.000000000 Z
11
+ date: 2024-05-31 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.10
128
+ rubygems_version: 3.4.19
129
129
  signing_key:
130
130
  specification_version: 4
131
131
  summary: A ruby library for interacting with the Oxford Common File Layout (OCFL)