ro-crate 0.4.3 → 0.4.8
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/Gemfile.lock +1 -1
- data/lib/ro_crate/model/crate.rb +18 -13
- data/lib/ro_crate/model/directory.rb +14 -5
- data/lib/ro_crate/model/file.rb +3 -1
- data/lib/ro_crate/reader.rb +48 -7
- data/ro_crate.gemspec +1 -1
- data/test/crate_test.rb +48 -5
- data/test/fixtures/directory/.dir/test.txt +1 -0
- data/test/fixtures/directory/.dotfile +1 -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 +56 -2
- data/test/writer_test.rb +20 -0
- metadata +14 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7003f224766d4445498db499257b246ea2dbfb842f0f5e0c8d04471ccea4d299
|
4
|
+
data.tar.gz: f62e7c90a54f26aa6b18cf98310c998ada8c6836975c997f551b2b1ab7d85e29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f63fa2c3b9d88ec76f20e8986986d81878dc8bbb82bedd4c2c862ca6fca7f021ad84309678abb12ec6de7fb498a87711409f3f64809aba4c09c5b00676c60aac
|
7
|
+
data.tar.gz: 16616f82e91760e9a6ff3eff1199c327143401086b0f9c577908e28d023e27828b7e36eeffc65333ec3aa440697b8f18cddd9406185f116ccc59ff238c98b1e9
|
data/Gemfile.lock
CHANGED
data/lib/ro_crate/model/crate.rb
CHANGED
@@ -68,22 +68,23 @@ module ROCrate
|
|
68
68
|
#
|
69
69
|
# @param source_directory [String, Pathname, ::File,] The source directory that will be included in the crate.
|
70
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).
|
71
72
|
#
|
72
73
|
# @return [Array<DataEntity>] Any entities that were created from the directory contents. Will be empty if `create_entities` was false.
|
73
|
-
def add_all(source_directory, create_entities = true)
|
74
|
+
def add_all(source_directory, create_entities = true, include_hidden: false)
|
74
75
|
added = []
|
75
76
|
|
76
|
-
|
77
|
-
|
78
|
-
|
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
|
79
80
|
if source_path.directory?
|
80
81
|
added << add_directory(source_path, rel_path)
|
81
82
|
else
|
82
83
|
added << add_file(source_path, rel_path)
|
83
84
|
end
|
84
|
-
else
|
85
|
-
populate_entries(Pathname.new(::File.expand_path(source_directory)))
|
86
85
|
end
|
86
|
+
else
|
87
|
+
populate_entries(Pathname.new(::File.expand_path(source_directory)), include_hidden: include_hidden)
|
87
88
|
end
|
88
89
|
|
89
90
|
added
|
@@ -216,16 +217,20 @@ module ROCrate
|
|
216
217
|
|
217
218
|
alias_method :own_entries, :entries
|
218
219
|
##
|
219
|
-
#
|
220
|
-
# 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.
|
221
222
|
#
|
222
223
|
# @return [Hash{String => Entry}>]
|
223
224
|
def entries
|
224
|
-
entries
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
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
|
229
234
|
end
|
230
235
|
end
|
231
236
|
|
@@ -21,7 +21,7 @@ module ROCrate
|
|
21
21
|
|
22
22
|
if source_directory
|
23
23
|
source_directory = Pathname.new(::File.expand_path(source_directory))
|
24
|
-
@entry = source_directory
|
24
|
+
@entry = Entry.new(source_directory)
|
25
25
|
populate_entries(source_directory)
|
26
26
|
crate_path = source_directory.basename.to_s if crate_path.nil?
|
27
27
|
end
|
@@ -30,8 +30,8 @@ module ROCrate
|
|
30
30
|
end
|
31
31
|
|
32
32
|
##
|
33
|
-
#
|
34
|
-
# 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.
|
35
35
|
#
|
36
36
|
# @return [Hash{String => Entry}>]
|
37
37
|
def entries
|
@@ -51,13 +51,14 @@ module ROCrate
|
|
51
51
|
# Populate this directory with files/directories from a given source directory on disk.
|
52
52
|
#
|
53
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).
|
54
55
|
#
|
55
56
|
# @return [Hash{String => Entry}>] The files/directories that were populated.
|
56
57
|
# The key is the relative path of the file/directory, and the value is an Entry object where data can be read etc.
|
57
|
-
def populate_entries(source_directory)
|
58
|
+
def populate_entries(source_directory, include_hidden: false)
|
58
59
|
raise 'Not a directory' unless ::File.directory?(source_directory)
|
59
60
|
@directory_entries = {}
|
60
|
-
|
61
|
+
list_all_files(source_directory, include_hidden: include_hidden).each do |rel_path|
|
61
62
|
source_path = Pathname.new(::File.join(source_directory, rel_path)).expand_path
|
62
63
|
@directory_entries[rel_path] = Entry.new(source_path)
|
63
64
|
end
|
@@ -69,6 +70,14 @@ module ROCrate
|
|
69
70
|
::File.join(filepath, relative_path)
|
70
71
|
end
|
71
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
|
+
|
72
81
|
def default_properties
|
73
82
|
super.merge(
|
74
83
|
'@id' => "#{SecureRandom.uuid}/",
|
data/lib/ro_crate/model/file.rb
CHANGED
@@ -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.
|
data/lib/ro_crate/reader.rb
CHANGED
@@ -3,29 +3,67 @@ module ROCrate
|
|
3
3
|
# A class to handle reading of RO-Crates from Zip files or directories.
|
4
4
|
class Reader
|
5
5
|
##
|
6
|
-
# Reads an RO-Crate from a directory
|
6
|
+
# Reads an RO-Crate from a directory or zip file.
|
7
7
|
#
|
8
|
-
# @param source [String, ::File, Pathname] The
|
8
|
+
# @param source [String, ::File, Pathname, #read] The location of the zip or directory, or an IO-like object containing a zip.
|
9
9
|
# @param target_dir [String, ::File, Pathname] The target directory where the crate should be unzipped (if its a Zip file).
|
10
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
|
+
begin
|
14
|
+
is_dir = ::File.directory?(source)
|
15
|
+
rescue TypeError
|
16
|
+
is_dir = false
|
17
|
+
end
|
18
|
+
|
19
|
+
if is_dir
|
14
20
|
read_directory(source)
|
15
21
|
else
|
16
22
|
read_zip(source, target_dir: target_dir)
|
17
23
|
end
|
18
24
|
end
|
19
25
|
|
26
|
+
##
|
27
|
+
# Extract the contents of the given Zip file/data to the given directory.
|
28
|
+
#
|
29
|
+
# @param source [String, ::File, Pathname, #read] The location of the zip file, or an IO-like object.
|
30
|
+
# @param target [String, ::File, Pathname] The target directory where the file should be unzipped.
|
31
|
+
def self.unzip_to(source, target)
|
32
|
+
source = Pathname.new(::File.expand_path(source)) if source.is_a?(String)
|
33
|
+
|
34
|
+
if source.is_a?(Pathname) || source.is_a?(::File)
|
35
|
+
unzip_file_to(source, target)
|
36
|
+
else
|
37
|
+
unzip_io_to(source, target)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Extract the given Zip file data to the given directory.
|
43
|
+
#
|
44
|
+
# @param source [#read] An IO-like object containing a Zip file.
|
45
|
+
# @param target [String, ::File, Pathname] The target directory where the file should be unzipped.
|
46
|
+
def self.unzip_io_to(io, target)
|
47
|
+
Dir.chdir(target) do
|
48
|
+
Zip::InputStream.open(io) do |input|
|
49
|
+
while (entry = input.get_next_entry)
|
50
|
+
unless ::File.exist?(entry.name) || entry.name_is_directory?
|
51
|
+
FileUtils::mkdir_p(::File.dirname(entry.name))
|
52
|
+
::File.binwrite(entry.name, input.read)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
20
59
|
##
|
21
60
|
# Extract the contents of the given Zip file to the given directory.
|
22
61
|
#
|
23
62
|
# @param source [String, ::File, Pathname] The location of the zip file.
|
24
63
|
# @param target [String, ::File, Pathname] The target directory where the file should be unzipped.
|
25
|
-
def self.
|
26
|
-
source = ::File.expand_path(source)
|
64
|
+
def self.unzip_file_to(file_or_path, target)
|
27
65
|
Dir.chdir(target) do
|
28
|
-
Zip::File.open(
|
66
|
+
Zip::File.open(file_or_path) do |zipfile|
|
29
67
|
zipfile.each do |entry|
|
30
68
|
unless ::File.exist?(entry.name)
|
31
69
|
FileUtils::mkdir_p(::File.dirname(entry.name))
|
@@ -40,7 +78,7 @@ module ROCrate
|
|
40
78
|
# Reads an RO-Crate from a zip file. It first extracts the Zip file to a temporary directory, and then calls
|
41
79
|
# #read_directory.
|
42
80
|
#
|
43
|
-
# @param source [String, ::File, Pathname] The location of the zip file.
|
81
|
+
# @param source [String, ::File, Pathname, #read] The location of the zip file, or an IO-like object.
|
44
82
|
# @param target_dir [String, ::File, Pathname] The target directory where the crate should be unzipped.
|
45
83
|
# @return [Crate] The RO-Crate.
|
46
84
|
def self.read_zip(source, target_dir: Dir.mktmpdir)
|
@@ -55,6 +93,8 @@ module ROCrate
|
|
55
93
|
# @param source [String, ::File, Pathname] The location of the directory.
|
56
94
|
# @return [Crate] The RO-Crate.
|
57
95
|
def self.read_directory(source)
|
96
|
+
raise "Not a directory!" unless ::File.directory?(source)
|
97
|
+
|
58
98
|
source = ::File.expand_path(source)
|
59
99
|
metadata_file = Dir.entries(source).detect { |entry| entry == ROCrate::Metadata::IDENTIFIER ||
|
60
100
|
entry == ROCrate::Metadata::IDENTIFIER_1_0 }
|
@@ -107,6 +147,7 @@ module ROCrate
|
|
107
147
|
crate.metadata.properties = entity_hash.delete(ROCrate::Metadata::IDENTIFIER)
|
108
148
|
preview_properties = entity_hash.delete(ROCrate::Preview::IDENTIFIER)
|
109
149
|
crate.preview.properties = preview_properties if preview_properties
|
150
|
+
crate.add_all(source, false)
|
110
151
|
extract_data_entities(crate, source, entity_hash).each do |entity|
|
111
152
|
crate.add_data_entity(entity)
|
112
153
|
end
|
data/ro_crate.gemspec
CHANGED
data/test/crate_test.rb
CHANGED
@@ -201,44 +201,54 @@ class CrateTest < Test::Unit::TestCase
|
|
201
201
|
|
202
202
|
test 'can add an entire directory tree as data entities' do
|
203
203
|
crate = ROCrate::Crate.new
|
204
|
-
entities = crate.add_all(fixture_file('directory').path)
|
204
|
+
entities = crate.add_all(fixture_file('directory').path, include_hidden: true)
|
205
205
|
|
206
206
|
paths = crate.entries.keys
|
207
|
-
assert_equal
|
207
|
+
assert_equal 11, paths.length
|
208
208
|
assert_includes paths, 'data'
|
209
209
|
assert_includes paths, 'root.txt'
|
210
210
|
assert_includes paths, 'info.txt'
|
211
211
|
assert_includes paths, 'data/binary.jpg'
|
212
212
|
assert_includes paths, 'data/info.txt'
|
213
213
|
assert_includes paths, 'data/nested.txt'
|
214
|
+
assert_includes paths, '.dotfile'
|
215
|
+
assert_includes paths, '.dir'
|
216
|
+
assert_includes paths, '.dir/test.txt'
|
214
217
|
assert_includes paths, 'ro-crate-metadata.json'
|
215
218
|
assert_includes paths, 'ro-crate-preview.html'
|
216
219
|
|
217
|
-
assert_equal
|
220
|
+
assert_equal 9, entities.length
|
218
221
|
assert_equal 'ROCrate::Directory', crate.dereference('data/').class.name
|
219
222
|
assert_equal 'ROCrate::File', crate.dereference('root.txt').class.name
|
220
223
|
assert_equal 'ROCrate::File', crate.dereference('info.txt').class.name
|
221
224
|
assert_equal 'ROCrate::File', crate.dereference('data/binary.jpg').class.name
|
222
225
|
assert_equal 'ROCrate::File', crate.dereference('data/info.txt').class.name
|
223
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
|
224
230
|
|
225
231
|
assert_equal "5678\n", crate.dereference('data/info.txt').source.read
|
232
|
+
assert_equal "Am I included?\n", crate.dereference('.dotfile').source.read
|
226
233
|
end
|
227
234
|
|
228
235
|
test 'can create an RO-Crate using content from a given directory' do
|
229
236
|
crate = ROCrate::Crate.new
|
230
|
-
entities = crate.add_all(fixture_file('directory').path, false)
|
237
|
+
entities = crate.add_all(fixture_file('directory').path, false, include_hidden: true)
|
231
238
|
|
232
239
|
assert_empty entities
|
233
240
|
|
234
241
|
paths = crate.entries.keys
|
235
|
-
assert_equal
|
242
|
+
assert_equal 11, paths.length
|
236
243
|
assert_includes paths, 'data'
|
237
244
|
assert_includes paths, 'root.txt'
|
238
245
|
assert_includes paths, 'info.txt'
|
239
246
|
assert_includes paths, 'data/binary.jpg'
|
240
247
|
assert_includes paths, 'data/info.txt'
|
241
248
|
assert_includes paths, 'data/nested.txt'
|
249
|
+
assert_includes paths, '.dotfile'
|
250
|
+
assert_includes paths, '.dir'
|
251
|
+
assert_includes paths, '.dir/test.txt'
|
242
252
|
assert_includes paths, 'ro-crate-metadata.json'
|
243
253
|
assert_includes paths, 'ro-crate-preview.html'
|
244
254
|
|
@@ -249,5 +259,38 @@ class CrateTest < Test::Unit::TestCase
|
|
249
259
|
assert_nil crate.dereference('data/binary.jpg')
|
250
260
|
assert_nil crate.dereference('data/info.txt')
|
251
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
|
252
295
|
end
|
253
296
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
123
|
@@ -0,0 +1 @@
|
|
1
|
+
Am I included?
|
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,56 @@ 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
|
198
|
+
|
199
|
+
test 'reading a zip from various object types' do
|
200
|
+
string_io = StringIO.new
|
201
|
+
string_io.write(::File.read(fixture_file('sparse_directory_crate.zip').path))
|
202
|
+
string_io.rewind
|
203
|
+
assert string_io.is_a?(StringIO)
|
204
|
+
assert_equal 11, ROCrate::Reader.read_zip(string_io).entries.count
|
205
|
+
|
206
|
+
path = Pathname.new(fixture_file('sparse_directory_crate.zip').path)
|
207
|
+
assert path.is_a?(Pathname)
|
208
|
+
assert_equal 11, ROCrate::Reader.read_zip(path).entries.count
|
209
|
+
|
210
|
+
file = ::File.open(fixture_file('sparse_directory_crate.zip').path)
|
211
|
+
assert file.is_a?(::File)
|
212
|
+
assert_equal 11, ROCrate::Reader.read_zip(file).entries.count
|
213
|
+
|
214
|
+
string = fixture_file('sparse_directory_crate.zip').path
|
215
|
+
assert string.is_a?(String)
|
216
|
+
assert_equal 11, ROCrate::Reader.read_zip(string).entries.count
|
217
|
+
end
|
164
218
|
end
|
data/test/writer_test.rb
CHANGED
@@ -112,4 +112,24 @@ class WriterTest < Test::Unit::TestCase
|
|
112
112
|
assert_equal 2529, ::File.size(::File.join(dir, 'data', 'binary.jpg'))
|
113
113
|
end
|
114
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
|
115
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.8
|
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-02-
|
11
|
+
date: 2021-02-26 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
|
@@ -165,6 +167,16 @@ files:
|
|
165
167
|
- test/fixtures/info.txt
|
166
168
|
- test/fixtures/spaces/file with spaces.txt
|
167
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
|
168
180
|
- test/fixtures/workflow-0.2.0.zip
|
169
181
|
- test/fixtures/workflow-0.2.0/Dockerfile
|
170
182
|
- test/fixtures/workflow-0.2.0/README.md
|