ro-crate 0.4.1 → 0.4.6
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/.ruby-version +1 -1
- data/Gemfile.lock +1 -1
- data/README.md +11 -7
- data/lib/ro_crate/json_ld_hash.rb +1 -1
- data/lib/ro_crate/model/contextual_entity.rb +1 -1
- data/lib/ro_crate/model/crate.rb +54 -15
- data/lib/ro_crate/model/data_entity.rb +1 -1
- data/lib/ro_crate/model/directory.rb +39 -11
- data/lib/ro_crate/model/entity.rb +3 -3
- data/lib/ro_crate/model/entry.rb +1 -1
- data/lib/ro_crate/model/file.rb +5 -3
- data/lib/ro_crate/model/remote_entry.rb +1 -1
- data/lib/ro_crate/reader.rb +18 -15
- data/lib/ro_crate/ro-crate-preview.html.erb +3 -3
- data/lib/ro_crate/writer.rb +3 -3
- data/ro_crate.gemspec +2 -2
- data/test/crate_test.rb +95 -0
- data/test/fixtures/directory.zip +0 -0
- data/test/fixtures/directory/.dir/test.txt +1 -0
- data/test/fixtures/directory/.dotfile +1 -0
- data/test/fixtures/directory_crate/ro-crate-metadata.jsonld +7 -0
- data/test/fixtures/directory_crate/ro-crate-preview.html +66 -0
- data/test/fixtures/sparse_directory_crate.zip +0 -0
- data/test/fixtures/sparse_directory_crate/fish/data/binary.jpg +0 -0
- data/test/fixtures/sparse_directory_crate/fish/data/info.txt +1 -0
- data/test/fixtures/sparse_directory_crate/fish/data/nested.txt +1 -0
- data/test/fixtures/sparse_directory_crate/fish/info.txt +1 -0
- data/test/fixtures/sparse_directory_crate/fish/root.txt +1 -0
- data/test/fixtures/sparse_directory_crate/listed_file.txt +1 -0
- data/test/fixtures/sparse_directory_crate/ro-crate-metadata.jsonld +32 -0
- data/test/fixtures/sparse_directory_crate/ro-crate-preview.html +66 -0
- data/test/fixtures/sparse_directory_crate/unlisted_file.txt +1 -0
- data/test/reader_test.rb +36 -2
- data/test/writer_test.rb +33 -0
- metadata +16 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4880110308b68d8bc35333b1fc8a8396ea30e36069f92e059b8c57ec3567d33e
|
4
|
+
data.tar.gz: 77a17a0436f2dea14254a3501f9db349eed5460851d94ab4e87adb7be83e1b38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 711a45d7aaa63f8a5a7bba78e433d82875311472d6f4abfd6d388dd8565a7707036152c81de4059fd92da5b7851925caf9d808f39d115752e68eaddbdc85bac1
|
7
|
+
data.tar.gz: ce14efaf63e7224adc79cdb11d27bdec933be290ccf60196014cb7ce9380136451265a8f814e1ca7b70286fc32852024d429334bbaab18208d31095cd619dc9e
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.
|
1
|
+
ruby-2.6.6
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# ro-crate-ruby
|
2
2
|
|
3
|
-
This is a WIP gem for creating, manipulating and reading RO
|
3
|
+
This is a WIP gem for creating, manipulating and reading RO-Crates (conforming to version 1.1 of the specification).
|
4
4
|
|
5
|
-
* RO
|
6
|
-
* RO
|
5
|
+
* RO-Crate - https://researchobject.github.io/ro-crate/
|
6
|
+
* RO-Crate spec (1.1) - https://researchobject.github.io/ro-crate/1.1/
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
@@ -31,13 +31,17 @@ crate = ROCrate::Crate.new
|
|
31
31
|
crate.add_file(File.open('Gemfile')) # Using IO-like objects
|
32
32
|
crate.add_file('README.md') # or paths
|
33
33
|
|
34
|
+
# Quickly add everything from a directory into the crate
|
35
|
+
crate = ROCrate::Crate.new
|
36
|
+
crate.add_all('workspace/secret_project/dataset123')
|
37
|
+
|
34
38
|
# Write to a zip file
|
35
39
|
ROCrate::Writer.new(crate).write_zip(File.new('ro_crate.zip', 'w'))
|
36
40
|
|
37
41
|
# Write to a directory
|
38
42
|
ROCrate::Writer.new(crate).write('./ro_crate_stuff')
|
39
43
|
|
40
|
-
# Read an RO
|
44
|
+
# Read an RO-Crate
|
41
45
|
crate = ROCrate::Reader.read('./an_ro_crate_directory')
|
42
46
|
|
43
47
|
# Make some changes
|
@@ -55,9 +59,9 @@ ext_file = crate.add_external_file('https://example.com/my_file.txt')
|
|
55
59
|
ROCrate::Writer.new(crate).write('./an_ro_crate_directory')
|
56
60
|
```
|
57
61
|
|
58
|
-
### RO
|
59
|
-
A simple HTML preview page is generated when an RO
|
60
|
-
metadata. This preview is written to `ro-crate-preview.html` at the root of the RO
|
62
|
+
### RO-Crate Preview
|
63
|
+
A simple HTML preview page is generated when an RO-Crate is written, containing a list of the crate's contents and some
|
64
|
+
metadata. This preview is written to `ro-crate-preview.html` at the root of the RO-Crate.
|
61
65
|
|
62
66
|
The default template can be seen here [here](lib/ro_crate/ro-crate-preview.html.erb).
|
63
67
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ROCrate
|
2
2
|
##
|
3
|
-
# A wrapper class for Hash that adds methods to dereference Entities within an RO
|
3
|
+
# A wrapper class for Hash that adds methods to dereference Entities within an RO-Crate.
|
4
4
|
class JSONLDHash < ::Hash
|
5
5
|
def initialize(graph, content = {})
|
6
6
|
@graph = graph
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ROCrate
|
2
2
|
##
|
3
|
-
# A class to represent a "Contextual Entity" within an RO
|
3
|
+
# A class to represent a "Contextual Entity" within an RO-Crate.
|
4
4
|
# Contextual Entities are used to describe and provide context to the Data Entities within the crate.
|
5
5
|
class ContextualEntity < Entity
|
6
6
|
def self.format_id(id)
|
data/lib/ro_crate/model/crate.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module ROCrate
|
2
2
|
##
|
3
|
-
# A Ruby abstraction of an RO
|
3
|
+
# A Ruby abstraction of an RO-Crate.
|
4
4
|
class Crate < Directory
|
5
5
|
IDENTIFIER = './'.freeze
|
6
6
|
attr_reader :data_entities
|
@@ -13,7 +13,7 @@ module ROCrate
|
|
13
13
|
end
|
14
14
|
|
15
15
|
##
|
16
|
-
# Initialize an empty RO
|
16
|
+
# Initialize an empty RO-Crate.
|
17
17
|
def initialize(id = IDENTIFIER, properties = {})
|
18
18
|
@data_entities = []
|
19
19
|
@contextual_entities = []
|
@@ -24,7 +24,7 @@ module ROCrate
|
|
24
24
|
# Create a new file and add it to the crate.
|
25
25
|
#
|
26
26
|
# @param source [String, Pathname, ::File, #read, nil] The source on the disk where this file will be read.
|
27
|
-
# @param crate_path [String] The relative path within the RO
|
27
|
+
# @param crate_path [String] The relative path within the RO-Crate where this file will be written.
|
28
28
|
# @param entity_class [Class] The class to use to instantiate the Entity,
|
29
29
|
# useful if you have created a subclass of ROCrate::File that you want to use. (defaults to ROCrate::File).
|
30
30
|
# @param properties [Hash{String => Object}] A hash of JSON-LD properties to associate with this file.
|
@@ -51,7 +51,7 @@ module ROCrate
|
|
51
51
|
# Create a new directory and add it to the crate.
|
52
52
|
#
|
53
53
|
# @param source_directory [String, Pathname, ::File, #read, nil] The source directory that will be included in the crate.
|
54
|
-
# @param crate_path [String] The relative path within the RO
|
54
|
+
# @param crate_path [String] The relative path within the RO-Crate where this directory will be written.
|
55
55
|
# @param entity_class [Class] The class to use to instantiate the Entity,
|
56
56
|
# useful if you have created a subclass of ROCrate::Directory that you want to use. (defaults to ROCrate::Directory).
|
57
57
|
# @param properties [Hash{String => Object}] A hash of JSON-LD properties to associate with this directory.
|
@@ -61,6 +61,35 @@ module ROCrate
|
|
61
61
|
entity_class.new(self, source_directory, crate_path, properties).tap { |e| add_data_entity(e) }
|
62
62
|
end
|
63
63
|
|
64
|
+
##
|
65
|
+
# Recursively add the contents of the given source directory at the root of the crate.
|
66
|
+
# Useful for quickly RO-Crate-ifying a directory.
|
67
|
+
# Creates data entities for each file/directory discovered (excluding the top level directory itself) if `create_entities` is true.
|
68
|
+
#
|
69
|
+
# @param source_directory [String, Pathname, ::File,] The source directory that will be included in the crate.
|
70
|
+
# @param create_entities [Boolean] Whether to create data entities for the added content, or just include them anonymously.
|
71
|
+
# @param include_hidden [Boolean] Whether to include hidden files, i.e. those prefixed by a `.` (period).
|
72
|
+
#
|
73
|
+
# @return [Array<DataEntity>] Any entities that were created from the directory contents. Will be empty if `create_entities` was false.
|
74
|
+
def add_all(source_directory, create_entities = true, include_hidden: false)
|
75
|
+
added = []
|
76
|
+
|
77
|
+
if create_entities
|
78
|
+
list_all_files(source_directory, include_hidden: include_hidden).each do |rel_path|
|
79
|
+
source_path = Pathname.new(::File.join(source_directory, rel_path)).expand_path
|
80
|
+
if source_path.directory?
|
81
|
+
added << add_directory(source_path, rel_path)
|
82
|
+
else
|
83
|
+
added << add_file(source_path, rel_path)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
else
|
87
|
+
populate_entries(Pathname.new(::File.expand_path(source_directory)), include_hidden: include_hidden)
|
88
|
+
end
|
89
|
+
|
90
|
+
added
|
91
|
+
end
|
92
|
+
|
64
93
|
##
|
65
94
|
# Create a new ROCrate::Person and add it to the crate
|
66
95
|
#
|
@@ -119,7 +148,7 @@ module ROCrate
|
|
119
148
|
end
|
120
149
|
|
121
150
|
##
|
122
|
-
# The RO
|
151
|
+
# The RO-Crate metadata file
|
123
152
|
#
|
124
153
|
# @return [Metadata]
|
125
154
|
def metadata
|
@@ -127,7 +156,7 @@ module ROCrate
|
|
127
156
|
end
|
128
157
|
|
129
158
|
##
|
130
|
-
# The RO
|
159
|
+
# The RO-Crate preview file
|
131
160
|
#
|
132
161
|
# @return [Preview]
|
133
162
|
def preview
|
@@ -143,7 +172,7 @@ module ROCrate
|
|
143
172
|
end
|
144
173
|
|
145
174
|
##
|
146
|
-
# Entities for the metadata file and crate itself, which should be present in all RO
|
175
|
+
# Entities for the metadata file and crate itself, which should be present in all RO-Crates.
|
147
176
|
#
|
148
177
|
# @return [Array<Entity>]
|
149
178
|
def default_entities
|
@@ -186,18 +215,22 @@ module ROCrate
|
|
186
215
|
entity.class.new(crate, entity.id, entity.raw_properties)
|
187
216
|
end
|
188
217
|
|
218
|
+
alias_method :own_entries, :entries
|
189
219
|
##
|
190
|
-
#
|
191
|
-
# and the value is an Entry where the source data can be read.
|
220
|
+
# # The RO-Crate's "payload" of the crate - a map of all the files/directories contained in the RO-Crate, where the
|
221
|
+
# key is the destination path within the crate and the value is an Entry where the source data can be read.
|
192
222
|
#
|
193
223
|
# @return [Hash{String => Entry}>]
|
194
224
|
def entries
|
195
|
-
entries
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
225
|
+
# Gather a map of entries, starting from the crate itself, then any directory data entities, then finally any
|
226
|
+
# file data entities. This ensures in the case of a conflict, the more "specific" data entities take priority.
|
227
|
+
entries = own_entries
|
228
|
+
non_self_entities = default_entities.reject { |e| e == self }
|
229
|
+
sorted_entities = (non_self_entities | data_entities).sort_by { |e| e.is_a?(ROCrate::Directory) ? 0 : 1 }
|
230
|
+
|
231
|
+
sorted_entities.each do |entity|
|
232
|
+
entity.entries.each do |path, entry|
|
233
|
+
entries[path] = entry
|
201
234
|
end
|
202
235
|
end
|
203
236
|
|
@@ -207,5 +240,11 @@ module ROCrate
|
|
207
240
|
def get_binding
|
208
241
|
binding
|
209
242
|
end
|
243
|
+
|
244
|
+
private
|
245
|
+
|
246
|
+
def full_entry_path(relative_path)
|
247
|
+
relative_path
|
248
|
+
end
|
210
249
|
end
|
211
250
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ROCrate
|
2
2
|
##
|
3
|
-
# A class to represent a "Data Entity" within an RO
|
3
|
+
# A class to represent a "Data Entity" within an RO-Crate.
|
4
4
|
# Data Entities are the actual physical files and directories within the Crate.
|
5
5
|
class DataEntity < Entity
|
6
6
|
def self.format_id(id)
|
@@ -12,37 +12,34 @@ module ROCrate
|
|
12
12
|
# Create a new Directory. PLEASE NOTE, the new directory will not be added to the crate. To do this, call
|
13
13
|
# Crate#add_data_entity, or just use Crate#add_directory.
|
14
14
|
#
|
15
|
-
# @param crate [Crate] The RO
|
15
|
+
# @param crate [Crate] The RO-Crate that owns this directory.
|
16
16
|
# @param source_directory [String, Pathname, ::File, nil] The source directory that will be included in the crate.
|
17
|
-
# @param crate_path [String] The relative path within the RO
|
17
|
+
# @param crate_path [String] The relative path within the RO-Crate where this directory will be written.
|
18
18
|
# @param properties [Hash{String => Object}] A hash of JSON-LD properties to associate with this directory.
|
19
19
|
def initialize(crate, source_directory = nil, crate_path = nil, properties = {})
|
20
20
|
@directory_entries = {}
|
21
21
|
|
22
22
|
if source_directory
|
23
|
-
raise 'Not a directory' unless ::File.directory?(source_directory)
|
24
23
|
source_directory = Pathname.new(::File.expand_path(source_directory))
|
24
|
+
@entry = Entry.new(source_directory)
|
25
|
+
populate_entries(source_directory)
|
25
26
|
crate_path = source_directory.basename.to_s if crate_path.nil?
|
26
|
-
|
27
|
-
Dir.chdir(source_directory) { Dir.glob('**/*') }.each do |rel_path|
|
28
|
-
source_path = Pathname.new(::File.join(source_directory, rel_path)).expand_path
|
29
|
-
@directory_entries[rel_path] = Entry.new(source_path)
|
30
|
-
end
|
31
27
|
end
|
32
28
|
|
33
29
|
super(crate, crate_path, properties)
|
34
30
|
end
|
35
31
|
|
36
32
|
##
|
37
|
-
#
|
38
|
-
# and the value is an Entry where the source data can be read.
|
33
|
+
# The "payload" of this directory - a map of all the files/directories, where the key is the destination path
|
34
|
+
# within the crate and the value is an Entry where the source data can be read.
|
39
35
|
#
|
40
36
|
# @return [Hash{String => Entry}>]
|
41
37
|
def entries
|
42
38
|
entries = {}
|
39
|
+
entries[filepath.chomp('/')] = @entry if @entry
|
43
40
|
|
44
41
|
@directory_entries.each do |rel_path, entry|
|
45
|
-
entries[
|
42
|
+
entries[full_entry_path(rel_path)] = entry
|
46
43
|
end
|
47
44
|
|
48
45
|
entries
|
@@ -50,6 +47,37 @@ module ROCrate
|
|
50
47
|
|
51
48
|
private
|
52
49
|
|
50
|
+
##
|
51
|
+
# Populate this directory with files/directories from a given source directory on disk.
|
52
|
+
#
|
53
|
+
# @param source_directory [Pathname] The source directory to populate from.
|
54
|
+
# @param include_hidden [Boolean] Whether to include hidden files, i.e. those prefixed by a `.` (period).
|
55
|
+
#
|
56
|
+
# @return [Hash{String => Entry}>] The files/directories that were populated.
|
57
|
+
# The key is the relative path of the file/directory, and the value is an Entry object where data can be read etc.
|
58
|
+
def populate_entries(source_directory, include_hidden: false)
|
59
|
+
raise 'Not a directory' unless ::File.directory?(source_directory)
|
60
|
+
@directory_entries = {}
|
61
|
+
list_all_files(source_directory, include_hidden: include_hidden).each do |rel_path|
|
62
|
+
source_path = Pathname.new(::File.join(source_directory, rel_path)).expand_path
|
63
|
+
@directory_entries[rel_path] = Entry.new(source_path)
|
64
|
+
end
|
65
|
+
|
66
|
+
@directory_entries
|
67
|
+
end
|
68
|
+
|
69
|
+
def full_entry_path(relative_path)
|
70
|
+
::File.join(filepath, relative_path)
|
71
|
+
end
|
72
|
+
|
73
|
+
def list_all_files(source_directory, include_hidden: false)
|
74
|
+
args = ['**/*']
|
75
|
+
args << ::File::FNM_DOTMATCH if include_hidden
|
76
|
+
Dir.chdir(source_directory) { Dir.glob(*args) }.reject do |path|
|
77
|
+
path == '.' || path == '..' || path.end_with?('/.')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
53
81
|
def default_properties
|
54
82
|
super.merge(
|
55
83
|
'@id' => "#{SecureRandom.uuid}/",
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ROCrate
|
2
2
|
##
|
3
|
-
# A generic "Entity" within an RO
|
4
|
-
# RO
|
3
|
+
# A generic "Entity" within an RO-Crate. It has an identifier and a set of properties, and will be referenced in the
|
4
|
+
# RO-Crate Metadata's @graph.
|
5
5
|
class Entity
|
6
6
|
attr_reader :crate
|
7
7
|
attr_reader :properties
|
@@ -60,7 +60,7 @@ module ROCrate
|
|
60
60
|
##
|
61
61
|
# Automatically replace an Entity or Array of Entities with a reference or Array of references. Also associates
|
62
62
|
# the Entity/Entities with the current crate. This is useful for maintaining the flat @graph of entities that the
|
63
|
-
# RO
|
63
|
+
# RO-Crate metadata file requires.
|
64
64
|
#
|
65
65
|
# @param value [Entity, Array<Entity>, Object] A value that may be reference or array of references.
|
66
66
|
# @return [Hash, Array<Hash>, Object] Return a reference, Array of references, or just the object itself if
|
data/lib/ro_crate/model/entry.rb
CHANGED
data/lib/ro_crate/model/file.rb
CHANGED
@@ -8,9 +8,9 @@ module ROCrate
|
|
8
8
|
# Create a new ROCrate::File. PLEASE NOTE, the new file will not be added to the crate. To do this, call
|
9
9
|
# Crate#add_data_entity, or just use Crate#add_file.
|
10
10
|
#
|
11
|
-
# @param crate [Crate] The RO
|
11
|
+
# @param crate [Crate] The RO-Crate that owns this file.
|
12
12
|
# @param source [String, Pathname, ::File, #read, URI, nil] The source on the disk (or on the internet if a URI) where this file will be read.
|
13
|
-
# @param crate_path [String] The relative path within the RO
|
13
|
+
# @param crate_path [String] The relative path within the RO-Crate where this file will be written.
|
14
14
|
# @param properties [Hash{String => Object}] A hash of JSON-LD properties to associate with this file.
|
15
15
|
def initialize(crate, source, crate_path = nil, properties = {})
|
16
16
|
if crate_path.is_a?(Hash) && properties.empty?
|
@@ -52,7 +52,9 @@ module ROCrate
|
|
52
52
|
end
|
53
53
|
|
54
54
|
##
|
55
|
-
# A map
|
55
|
+
# The "payload". A map with a single key and value, of the relative filepath within the crate, to the source on disk
|
56
|
+
# where the actual bytes of the file can be read. Blank if remote.
|
57
|
+
#
|
56
58
|
# (for compatibility with Directory#entries)
|
57
59
|
#
|
58
60
|
# @return [Hash{String => Entry}>] The key is the location within the crate, and the value is an Entry.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ROCrate
|
2
2
|
##
|
3
|
-
# A class to represent a reference within an RO
|
3
|
+
# A class to represent a reference within an RO-Crate, to a remote file held on the internet somewhere.
|
4
4
|
# It handles the actual reading/writing of bytes.
|
5
5
|
class RemoteEntry
|
6
6
|
attr_reader :uri
|
data/lib/ro_crate/reader.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
module ROCrate
|
2
2
|
##
|
3
|
-
# A class to handle reading of RO
|
3
|
+
# A class to handle reading of RO-Crates from Zip files or directories.
|
4
4
|
class Reader
|
5
5
|
##
|
6
|
-
# Reads an RO
|
6
|
+
# Reads an RO-Crate from a directory of zip file.
|
7
7
|
#
|
8
8
|
# @param source [String, ::File, Pathname] The source location for the crate.
|
9
9
|
# @param target_dir [String, ::File, Pathname] The target directory where the crate should be unzipped (if its a Zip file).
|
10
|
-
# @return [Crate] The RO
|
10
|
+
# @return [Crate] The RO-Crate.
|
11
11
|
def self.read(source, target_dir: Dir.mktmpdir)
|
12
12
|
raise "Not a directory!" unless ::File.directory?(target_dir)
|
13
13
|
if ::File.directory?(source)
|
@@ -37,12 +37,12 @@ module ROCrate
|
|
37
37
|
end
|
38
38
|
|
39
39
|
##
|
40
|
-
# Reads an RO
|
40
|
+
# Reads an RO-Crate from a zip file. It first extracts the Zip file to a temporary directory, and then calls
|
41
41
|
# #read_directory.
|
42
42
|
#
|
43
43
|
# @param source [String, ::File, Pathname] The location of the zip file.
|
44
44
|
# @param target_dir [String, ::File, Pathname] The target directory where the crate should be unzipped.
|
45
|
-
# @return [Crate] The RO
|
45
|
+
# @return [Crate] The RO-Crate.
|
46
46
|
def self.read_zip(source, target_dir: Dir.mktmpdir)
|
47
47
|
unzip_to(source, target_dir)
|
48
48
|
|
@@ -50,10 +50,10 @@ module ROCrate
|
|
50
50
|
end
|
51
51
|
|
52
52
|
##
|
53
|
-
# Reads an RO
|
53
|
+
# Reads an RO-Crate from a directory.
|
54
54
|
#
|
55
55
|
# @param source [String, ::File, Pathname] The location of the directory.
|
56
|
-
# @return [Crate] The RO
|
56
|
+
# @return [Crate] The RO-Crate.
|
57
57
|
def self.read_directory(source)
|
58
58
|
source = ::File.expand_path(source)
|
59
59
|
metadata_file = Dir.entries(source).detect { |entry| entry == ROCrate::Metadata::IDENTIFIER ||
|
@@ -68,7 +68,7 @@ module ROCrate
|
|
68
68
|
end
|
69
69
|
|
70
70
|
##
|
71
|
-
# Extracts all the entities from the @graph of the RO
|
71
|
+
# Extracts all the entities from the @graph of the RO-Crate Metadata.
|
72
72
|
#
|
73
73
|
# @param metadata_json [String] A string containing the metadata JSON.
|
74
74
|
# @return [Hash{String => Hash}] A Hash of all the entities, mapped by their @id.
|
@@ -99,12 +99,15 @@ module ROCrate
|
|
99
99
|
# Create a crate from the given set of entities.
|
100
100
|
#
|
101
101
|
# @param entity_hash [Hash{String => Hash}] A Hash containing all the entities in the @graph, mapped by their @id.
|
102
|
-
# @param source [String, ::File, Pathname] The location of the RO
|
103
|
-
# @return [Crate] The RO
|
102
|
+
# @param source [String, ::File, Pathname] The location of the RO-Crate being read.
|
103
|
+
# @return [Crate] The RO-Crate.
|
104
104
|
def self.build_crate(entity_hash, source)
|
105
105
|
ROCrate::Crate.new.tap do |crate|
|
106
106
|
crate.properties = entity_hash.delete(ROCrate::Crate::IDENTIFIER)
|
107
107
|
crate.metadata.properties = entity_hash.delete(ROCrate::Metadata::IDENTIFIER)
|
108
|
+
preview_properties = entity_hash.delete(ROCrate::Preview::IDENTIFIER)
|
109
|
+
crate.preview.properties = preview_properties if preview_properties
|
110
|
+
crate.add_all(source, false)
|
108
111
|
extract_data_entities(crate, source, entity_hash).each do |entity|
|
109
112
|
crate.add_data_entity(entity)
|
110
113
|
end
|
@@ -118,8 +121,8 @@ module ROCrate
|
|
118
121
|
##
|
119
122
|
# Discover data entities from the `hasPart` property of a crate, and create DataEntity objects for them.
|
120
123
|
# Entities are looked up in the given `entity_hash` (and then removed from it).
|
121
|
-
# @param crate [Crate] The RO
|
122
|
-
# @param source [String, ::File, Pathname] The location of the RO
|
124
|
+
# @param crate [Crate] The RO-Crate being read.
|
125
|
+
# @param source [String, ::File, Pathname] The location of the RO-Crate being read.
|
123
126
|
# @param entity_hash [Hash] A Hash containing all the entities in the @graph, mapped by their @id.
|
124
127
|
# @return [Array<ROCrate::File, ROCrate::Directory>] The extracted DataEntity objects.
|
125
128
|
def self.extract_data_entities(crate, source, entity_hash)
|
@@ -135,7 +138,7 @@ module ROCrate
|
|
135
138
|
|
136
139
|
##
|
137
140
|
# Create appropriately specialized ContextualEntity objects from the given hash of entities and their properties.
|
138
|
-
# @param crate [Crate] The RO
|
141
|
+
# @param crate [Crate] The RO-Crate being read.
|
139
142
|
# @param entity_hash [Hash] A Hash containing all the entities in the @graph, mapped by their @id.
|
140
143
|
# @return [Array<ContextualEntity>] The extracted ContextualEntity objects.
|
141
144
|
def self.extract_contextual_entities(crate, entity_hash)
|
@@ -152,8 +155,8 @@ module ROCrate
|
|
152
155
|
|
153
156
|
##
|
154
157
|
# Create a DataEntity of the given class.
|
155
|
-
# @param crate [Crate] The RO
|
156
|
-
# @param source [String, ::File, Pathname] The location of the RO
|
158
|
+
# @param crate [Crate] The RO-Crate being read.
|
159
|
+
# @param source [String, ::File, Pathname] The location of the RO-Crate being read.
|
157
160
|
# @param entity_props [Hash] A Hash containing the entity's properties, including its @id.
|
158
161
|
# @return [ROCrate::File, ROCrate::Directory, nil] The DataEntity object,
|
159
162
|
# or nil if it referenced a local file that wasn't found.
|
@@ -1,13 +1,13 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
3
|
<head>
|
4
|
-
<title><%= name || "New RO
|
4
|
+
<title><%= name || "New RO-Crate" %></title>
|
5
5
|
<script type="application/ld+json"><%= metadata.generate %></script>
|
6
6
|
<meta name="generator" content="https://github.com/fbacall/ro-crate-ruby">
|
7
|
-
<meta name="keywords" content="RO
|
7
|
+
<meta name="keywords" content="RO-Crate">
|
8
8
|
</head>
|
9
9
|
<body>
|
10
|
-
<h1><%= name || "New RO
|
10
|
+
<h1><%= name || "New RO-Crate" %></h1>
|
11
11
|
<% if url %>
|
12
12
|
<a href="<%= url %>" target="_blank"><%= url %></a>
|
13
13
|
<% end %>
|
data/lib/ro_crate/writer.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
module ROCrate
|
2
2
|
##
|
3
|
-
# A class to handle writing of RO
|
3
|
+
# A class to handle writing of RO-Crates to Zip files or directories.
|
4
4
|
class Writer
|
5
5
|
##
|
6
6
|
# Initialize a new Writer for the given Crate.
|
7
|
-
# @param crate [Crate] The RO
|
7
|
+
# @param crate [Crate] The RO-Crate to be written.
|
8
8
|
def initialize(crate)
|
9
9
|
@crate = crate
|
10
10
|
end
|
@@ -35,7 +35,7 @@ module ROCrate
|
|
35
35
|
##
|
36
36
|
# Write the crate to a zip file.
|
37
37
|
#
|
38
|
-
# @param destination [String, ::File] The destination where to write the RO
|
38
|
+
# @param destination [String, ::File] The destination where to write the RO-Crate zip.
|
39
39
|
def write_zip(destination)
|
40
40
|
Zip::File.open(destination, Zip::File::CREATE) do |zip|
|
41
41
|
@crate.entries.each do |path, entry|
|
data/ro_crate.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'ro-crate'
|
3
|
-
s.version = '0.4.
|
4
|
-
s.summary = 'Create, manipulate, read RO
|
3
|
+
s.version = '0.4.6'
|
4
|
+
s.summary = 'Create, manipulate, read RO-Crates.'
|
5
5
|
s.authors = ['Finn Bacall']
|
6
6
|
s.email = 'finn.bacall@manchester.ac.uk'
|
7
7
|
s.files = `git ls-files`.split("\n")
|
data/test/crate_test.rb
CHANGED
@@ -198,4 +198,99 @@ class CrateTest < Test::Unit::TestCase
|
|
198
198
|
assert_equal file, new_crate.get('some/file.txt')
|
199
199
|
assert_equal file, new_crate.get('http://mycoolwebsite.golf/ro_crate/some/file.txt')
|
200
200
|
end
|
201
|
+
|
202
|
+
test 'can add an entire directory tree as data entities' do
|
203
|
+
crate = ROCrate::Crate.new
|
204
|
+
entities = crate.add_all(fixture_file('directory').path, include_hidden: true)
|
205
|
+
|
206
|
+
paths = crate.entries.keys
|
207
|
+
assert_equal 11, paths.length
|
208
|
+
assert_includes paths, 'data'
|
209
|
+
assert_includes paths, 'root.txt'
|
210
|
+
assert_includes paths, 'info.txt'
|
211
|
+
assert_includes paths, 'data/binary.jpg'
|
212
|
+
assert_includes paths, 'data/info.txt'
|
213
|
+
assert_includes paths, 'data/nested.txt'
|
214
|
+
assert_includes paths, '.dotfile'
|
215
|
+
assert_includes paths, '.dir'
|
216
|
+
assert_includes paths, '.dir/test.txt'
|
217
|
+
assert_includes paths, 'ro-crate-metadata.json'
|
218
|
+
assert_includes paths, 'ro-crate-preview.html'
|
219
|
+
|
220
|
+
assert_equal 9, entities.length
|
221
|
+
assert_equal 'ROCrate::Directory', crate.dereference('data/').class.name
|
222
|
+
assert_equal 'ROCrate::File', crate.dereference('root.txt').class.name
|
223
|
+
assert_equal 'ROCrate::File', crate.dereference('info.txt').class.name
|
224
|
+
assert_equal 'ROCrate::File', crate.dereference('data/binary.jpg').class.name
|
225
|
+
assert_equal 'ROCrate::File', crate.dereference('data/info.txt').class.name
|
226
|
+
assert_equal 'ROCrate::File', crate.dereference('data/nested.txt').class.name
|
227
|
+
assert_equal 'ROCrate::File', crate.dereference('.dotfile').class.name
|
228
|
+
assert_equal 'ROCrate::Directory', crate.dereference('.dir/').class.name
|
229
|
+
assert_equal 'ROCrate::File', crate.dereference('.dir/test.txt').class.name
|
230
|
+
|
231
|
+
assert_equal "5678\n", crate.dereference('data/info.txt').source.read
|
232
|
+
assert_equal "Am I included?\n", crate.dereference('.dotfile').source.read
|
233
|
+
end
|
234
|
+
|
235
|
+
test 'can create an RO-Crate using content from a given directory' do
|
236
|
+
crate = ROCrate::Crate.new
|
237
|
+
entities = crate.add_all(fixture_file('directory').path, false, include_hidden: true)
|
238
|
+
|
239
|
+
assert_empty entities
|
240
|
+
|
241
|
+
paths = crate.entries.keys
|
242
|
+
assert_equal 11, paths.length
|
243
|
+
assert_includes paths, 'data'
|
244
|
+
assert_includes paths, 'root.txt'
|
245
|
+
assert_includes paths, 'info.txt'
|
246
|
+
assert_includes paths, 'data/binary.jpg'
|
247
|
+
assert_includes paths, 'data/info.txt'
|
248
|
+
assert_includes paths, 'data/nested.txt'
|
249
|
+
assert_includes paths, '.dotfile'
|
250
|
+
assert_includes paths, '.dir'
|
251
|
+
assert_includes paths, '.dir/test.txt'
|
252
|
+
assert_includes paths, 'ro-crate-metadata.json'
|
253
|
+
assert_includes paths, 'ro-crate-preview.html'
|
254
|
+
|
255
|
+
# Should not create any data entities
|
256
|
+
assert_nil crate.dereference('data/')
|
257
|
+
assert_nil crate.dereference('root.txt')
|
258
|
+
assert_nil crate.dereference('info.txt')
|
259
|
+
assert_nil crate.dereference('data/binary.jpg')
|
260
|
+
assert_nil crate.dereference('data/info.txt')
|
261
|
+
assert_nil crate.dereference('data/nested.txt')
|
262
|
+
assert_nil crate.dereference('.dotfile')
|
263
|
+
end
|
264
|
+
|
265
|
+
test 'can create an RO-Crate using content from a given directory, excluding hidden files' do
|
266
|
+
crate = ROCrate::Crate.new
|
267
|
+
entities = crate.add_all(fixture_file('directory').path)
|
268
|
+
|
269
|
+
paths = crate.entries.keys
|
270
|
+
assert_equal 8, paths.length
|
271
|
+
assert_includes paths, 'data'
|
272
|
+
assert_includes paths, 'root.txt'
|
273
|
+
assert_includes paths, 'info.txt'
|
274
|
+
assert_includes paths, 'data/binary.jpg'
|
275
|
+
assert_includes paths, 'data/info.txt'
|
276
|
+
assert_includes paths, 'data/nested.txt'
|
277
|
+
assert_not_includes paths, '.dotfile'
|
278
|
+
assert_not_includes paths, '.dir'
|
279
|
+
assert_not_includes paths, '.dir/test.txt'
|
280
|
+
assert_includes paths, 'ro-crate-metadata.json'
|
281
|
+
assert_includes paths, 'ro-crate-preview.html'
|
282
|
+
|
283
|
+
assert_equal 6, entities.length
|
284
|
+
assert_equal 'ROCrate::Directory', crate.dereference('data/').class.name
|
285
|
+
assert_equal 'ROCrate::File', crate.dereference('root.txt').class.name
|
286
|
+
assert_equal 'ROCrate::File', crate.dereference('info.txt').class.name
|
287
|
+
assert_equal 'ROCrate::File', crate.dereference('data/binary.jpg').class.name
|
288
|
+
assert_equal 'ROCrate::File', crate.dereference('data/info.txt').class.name
|
289
|
+
assert_equal 'ROCrate::File', crate.dereference('data/nested.txt').class.name
|
290
|
+
assert_nil crate.dereference('.dotfile')
|
291
|
+
assert_nil crate.dereference('.dir/')
|
292
|
+
assert_nil crate.dereference('.dir/test.txt')
|
293
|
+
|
294
|
+
assert_equal "5678\n", crate.dereference('data/info.txt').source.read
|
295
|
+
end
|
201
296
|
end
|
data/test/fixtures/directory.zip
CHANGED
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
123
|
@@ -0,0 +1 @@
|
|
1
|
+
Am I included?
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>New RO-Crate</title>
|
5
|
+
<script type="application/ld+json">{
|
6
|
+
"@context": "https://w3id.org/ro/crate/1.1/context",
|
7
|
+
"@graph": [
|
8
|
+
{
|
9
|
+
"@id": "ro-crate-metadata.jsonld",
|
10
|
+
"@type": "CreativeWork",
|
11
|
+
"about": {
|
12
|
+
"@id": "./"
|
13
|
+
}
|
14
|
+
},
|
15
|
+
{
|
16
|
+
"@id": "ro-crate-preview.html",
|
17
|
+
"@type": "CreativeWork",
|
18
|
+
"about": {
|
19
|
+
"@id": "./"
|
20
|
+
}
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"@id": "./",
|
24
|
+
"@type": "Dataset",
|
25
|
+
"hasPart": [
|
26
|
+
{
|
27
|
+
"@id": "fish/"
|
28
|
+
}
|
29
|
+
]
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"@id": "fish/",
|
33
|
+
"@type": "Dataset"
|
34
|
+
}
|
35
|
+
]
|
36
|
+
}</script>
|
37
|
+
<meta name="generator" content="https://github.com/fbacall/ro-crate-ruby">
|
38
|
+
<meta name="keywords" content="RO-Crate">
|
39
|
+
</head>
|
40
|
+
<body>
|
41
|
+
<h1>New RO-Crate</h1>
|
42
|
+
|
43
|
+
<p>
|
44
|
+
|
45
|
+
</p>
|
46
|
+
<dl>
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
</dl>
|
52
|
+
|
53
|
+
<h2>Contents</h2>
|
54
|
+
<ul>
|
55
|
+
|
56
|
+
<li id="__data_entity_fish/">
|
57
|
+
|
58
|
+
<strong>fish/</strong>
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
</li>
|
63
|
+
|
64
|
+
</ul>
|
65
|
+
</body>
|
66
|
+
</html>
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
5678
|
@@ -0,0 +1 @@
|
|
1
|
+
I'm nested
|
@@ -0,0 +1 @@
|
|
1
|
+
1234
|
@@ -0,0 +1 @@
|
|
1
|
+
I'm at the root
|
@@ -0,0 +1 @@
|
|
1
|
+
123
|
@@ -0,0 +1,32 @@
|
|
1
|
+
{
|
2
|
+
"@context": "https://w3id.org/ro/crate/1.0/context",
|
3
|
+
"@graph": [
|
4
|
+
{
|
5
|
+
"@id": "ro-crate-metadata.jsonld",
|
6
|
+
"@type": "CreativeWork",
|
7
|
+
"about": {
|
8
|
+
"@id": "./"
|
9
|
+
}
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"@id": "ro-crate-preview.html",
|
13
|
+
"@type": "CreativeWork",
|
14
|
+
"about": {
|
15
|
+
"@id": "./"
|
16
|
+
}
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"@id": "./",
|
20
|
+
"@type": "Dataset",
|
21
|
+
"hasPart": [
|
22
|
+
{
|
23
|
+
"@id": "listed_file.txt"
|
24
|
+
}
|
25
|
+
]
|
26
|
+
},
|
27
|
+
{
|
28
|
+
"@id": "listed_file.txt",
|
29
|
+
"@type": "File"
|
30
|
+
}
|
31
|
+
]
|
32
|
+
}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>New RO-Crate</title>
|
5
|
+
<script type="application/ld+json">{
|
6
|
+
"@context": "https://w3id.org/ro/crate/1.1/context",
|
7
|
+
"@graph": [
|
8
|
+
{
|
9
|
+
"@id": "ro-crate-metadata.jsonld",
|
10
|
+
"@type": "CreativeWork",
|
11
|
+
"about": {
|
12
|
+
"@id": "./"
|
13
|
+
}
|
14
|
+
},
|
15
|
+
{
|
16
|
+
"@id": "ro-crate-preview.html",
|
17
|
+
"@type": "CreativeWork",
|
18
|
+
"about": {
|
19
|
+
"@id": "./"
|
20
|
+
}
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"@id": "./",
|
24
|
+
"@type": "Dataset",
|
25
|
+
"hasPart": [
|
26
|
+
{
|
27
|
+
"@id": "fish/"
|
28
|
+
}
|
29
|
+
]
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"@id": "fish/",
|
33
|
+
"@type": "Dataset"
|
34
|
+
}
|
35
|
+
]
|
36
|
+
}</script>
|
37
|
+
<meta name="generator" content="https://github.com/fbacall/ro-crate-ruby">
|
38
|
+
<meta name="keywords" content="RO-Crate">
|
39
|
+
</head>
|
40
|
+
<body>
|
41
|
+
<h1>New RO-Crate</h1>
|
42
|
+
|
43
|
+
<p>
|
44
|
+
|
45
|
+
</p>
|
46
|
+
<dl>
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
</dl>
|
52
|
+
|
53
|
+
<h2>Contents</h2>
|
54
|
+
<ul>
|
55
|
+
|
56
|
+
<li id="__data_entity_fish/">
|
57
|
+
|
58
|
+
<strong>fish/</strong>
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
</li>
|
63
|
+
|
64
|
+
</ul>
|
65
|
+
</body>
|
66
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
456
|
data/test/reader_test.rb
CHANGED
@@ -109,11 +109,13 @@ class ReaderTest < Test::Unit::TestCase
|
|
109
109
|
test 'reading from directory with directories' do
|
110
110
|
crate = ROCrate::Reader.read_directory(fixture_file('directory_crate').path)
|
111
111
|
|
112
|
+
assert crate.entries.values.all? { |e| e.is_a?(ROCrate::Entry) }
|
112
113
|
assert crate.entries['fish/info.txt']
|
113
114
|
assert_equal '1234', crate.entries['fish/info.txt'].source.read.chomp
|
114
|
-
|
115
|
+
refute crate.entries['fish/root.txt'].directory?
|
116
|
+
assert crate.entries['fish/data'].directory?
|
115
117
|
assert crate.entries['fish/data/info.txt']
|
116
|
-
|
118
|
+
refute crate.entries['fish/data/nested.txt'].remote?
|
117
119
|
assert crate.entries['fish/data/binary.jpg']
|
118
120
|
assert_equal ['./', 'fish/', 'ro-crate-metadata.jsonld', 'ro-crate-preview.html'], crate.entities.map(&:id).sort
|
119
121
|
end
|
@@ -161,4 +163,36 @@ class ReaderTest < Test::Unit::TestCase
|
|
161
163
|
assert_equal 'http://example.com/external_ref.txt', ext_file.id
|
162
164
|
assert_equal 'file contents', ext_file.source.read
|
163
165
|
end
|
166
|
+
|
167
|
+
test 'reading from directory with unlisted files' do
|
168
|
+
crate = ROCrate::Reader.read_directory(fixture_file('sparse_directory_crate').path)
|
169
|
+
|
170
|
+
assert_equal 11, crate.entries.count
|
171
|
+
assert crate.entries['listed_file.txt']
|
172
|
+
assert crate.entries['unlisted_file.txt']
|
173
|
+
assert crate.entries['fish']
|
174
|
+
assert_equal '1234', crate.entries['fish/info.txt'].source.read.chomp
|
175
|
+
refute crate.entries['fish/root.txt'].directory?
|
176
|
+
assert crate.entries['fish/data'].directory?
|
177
|
+
assert crate.entries['fish/data/info.txt']
|
178
|
+
refute crate.entries['fish/data/nested.txt'].remote?
|
179
|
+
assert crate.entries['fish/data/binary.jpg']
|
180
|
+
assert_equal ['./', 'listed_file.txt', 'ro-crate-metadata.jsonld', 'ro-crate-preview.html'], crate.entities.map(&:id).sort
|
181
|
+
end
|
182
|
+
|
183
|
+
test 'reading from a zip with unlisted files' do
|
184
|
+
crate = ROCrate::Reader.read_zip(fixture_file('sparse_directory_crate.zip').path)
|
185
|
+
|
186
|
+
assert_equal 11, crate.entries.count
|
187
|
+
assert crate.entries['listed_file.txt']
|
188
|
+
assert crate.entries['unlisted_file.txt']
|
189
|
+
assert crate.entries['fish']
|
190
|
+
assert_equal '1234', crate.entries['fish/info.txt'].source.read.chomp
|
191
|
+
refute crate.entries['fish/root.txt'].directory?
|
192
|
+
assert crate.entries['fish/data'].directory?
|
193
|
+
assert crate.entries['fish/data/info.txt']
|
194
|
+
refute crate.entries['fish/data/nested.txt'].remote?
|
195
|
+
assert crate.entries['fish/data/binary.jpg']
|
196
|
+
assert_equal ['./', 'listed_file.txt', 'ro-crate-metadata.jsonld', 'ro-crate-preview.html'], crate.entities.map(&:id).sort
|
197
|
+
end
|
164
198
|
end
|
data/test/writer_test.rb
CHANGED
@@ -99,4 +99,37 @@ class WriterTest < Test::Unit::TestCase
|
|
99
99
|
end
|
100
100
|
end
|
101
101
|
end
|
102
|
+
|
103
|
+
test 'should write out same contents that it was created with' do
|
104
|
+
crate = ROCrate::Crate.new
|
105
|
+
crate.add_all(fixture_file('directory').path, false)
|
106
|
+
|
107
|
+
Dir.mktmpdir do |dir|
|
108
|
+
ROCrate::Writer.new(crate).write(dir)
|
109
|
+
assert ::File.exist?(::File.join(dir, ROCrate::Metadata::IDENTIFIER))
|
110
|
+
assert ::File.exist?(::File.join(dir, ROCrate::Preview::IDENTIFIER))
|
111
|
+
assert_equal 5, ::File.size(::File.join(dir, 'info.txt'))
|
112
|
+
assert_equal 2529, ::File.size(::File.join(dir, 'data', 'binary.jpg'))
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
test 'reading and writing out a directory crate produces an identical crate' do
|
117
|
+
fixture = fixture_file('sparse_directory_crate').path
|
118
|
+
Dir.mktmpdir do |dir|
|
119
|
+
dir = ::File.join(dir, 'new_directory')
|
120
|
+
crate = ROCrate::Reader.read(fixture)
|
121
|
+
|
122
|
+
ROCrate::Writer.new(crate).write(dir)
|
123
|
+
expected_files = Dir.chdir(fixture) { Dir.glob('**/*') }
|
124
|
+
actual_files = Dir.chdir(dir) { Dir.glob('**/*') }
|
125
|
+
assert_equal expected_files, actual_files
|
126
|
+
expected_files.each do |file|
|
127
|
+
next if file == 'ro-crate-metadata.jsonld' # Expected context gets updated.
|
128
|
+
next if file == 'ro-crate-preview.html' # RO-Crate preview format changed
|
129
|
+
abs_file_path = ::File.join(fixture, file)
|
130
|
+
next if ::File.directory?(abs_file_path)
|
131
|
+
assert_equal ::File.read(abs_file_path), ::File.read(::File.join(dir, file)), "#{file} didn't match"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
102
135
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ro-crate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Finn Bacall
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-02-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -149,6 +149,8 @@ files:
|
|
149
149
|
- test/fixtures/crate-spec1.1/ro-crate-metadata.json
|
150
150
|
- test/fixtures/data.csv
|
151
151
|
- test/fixtures/directory.zip
|
152
|
+
- test/fixtures/directory/.dir/test.txt
|
153
|
+
- test/fixtures/directory/.dotfile
|
152
154
|
- test/fixtures/directory/data/binary.jpg
|
153
155
|
- test/fixtures/directory/data/info.txt
|
154
156
|
- test/fixtures/directory/data/nested.txt
|
@@ -160,10 +162,21 @@ files:
|
|
160
162
|
- test/fixtures/directory_crate/fish/info.txt
|
161
163
|
- test/fixtures/directory_crate/fish/root.txt
|
162
164
|
- test/fixtures/directory_crate/ro-crate-metadata.jsonld
|
165
|
+
- test/fixtures/directory_crate/ro-crate-preview.html
|
163
166
|
- test/fixtures/file with spaces.txt
|
164
167
|
- test/fixtures/info.txt
|
165
168
|
- test/fixtures/spaces/file with spaces.txt
|
166
169
|
- test/fixtures/spaces/ro-crate-metadata.jsonld
|
170
|
+
- test/fixtures/sparse_directory_crate.zip
|
171
|
+
- test/fixtures/sparse_directory_crate/fish/data/binary.jpg
|
172
|
+
- test/fixtures/sparse_directory_crate/fish/data/info.txt
|
173
|
+
- test/fixtures/sparse_directory_crate/fish/data/nested.txt
|
174
|
+
- test/fixtures/sparse_directory_crate/fish/info.txt
|
175
|
+
- test/fixtures/sparse_directory_crate/fish/root.txt
|
176
|
+
- test/fixtures/sparse_directory_crate/listed_file.txt
|
177
|
+
- test/fixtures/sparse_directory_crate/ro-crate-metadata.jsonld
|
178
|
+
- test/fixtures/sparse_directory_crate/ro-crate-preview.html
|
179
|
+
- test/fixtures/sparse_directory_crate/unlisted_file.txt
|
167
180
|
- test/fixtures/workflow-0.2.0.zip
|
168
181
|
- test/fixtures/workflow-0.2.0/Dockerfile
|
169
182
|
- test/fixtures/workflow-0.2.0/README.md
|
@@ -2414,5 +2427,5 @@ requirements: []
|
|
2414
2427
|
rubygems_version: 3.0.8
|
2415
2428
|
signing_key:
|
2416
2429
|
specification_version: 4
|
2417
|
-
summary: Create, manipulate, read RO
|
2430
|
+
summary: Create, manipulate, read RO-Crates.
|
2418
2431
|
test_files: []
|