ocfl 0.6.0 → 0.8.0
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/.rubocop.yml +3 -0
- data/README.md +30 -4
- data/lib/ocfl/object/directory.rb +7 -0
- data/lib/ocfl/object/directory_builder.rb +2 -2
- data/lib/ocfl/object/draft_version.rb +35 -7
- data/lib/ocfl/version.rb +1 -1
- data/lib/ocfl.rb +1 -0
- 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: 9b1b7553fa1d862a3aa1f6a7f63b148f424f1448c321f7b534776c857ce932f2
|
4
|
+
data.tar.gz: 8408cf71f4a08fc2c44485ea69e6f77eb5e49366a80d460d20e7ab7961ef9442
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5420543eb4d07840970600fbc1f4a475e2ae3f09dea57de76087e626ed87a99ec9b02cf4dd38598398fb75aaa1e8eb61fb20d2af4d4b2b9939a269cf811d7b13
|
7
|
+
data.tar.gz: f3f6b84156e307897c3be76ed247043ce5d5f161536267b2ee5cfb8a91b50c6080da57ba6fc5c063349603784a13689ef4bbc74c624cbf302ec3f50810b53307
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -20,25 +20,54 @@ directory = OCFL::Object::Directory.new(object_root: '/files/[object_root]')
|
|
20
20
|
directory.exists?
|
21
21
|
# => false
|
22
22
|
builder = OCFL::Object::DirectoryBuilder.new(object_root: 'spec/abc123', id: 'http://example.com/abc123')
|
23
|
-
builder.copy_file('sig/ocfl.rbs')
|
23
|
+
builder.copy_file('sig/ocfl.rbs', destination_path: 'ocfl/types/generated.rbs')
|
24
24
|
|
25
25
|
directory = builder.save
|
26
26
|
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
|
+
#### Modify the existing head version
|
47
|
+
```
|
48
|
+
new_version = directory.head_version
|
49
|
+
new_version.delete_file('sample.txt')
|
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"]
|
41
66
|
|
67
|
+
# Or on the head version
|
68
|
+
directory.head_version.file_names
|
69
|
+
# => ["ocfl.rbs"]
|
70
|
+
|
42
71
|
# Get the path of a file in a given version
|
43
72
|
directory.path(filepath: "ocfl.rbs", version: "v2")
|
44
73
|
# => <Pathname:/files/[object_root]/v2/content/ocfl.rbs>
|
@@ -47,9 +76,6 @@ directory.path(filepath: "ocfl.rbs", version: "v2")
|
|
47
76
|
directory.path(filepath: "ocfl.rbs")
|
48
77
|
# => <Pathname:/files/[object_root]/v2/content/ocfl.rbs>
|
49
78
|
|
50
|
-
new_version = directory.overwrite_current_version
|
51
|
-
new_version.copy_file('sig/ocfl.rbs')
|
52
|
-
new_version.save
|
53
79
|
```
|
54
80
|
|
55
81
|
## Development
|
@@ -64,10 +64,17 @@ module OCFL
|
|
64
64
|
true
|
65
65
|
end
|
66
66
|
|
67
|
+
# Start a completely new version
|
67
68
|
def begin_new_version
|
68
69
|
DraftVersion.new(object_directory: self, state: head_inventory.state)
|
69
70
|
end
|
70
71
|
|
72
|
+
# Get a handle for the head version
|
73
|
+
def head_version
|
74
|
+
DraftVersion.new(object_directory: self, overwrite_head: true, state: head_inventory.state)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Get a handle that will replace the existing head version
|
71
78
|
def overwrite_current_version
|
72
79
|
DraftVersion.new(object_directory: self, overwrite_head: true)
|
73
80
|
end
|
@@ -33,12 +33,12 @@ module OCFL
|
|
33
33
|
|
34
34
|
def create_object_directory
|
35
35
|
FileUtils.mkdir_p(object_root)
|
36
|
+
FileUtils.touch(object_directory.namaste_file) unless File.exist?(object_directory.namaste_file)
|
36
37
|
end
|
37
38
|
|
38
39
|
# @return [Directory]
|
39
40
|
def save
|
40
|
-
|
41
|
-
FileUtils.touch(object_directory.namaste_file)
|
41
|
+
create_object_directory
|
42
42
|
write_inventory
|
43
43
|
object_directory
|
44
44
|
end
|
@@ -17,6 +17,8 @@ module OCFL
|
|
17
17
|
|
18
18
|
attr_reader :object_directory, :manifest, :state, :version_number
|
19
19
|
|
20
|
+
delegate :file_names, to: :to_version_struct
|
21
|
+
|
20
22
|
def move_file(incoming_path)
|
21
23
|
prepare_content_directory
|
22
24
|
add(incoming_path)
|
@@ -25,7 +27,24 @@ module OCFL
|
|
25
27
|
|
26
28
|
def copy_file(incoming_path, destination_path: "")
|
27
29
|
prepare_content_directory
|
28
|
-
copy_one(File.basename(incoming_path), incoming_path
|
30
|
+
copy_one(destination_path.presence || File.basename(incoming_path), incoming_path)
|
31
|
+
end
|
32
|
+
|
33
|
+
def digest_for_filename(filename)
|
34
|
+
state.find { |_, filenames| filenames.include?(filename) }&.first
|
35
|
+
end
|
36
|
+
|
37
|
+
# Note, this only removes the file from this version. Previous versions may still use it.
|
38
|
+
def delete_file(filename)
|
39
|
+
sha512_digest = digest_for_filename(filename)
|
40
|
+
raise "Unknown file: #{filename}" unless sha512_digest
|
41
|
+
|
42
|
+
state.delete(sha512_digest)
|
43
|
+
# If the manifest points at the current content directory, then we can delete it.
|
44
|
+
file_paths = manifest[sha512_digest]
|
45
|
+
return unless file_paths.all? { |path| path.start_with?("#{version_number}/") }
|
46
|
+
|
47
|
+
File.unlink (object_directory.object_root + file_paths.first).to_s
|
29
48
|
end
|
30
49
|
|
31
50
|
# Copies files into the object and preserves their relative paths as logical directories in the object
|
@@ -33,7 +52,10 @@ module OCFL
|
|
33
52
|
prepare_content_directory
|
34
53
|
incoming_path = incoming_path.delete_suffix("/")
|
35
54
|
Dir.glob("#{incoming_path}/**/*").reject { |fn| File.directory?(fn) }.each do |file|
|
36
|
-
|
55
|
+
logical_file_path = file.delete_prefix(incoming_path).delete_prefix("/")
|
56
|
+
logical_file_path = File.join(destination_path, logical_file_path) unless destination_path.empty?
|
57
|
+
|
58
|
+
copy_one(logical_file_path, file)
|
37
59
|
end
|
38
60
|
end
|
39
61
|
|
@@ -43,6 +65,10 @@ module OCFL
|
|
43
65
|
object_directory.reload
|
44
66
|
end
|
45
67
|
|
68
|
+
def to_version_struct
|
69
|
+
Version.new(state:, created: Time.now.utc.iso8601)
|
70
|
+
end
|
71
|
+
|
46
72
|
private
|
47
73
|
|
48
74
|
def write_inventory(inventory)
|
@@ -51,8 +77,9 @@ module OCFL
|
|
51
77
|
FileUtils.cp(path / "inventory.json.sha512", object_directory.object_root)
|
52
78
|
end
|
53
79
|
|
54
|
-
|
55
|
-
|
80
|
+
# @param [String] logical_file_path where we're going to store the file (e.g. 'object/directory_builder_spec.rb')
|
81
|
+
# @param [String] incoming_path where's this file from (e.g. 'spec/ocfl/object/directory_builder_spec.rb')
|
82
|
+
def copy_one(logical_file_path, incoming_path)
|
56
83
|
add(incoming_path, logical_file_path:)
|
57
84
|
parent_dir = (content_path / logical_file_path).parent
|
58
85
|
FileUtils.mkdir_p(parent_dir) unless parent_dir == content_path
|
@@ -93,8 +120,8 @@ module OCFL
|
|
93
120
|
def build_inventory
|
94
121
|
old_data = object_directory.inventory.data
|
95
122
|
versions = versions(old_data.versions)
|
96
|
-
# Prune items from manifest if they are not part of any version
|
97
123
|
|
124
|
+
# Prune items from manifest if they are not part of any version
|
98
125
|
Inventory::InventoryStruct.new(old_data.to_h.merge(manifest: filtered_manifest(versions),
|
99
126
|
head: version_number, versions:))
|
100
127
|
end
|
@@ -102,13 +129,14 @@ module OCFL
|
|
102
129
|
# This gives the update list of versions. The old list plus this new one.
|
103
130
|
# @param [Hash] old_versions the versions prior to this one.
|
104
131
|
def versions(old_versions)
|
105
|
-
old_versions.merge(version_number =>
|
132
|
+
old_versions.merge(version_number => to_version_struct)
|
106
133
|
end
|
107
134
|
|
108
135
|
# The manifest after unused SHAs have been filtered out.
|
109
136
|
def filtered_manifest(versions)
|
110
137
|
shas_in_versions = versions.values.flat_map { |v| v.state.keys }.uniq
|
111
|
-
manifest.slice(*shas_in_versions)
|
138
|
+
manifest.slice!(*shas_in_versions)
|
139
|
+
manifest
|
112
140
|
end
|
113
141
|
end
|
114
142
|
end
|
data/lib/ocfl/version.rb
CHANGED
data/lib/ocfl.rb
CHANGED
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.8.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-
|
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.
|
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)
|