zip-container 2.0.0 → 2.1.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 +8 -8
- data/.ruby-env +1 -0
- data/.travis.yml +7 -1
- data/Changes.rdoc +17 -0
- data/ReadMe.rdoc +11 -5
- data/examples/create-zip-container +1 -1
- data/examples/verify-zip-container +1 -1
- data/examples/zip-container-info +1 -1
- data/lib/zip-container.rb +2 -0
- data/lib/zip-container/container.rb +131 -0
- data/lib/zip-container/dir.rb +192 -0
- data/lib/zip-container/file.rb +21 -95
- data/test/data/dirs/dir-mimetype/mimetype/.gitkeep +1 -0
- data/test/data/dirs/empty/mimetype +1 -0
- data/test/data/dirs/null/.gitkeep +1 -0
- data/test/tc_create_dir.rb +59 -0
- data/test/{tc_create.rb → tc_create_file.rb} +1 -1
- data/test/tc_read_dir.rb +65 -0
- data/test/{tc_read.rb → tc_read_file.rb} +1 -1
- data/test/ts_container.rb +7 -2
- data/version.yml +1 -1
- data/zip-container.gemspec +6 -6
- metadata +41 -14
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZmM2M2M1M2YyMWUwOTk2NWRkNjllMjU0MDc0ZjQ4NGU3OWRiNTFlMg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OWFjNzFmYjM4NTliZjc4ZGE0NTZjYzNhMjBiMjJjY2Q3NGVmZjdmMw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZmQxZTFjNzY2NjEyZGIzM2IzOTc2ZGU1ZjlkM2IwMzljZmM4NmUyN2JmNWYx
|
10
|
+
ZGU4YWU0ZjYzOTU3MjU3ZWVhZjdlNzI4MjY3MzhkYTEyNmNkOGFjNWNkZjFh
|
11
|
+
NmE1YWU3YWFjMzM0ODI0YTM2YTc4NzU3MDYyYzE2MTVjMDZjMTc=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MDBmMWJmMjE2YzY4ZjkxYWZiOWU2NzNhOTU3Njk4MDViYWIzOGYyMDEzZDlk
|
14
|
+
NTNiYTM4YmFmMjAwNDZmZGVlMjYxMTAxMDU3YTcyYWVmMmE1NjFjMGY5MGFm
|
15
|
+
YmE0MjQwOTFkZjk1MGM2ZDQyY2ZhMDViYTA0NWYyM2ZlMjk3YTU=
|
data/.ruby-env
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
RUBYLIB=./lib:../lib
|
data/.travis.yml
CHANGED
data/Changes.rdoc
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
= Changes log for the ZIP Container Ruby Gem
|
2
2
|
|
3
|
+
== Version 2.1.0
|
4
|
+
|
5
|
+
* Set up the Container superclass.
|
6
|
+
* Open the container from the superclass.
|
7
|
+
* Check and read the mimetype file in the superclass.
|
8
|
+
* Initialize reserved names and managed entries in the superclass.
|
9
|
+
* Refactor mimetype verification.
|
10
|
+
* Move container verification into the superclass.
|
11
|
+
* Update the example scripts to the new API.
|
12
|
+
* Move ::open to the Container superclass.
|
13
|
+
* Move ::verify and ::verify! to the superclass.
|
14
|
+
* Add the ZipContainer::Dir class.
|
15
|
+
* Add a test for a mimetype entry that is a directory.
|
16
|
+
* Add a test for an unreadable mimetype file.
|
17
|
+
* Update dependencies.
|
18
|
+
* Disambiguate the two test classes for File and Dir.
|
19
|
+
|
3
20
|
== Version 2.0.0
|
4
21
|
|
5
22
|
* Change API: Container => File.
|
data/ReadMe.rdoc
CHANGED
@@ -19,16 +19,22 @@ This is a Ruby library for working with ZIP Container files. See the
|
|
19
19
|
{UDF}[https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format]
|
20
20
|
specifications for more details.
|
21
21
|
|
22
|
+
We follow the principles of {Semantic Versioning}[http://semver.org/] for our
|
23
|
+
releases.
|
24
|
+
|
22
25
|
== Backwards incompatibility warnings!
|
23
26
|
|
24
27
|
=== ZipContainer
|
25
28
|
|
26
|
-
The ZipContainer::Container class is
|
27
|
-
ZipContainer::File.
|
28
|
-
|
29
|
-
|
29
|
+
The ZipContainer::Container class is now a common superclass of
|
30
|
+
ZipContainer::Dir and ZipContainer::File. You can use ZipContainer::File as a
|
31
|
+
direct replacement for ZipContainer::Container as the functionality is
|
32
|
+
preserved. The new names bring this API into closer alignment with the
|
33
|
+
underlying rubyzip API (Zip::File) and allows this library to work with
|
34
|
+
"exploded" or unpacked containers directly.
|
30
35
|
|
31
|
-
ZipContainer::Container
|
36
|
+
ZipContainer::Container should not be used directly from version 2.0.0
|
37
|
+
onwards.
|
32
38
|
|
33
39
|
=== Rubyzip
|
34
40
|
|
@@ -49,7 +49,7 @@ if File.exists?(container_file)
|
|
49
49
|
end
|
50
50
|
|
51
51
|
begin
|
52
|
-
ZipContainer::
|
52
|
+
ZipContainer::File.create(container_file, "application/epub+zip") do |c|
|
53
53
|
|
54
54
|
# Add a cheery greeting file from a string.
|
55
55
|
c.file.open("greeting.txt", "w") do |f|
|
@@ -44,7 +44,7 @@ usage unless ARGV.length == 1
|
|
44
44
|
container_file = ARGV[0]
|
45
45
|
|
46
46
|
begin
|
47
|
-
ZipContainer::
|
47
|
+
ZipContainer::File.verify!(container_file)
|
48
48
|
rescue ZipContainer::MalformedContainerError, ZipContainer::ZipError => err
|
49
49
|
puts err.to_s
|
50
50
|
exit 1
|
data/examples/zip-container-info
CHANGED
@@ -44,7 +44,7 @@ usage unless ARGV.length == 1
|
|
44
44
|
container_file = ARGV[0]
|
45
45
|
|
46
46
|
begin
|
47
|
-
container = ZipContainer::
|
47
|
+
container = ZipContainer::File.open(container_file)
|
48
48
|
rescue ZipContainer::MalformedContainerError, ZipContainer::ZipError => err
|
49
49
|
puts err.to_s
|
50
50
|
exit 1
|
data/lib/zip-container.rb
CHANGED
@@ -43,7 +43,9 @@ require 'zip-container/entries/managed'
|
|
43
43
|
require 'zip-container/entries/entry'
|
44
44
|
require 'zip-container/entries/file'
|
45
45
|
require 'zip-container/entries/directory'
|
46
|
+
require 'zip-container/container'
|
46
47
|
require 'zip-container/file'
|
48
|
+
require 'zip-container/dir'
|
47
49
|
|
48
50
|
# This is a ruby library to read and write ZIP Container Format files. See the
|
49
51
|
# ZipContainer::Container class for more information.
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# Copyright (c) 2014 The University of Manchester, UK.
|
2
|
+
#
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# * Neither the names of The University of Manchester nor the names of its
|
16
|
+
# contributors may be used to endorse or promote products derived from this
|
17
|
+
# software without specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
23
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
24
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
25
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
26
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
27
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
28
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
#
|
31
|
+
# Author: Robert Haines
|
32
|
+
|
33
|
+
#
|
34
|
+
module ZipContainer
|
35
|
+
|
36
|
+
# The superclass of anything that represents a Zip Container. That
|
37
|
+
# representation could be as a Zip file (most commonly), as a directory or
|
38
|
+
# something else.
|
39
|
+
class Container
|
40
|
+
include ReservedNames
|
41
|
+
include ManagedEntries
|
42
|
+
|
43
|
+
private_class_method :new
|
44
|
+
|
45
|
+
# The mime-type of this ZipContainer.
|
46
|
+
attr_reader :mimetype
|
47
|
+
|
48
|
+
# :stopdoc:
|
49
|
+
# The reserved mimetype file name for standard ZipContainers.
|
50
|
+
MIMETYPE_FILE = "mimetype"
|
51
|
+
|
52
|
+
def initialize(location)
|
53
|
+
@container = open_container(location)
|
54
|
+
|
55
|
+
check_mimetype!
|
56
|
+
@mimetype = read_mimetype
|
57
|
+
|
58
|
+
# Reserved entry names. Just the mimetype file by default.
|
59
|
+
register_reserved_name(MIMETYPE_FILE)
|
60
|
+
|
61
|
+
# Initialize the managed entry tables.
|
62
|
+
initialize_managed_entries
|
63
|
+
end
|
64
|
+
# :startdoc:
|
65
|
+
|
66
|
+
# :call-seq:
|
67
|
+
# open(filename) -> container
|
68
|
+
# open(filename) {|container| ...}
|
69
|
+
#
|
70
|
+
# Open an existing ZipContainer. It will be checked for conformance upon
|
71
|
+
# first access.
|
72
|
+
def self.open(filename, &block)
|
73
|
+
c = new(filename)
|
74
|
+
|
75
|
+
if block_given?
|
76
|
+
begin
|
77
|
+
yield c
|
78
|
+
ensure
|
79
|
+
c.close
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
c
|
84
|
+
end
|
85
|
+
|
86
|
+
# :call-seq:
|
87
|
+
# verify(filename) -> boolean
|
88
|
+
#
|
89
|
+
# Verify that the specified ZipContainer conforms to the specification.
|
90
|
+
# This method returns +false+ if there are any problems at all with the
|
91
|
+
# container (including if it cannot be found).
|
92
|
+
def self.verify(filename)
|
93
|
+
begin
|
94
|
+
new(filename).verify!
|
95
|
+
rescue
|
96
|
+
return false
|
97
|
+
end
|
98
|
+
|
99
|
+
true
|
100
|
+
end
|
101
|
+
|
102
|
+
# :call-seq:
|
103
|
+
# verify!(filename)
|
104
|
+
#
|
105
|
+
# Verify that the specified ZipContainer conforms to the specification.
|
106
|
+
# This method raises exceptions when errors are found or if there is
|
107
|
+
# something fundamental wrong with the container itself (e.g. it cannot be
|
108
|
+
# found).
|
109
|
+
def self.verify!(filename)
|
110
|
+
new(filename).verify!
|
111
|
+
end
|
112
|
+
|
113
|
+
# :call-seq:
|
114
|
+
# verify!
|
115
|
+
#
|
116
|
+
# Verify the contents of this ZipContainer file. All managed files and
|
117
|
+
# directories are checked to make sure that they exist, if required.
|
118
|
+
def verify!
|
119
|
+
verify_managed_entries!
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def check_mimetype!
|
125
|
+
message = verify_mimetype
|
126
|
+
raise MalformedContainerError.new(message) unless message.nil?
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
# Copyright (c) 2014 The University of Manchester, UK.
|
2
|
+
#
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# * Neither the names of The University of Manchester nor the names of its
|
16
|
+
# contributors may be used to endorse or promote products derived from this
|
17
|
+
# software without specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
23
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
24
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
25
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
26
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
27
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
28
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
#
|
31
|
+
# Author: Robert Haines
|
32
|
+
|
33
|
+
require 'forwardable'
|
34
|
+
|
35
|
+
module ZipContainer
|
36
|
+
|
37
|
+
# This class represents a ZipContainer in directory format. See the
|
38
|
+
# {OCF}[http://www.idpf.org/epub/30/spec/epub30-ocf.html] and
|
39
|
+
# {UCF}[https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format]
|
40
|
+
# specifications for more details.
|
41
|
+
#
|
42
|
+
# This class provides most of the facilities of the standard <tt>::Dir</tt>
|
43
|
+
# class. Please also consult the
|
44
|
+
# {ruby Dir documentation}[http://ruby-doc.org/core-1.9.3/Dir.html]
|
45
|
+
# alongside these pages.
|
46
|
+
#
|
47
|
+
# There are code examples available with the source code of this library.
|
48
|
+
class Dir < Container
|
49
|
+
|
50
|
+
extend Forwardable
|
51
|
+
def_delegators :@container, :close, :each, :path, :pos, :pos=, :read,
|
52
|
+
:rewind, :seek, :tell
|
53
|
+
|
54
|
+
private_class_method :new
|
55
|
+
|
56
|
+
# :stopdoc:
|
57
|
+
def initialize(location)
|
58
|
+
super(location)
|
59
|
+
end
|
60
|
+
# :startdoc:
|
61
|
+
|
62
|
+
# :call-seq:
|
63
|
+
# create(pathname, mimetype) -> document
|
64
|
+
# create(pathname, mimetype) {|document| ...}
|
65
|
+
#
|
66
|
+
# Create a new (or convert an existing) directory as a ZipContainer with
|
67
|
+
# the specified mimetype.
|
68
|
+
def self.create(pathname, mimetype, &block)
|
69
|
+
::Dir.mkdir(pathname) unless ::File.directory?(pathname)
|
70
|
+
::File.write(full_path(MIMETYPE_FILE), mimetype)
|
71
|
+
|
72
|
+
# Now open the newly created container.
|
73
|
+
c = new(pathname)
|
74
|
+
|
75
|
+
if block_given?
|
76
|
+
begin
|
77
|
+
yield c
|
78
|
+
ensure
|
79
|
+
c.close
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
c
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
# Prepend the full path of the directory name to whatever is passed in
|
89
|
+
# here. This is for internal use to ensure we are always operating on
|
90
|
+
# files within our container directory.
|
91
|
+
def full_path(path)
|
92
|
+
::File.join(@container.path, path)
|
93
|
+
end
|
94
|
+
|
95
|
+
def open_container(location)
|
96
|
+
::Dir.new(location)
|
97
|
+
end
|
98
|
+
|
99
|
+
def verify_mimetype
|
100
|
+
mime_path = full_path(MIMETYPE_FILE)
|
101
|
+
if ::File.exist?(mime_path)
|
102
|
+
return "'mimetype' is not a regular file" unless ::File.file?(mime_path)
|
103
|
+
return "'mimetype' is not readable." unless ::File.readable?(mime_path)
|
104
|
+
else
|
105
|
+
return "'mimetype' file is missing."
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def read_mimetype
|
110
|
+
::File.read(full_path(MIMETYPE_FILE))
|
111
|
+
end
|
112
|
+
|
113
|
+
public
|
114
|
+
|
115
|
+
# Lots of extra docs out of the way at the end here...
|
116
|
+
|
117
|
+
##
|
118
|
+
# :method: close
|
119
|
+
# :call-seq:
|
120
|
+
# close -> nil
|
121
|
+
#
|
122
|
+
# Equal to
|
123
|
+
# {::Dir.close}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-close]
|
124
|
+
|
125
|
+
##
|
126
|
+
# :method: each
|
127
|
+
# :call-seq:
|
128
|
+
# each { |filename| ... } -> dir
|
129
|
+
# each -> an_enumerator
|
130
|
+
#
|
131
|
+
# Equal to
|
132
|
+
# {::Dir.each}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-each]
|
133
|
+
|
134
|
+
##
|
135
|
+
# :method: path
|
136
|
+
# :call-seq:
|
137
|
+
# path -> string or nil
|
138
|
+
#
|
139
|
+
# Equal to
|
140
|
+
# {::Dir.path}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-path]
|
141
|
+
|
142
|
+
##
|
143
|
+
# :method: pos
|
144
|
+
# :call-seq:
|
145
|
+
# pos -> integer
|
146
|
+
#
|
147
|
+
# Equal to
|
148
|
+
# {::Dir.pos}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-pos]
|
149
|
+
|
150
|
+
##
|
151
|
+
# :method: pos=
|
152
|
+
# :call-seq:
|
153
|
+
# pos = integer -> integer
|
154
|
+
#
|
155
|
+
# Equal to
|
156
|
+
# {::Dir.pos=}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-pos-3D]
|
157
|
+
|
158
|
+
##
|
159
|
+
# :method: read
|
160
|
+
# :call-seq:
|
161
|
+
# read -> string or nil
|
162
|
+
#
|
163
|
+
# Equal to
|
164
|
+
# {::Dir.read}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-read]
|
165
|
+
|
166
|
+
##
|
167
|
+
# :method: rewind
|
168
|
+
# :call-seq:
|
169
|
+
# rewind -> dir
|
170
|
+
#
|
171
|
+
# Equal to
|
172
|
+
# {::Dir.rewind}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-rewind]
|
173
|
+
|
174
|
+
##
|
175
|
+
# :method: seek
|
176
|
+
# :call-seq:
|
177
|
+
# seek(integer) -> dir
|
178
|
+
#
|
179
|
+
# Equal to
|
180
|
+
# {::Dir.seek}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-seek]
|
181
|
+
|
182
|
+
##
|
183
|
+
# :method: tell
|
184
|
+
# :call-seq:
|
185
|
+
# tell -> integer
|
186
|
+
#
|
187
|
+
# Equal to
|
188
|
+
# {::Dir.tell}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-tell]
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
data/lib/zip-container/file.rb
CHANGED
@@ -45,36 +45,20 @@ module ZipContainer
|
|
45
45
|
# alongside these pages.
|
46
46
|
#
|
47
47
|
# There are code examples available with the source code of this library.
|
48
|
-
class File
|
49
|
-
include ReservedNames
|
50
|
-
include ManagedEntries
|
48
|
+
class File < Container
|
51
49
|
|
52
50
|
extend Forwardable
|
53
|
-
def_delegators :@
|
51
|
+
def_delegators :@container, :comment, :comment=, :commit_required?, :each,
|
54
52
|
:entries, :extract, :get_input_stream, :name, :read, :size
|
55
53
|
|
56
54
|
private_class_method :new
|
57
55
|
|
58
|
-
# The mime-type of this ZipContainer file.
|
59
|
-
attr_reader :mimetype
|
60
|
-
|
61
56
|
# :stopdoc:
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
def initialize(document)
|
66
|
-
@zipfile = open_document(document)
|
67
|
-
check_mimetype!
|
57
|
+
def initialize(location)
|
58
|
+
super(location)
|
68
59
|
|
69
|
-
@mimetype = read_mimetype
|
70
60
|
@on_disk = true
|
71
61
|
|
72
|
-
# Reserved entry names. Just the mimetype file by default.
|
73
|
-
register_reserved_name(MIMETYPE_FILE)
|
74
|
-
|
75
|
-
# Initialize the managed entry tables.
|
76
|
-
initialize_managed_entries
|
77
|
-
|
78
62
|
# Here we fake up the connection to the rubyzip filesystem classes so
|
79
63
|
# that they also respect the reserved names that we define.
|
80
64
|
mapped_zip = ::Zip::FileSystem::ZipFileNameMapper.new(self)
|
@@ -131,53 +115,6 @@ module ZipContainer
|
|
131
115
|
c.each
|
132
116
|
end
|
133
117
|
|
134
|
-
# :call-seq:
|
135
|
-
# File.open(filename) -> document
|
136
|
-
# File.open(filename) {|document| ...}
|
137
|
-
#
|
138
|
-
# Open an existing ZipContainer file from disk. It will be checked for
|
139
|
-
# conformance upon first access.
|
140
|
-
def self.open(filename, &block)
|
141
|
-
c = new(filename)
|
142
|
-
|
143
|
-
if block_given?
|
144
|
-
begin
|
145
|
-
yield c
|
146
|
-
ensure
|
147
|
-
c.close
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
c
|
152
|
-
end
|
153
|
-
|
154
|
-
# :call-seq:
|
155
|
-
# File.verify(filename) -> boolean
|
156
|
-
#
|
157
|
-
# Verify that the specified ZipContainer file conforms to the
|
158
|
-
# specification. This method returns +false+ if there are any problems at
|
159
|
-
# all with the file (including if it cannot be found).
|
160
|
-
def self.verify(filename)
|
161
|
-
begin
|
162
|
-
new(filename).verify!
|
163
|
-
rescue
|
164
|
-
return false
|
165
|
-
end
|
166
|
-
|
167
|
-
true
|
168
|
-
end
|
169
|
-
|
170
|
-
# :call-seq:
|
171
|
-
# File.verify!(filename)
|
172
|
-
#
|
173
|
-
# Verify that the specified ZipContainer file conforms to the
|
174
|
-
# specification. This method raises exceptions when errors are found or if
|
175
|
-
# there is something fundamental wrong with the file itself (e.g. it
|
176
|
-
# cannot be found).
|
177
|
-
def self.verify!(filename)
|
178
|
-
new(filename).verify!
|
179
|
-
end
|
180
|
-
|
181
118
|
# :call-seq:
|
182
119
|
# add(entry, src_path, &continue_on_exists_proc)
|
183
120
|
#
|
@@ -193,7 +130,7 @@ module ZipContainer
|
|
193
130
|
raise ReservedNameClashError.new(entry.to_s)
|
194
131
|
end
|
195
132
|
|
196
|
-
@
|
133
|
+
@container.add(entry, src_path, &continue_on_exists_proc)
|
197
134
|
end
|
198
135
|
|
199
136
|
# :call-seq:
|
@@ -207,7 +144,7 @@ module ZipContainer
|
|
207
144
|
return false unless commit_required?
|
208
145
|
|
209
146
|
if on_disk?
|
210
|
-
@
|
147
|
+
@container.commit
|
211
148
|
end
|
212
149
|
end
|
213
150
|
|
@@ -251,7 +188,7 @@ module ZipContainer
|
|
251
188
|
return if hidden_entry?(entry_name)
|
252
189
|
end
|
253
190
|
|
254
|
-
@
|
191
|
+
@container.find_entry(entry_name)
|
255
192
|
end
|
256
193
|
|
257
194
|
# :call-seq:
|
@@ -268,7 +205,7 @@ module ZipContainer
|
|
268
205
|
raise Errno::ENOENT, entry if hidden_entry?(entry)
|
269
206
|
end
|
270
207
|
|
271
|
-
@
|
208
|
+
@container.get_entry(entry)
|
272
209
|
end
|
273
210
|
|
274
211
|
# :call-seq:
|
@@ -286,7 +223,7 @@ module ZipContainer
|
|
286
223
|
raise ReservedNameClashError.new(entry.to_s)
|
287
224
|
end
|
288
225
|
|
289
|
-
@
|
226
|
+
@container.get_output_stream(entry, permission, &block)
|
290
227
|
end
|
291
228
|
|
292
229
|
# :call-seq:
|
@@ -347,7 +284,7 @@ module ZipContainer
|
|
347
284
|
raise ReservedNameClashError.new(name)
|
348
285
|
end
|
349
286
|
|
350
|
-
@
|
287
|
+
@container.mkdir(name, permission)
|
351
288
|
end
|
352
289
|
|
353
290
|
# :call-seq:
|
@@ -366,7 +303,7 @@ module ZipContainer
|
|
366
303
|
# method will do nothing.
|
367
304
|
def remove(entry)
|
368
305
|
return if reserved_entry?(entry)
|
369
|
-
@
|
306
|
+
@container.remove(entry)
|
370
307
|
end
|
371
308
|
|
372
309
|
# :call-seq:
|
@@ -383,7 +320,7 @@ module ZipContainer
|
|
383
320
|
return if reserved_entry?(entry)
|
384
321
|
raise ReservedNameClashError.new(new_name) if reserved_entry?(new_name)
|
385
322
|
|
386
|
-
@
|
323
|
+
@container.rename(entry, new_name, &continue_on_exists_proc)
|
387
324
|
end
|
388
325
|
|
389
326
|
# :call-seq:
|
@@ -395,7 +332,7 @@ module ZipContainer
|
|
395
332
|
# nothing.
|
396
333
|
def replace(entry, src_path)
|
397
334
|
return if reserved_entry?(entry)
|
398
|
-
@
|
335
|
+
@container.replace(entry, src_path)
|
399
336
|
end
|
400
337
|
|
401
338
|
# :call-seq:
|
@@ -403,41 +340,30 @@ module ZipContainer
|
|
403
340
|
#
|
404
341
|
# Return a textual summary of this ZipContainer file.
|
405
342
|
def to_s
|
406
|
-
@
|
407
|
-
end
|
408
|
-
|
409
|
-
# :call-seq:
|
410
|
-
# verify!
|
411
|
-
#
|
412
|
-
# Verify the contents of this ZipContainer file. All managed files and
|
413
|
-
# directories are checked to make sure that they exist, if required.
|
414
|
-
def verify!
|
415
|
-
verify_managed_entries!
|
343
|
+
@container.to_s + " - #{@mimetype}"
|
416
344
|
end
|
417
345
|
|
418
346
|
private
|
419
347
|
|
420
|
-
def
|
348
|
+
def open_container(document)
|
421
349
|
::Zip::File.new(document)
|
422
350
|
end
|
423
351
|
|
424
|
-
def
|
352
|
+
def verify_mimetype
|
425
353
|
# Check mimetype file is present and correct.
|
426
|
-
entry = @
|
354
|
+
entry = @container.find_entry(MIMETYPE_FILE)
|
427
355
|
|
428
|
-
|
356
|
+
return "'mimetype' file is missing." if entry.nil?
|
429
357
|
if entry.local_header_offset != 0
|
430
|
-
|
358
|
+
return "'mimetype' file is not at offset 0 in the archive."
|
431
359
|
end
|
432
360
|
if entry.compression_method != ::Zip::Entry::STORED
|
433
|
-
|
361
|
+
return "'mimetype' file is compressed."
|
434
362
|
end
|
435
|
-
|
436
|
-
true
|
437
363
|
end
|
438
364
|
|
439
365
|
def read_mimetype
|
440
|
-
@
|
366
|
+
@container.read(MIMETYPE_FILE)
|
441
367
|
end
|
442
368
|
|
443
369
|
public
|
@@ -0,0 +1 @@
|
|
1
|
+
This "mimetype" directory needs to be preserved by git.
|
@@ -0,0 +1 @@
|
|
1
|
+
application/epub+zip
|
@@ -0,0 +1 @@
|
|
1
|
+
This dir should be "empty", which in this case just means no "mimetype" file.
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Copyright (c) 2014 The University of Manchester, UK.
|
2
|
+
#
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# * Neither the names of The University of Manchester nor the names of its
|
16
|
+
# contributors may be used to endorse or promote products derived from this
|
17
|
+
# software without specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
23
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
24
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
25
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
26
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
27
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
28
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
#
|
31
|
+
# Author: Robert Haines
|
32
|
+
|
33
|
+
require 'test/unit'
|
34
|
+
require 'tmpdir'
|
35
|
+
require 'zip-container'
|
36
|
+
|
37
|
+
class TestCreateDir < Test::Unit::TestCase
|
38
|
+
|
39
|
+
# Check that a mimetype which is not readable does not verify. We have to
|
40
|
+
# build this fixture programmatically as there's no way to add a file
|
41
|
+
# without read permissions into git.
|
42
|
+
def test_verify_unreadable_mimetype
|
43
|
+
Dir.mktmpdir do |dir|
|
44
|
+
container = File.join(dir, "unreadable")
|
45
|
+
Dir.mkdir(container)
|
46
|
+
mime_path = File.join(container, ZipContainer::Container::MIMETYPE_FILE)
|
47
|
+
File.open(mime_path, "w") { |file| file.write "MIMETYPE" }
|
48
|
+
File.chmod(0000, mime_path)
|
49
|
+
|
50
|
+
refute File.readable?(mime_path)
|
51
|
+
assert_raise(ZipContainer::MalformedContainerError) do
|
52
|
+
ZipContainer::Dir.verify!(container)
|
53
|
+
end
|
54
|
+
|
55
|
+
refute(ZipContainer::Dir.verify(container))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/test/tc_read_dir.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Copyright (c) 2014 The University of Manchester, UK.
|
2
|
+
#
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# * Neither the names of The University of Manchester nor the names of its
|
16
|
+
# contributors may be used to endorse or promote products derived from this
|
17
|
+
# software without specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
23
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
24
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
25
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
26
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
27
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
28
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
#
|
31
|
+
# Author: Robert Haines
|
32
|
+
|
33
|
+
require 'test/unit'
|
34
|
+
require 'zip-container'
|
35
|
+
|
36
|
+
class TestReadDir < Test::Unit::TestCase
|
37
|
+
|
38
|
+
# Check that the empty directory does not verify.
|
39
|
+
def test_verify_empty_directory
|
40
|
+
assert_raise(ZipContainer::MalformedContainerError) do
|
41
|
+
ZipContainer::Dir.verify!($dir_null)
|
42
|
+
end
|
43
|
+
|
44
|
+
refute(ZipContainer::Dir.verify($dir_null))
|
45
|
+
end
|
46
|
+
|
47
|
+
# Check that the empty container directory does verify.
|
48
|
+
def test_verify_empty_container
|
49
|
+
assert_nothing_raised(ZipContainer::MalformedContainerError) do
|
50
|
+
ZipContainer::Dir.verify!($dir_empty)
|
51
|
+
end
|
52
|
+
|
53
|
+
assert(ZipContainer::Dir.verify($dir_empty))
|
54
|
+
end
|
55
|
+
|
56
|
+
# Check that a mimetype entry that is a directory does not verify.
|
57
|
+
def test_verify_mimetype_directory
|
58
|
+
assert_raise(ZipContainer::MalformedContainerError) do
|
59
|
+
ZipContainer::Dir.verify!($dir_dir_mimetype)
|
60
|
+
end
|
61
|
+
|
62
|
+
refute(ZipContainer::Dir.verify($dir_dir_mimetype))
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
data/test/ts_container.rb
CHANGED
@@ -37,6 +37,9 @@ Coveralls.wear!
|
|
37
37
|
$mimetype = "application/epub+zip"
|
38
38
|
|
39
39
|
# Example data files
|
40
|
+
$dir_null = "test/data/dirs/null"
|
41
|
+
$dir_empty = "test/data/dirs/empty"
|
42
|
+
$dir_dir_mimetype = "test/data/dirs/dir-mimetype"
|
40
43
|
$file_null = "test/data/null.file"
|
41
44
|
$empty = "test/data/empty.container"
|
42
45
|
$empty_zip = "test/data/empty.zip"
|
@@ -47,7 +50,9 @@ $subclass = "test/data/subclassed.container"
|
|
47
50
|
# Run test cases.
|
48
51
|
require 'tc_util'
|
49
52
|
require 'tc_exceptions'
|
50
|
-
require '
|
51
|
-
require '
|
53
|
+
require 'tc_create_dir'
|
54
|
+
require 'tc_create_file'
|
55
|
+
require 'tc_read_dir'
|
56
|
+
require 'tc_read_file'
|
52
57
|
require 'tc_reserved_names'
|
53
58
|
require 'tc_managed_entries'
|
data/version.yml
CHANGED
data/zip-container.gemspec
CHANGED
@@ -55,10 +55,10 @@ Gem::Specification.new do |s|
|
|
55
55
|
s.extra_rdoc_files = [ "Changes.rdoc", "Licence.rdoc", "ReadMe.rdoc" ]
|
56
56
|
s.rdoc_options = [ "-N", "--tab-width=2", "--main=ReadMe.rdoc" ]
|
57
57
|
s.required_ruby_version = ">= 1.9.3"
|
58
|
-
s.add_development_dependency
|
59
|
-
s.add_development_dependency
|
60
|
-
s.add_development_dependency
|
61
|
-
s.add_development_dependency
|
62
|
-
s.
|
58
|
+
s.add_development_dependency "bundler", "~> 1.5"
|
59
|
+
s.add_development_dependency "rake", "~> 10.1"
|
60
|
+
s.add_development_dependency "rdoc", "~> 4.1"
|
61
|
+
s.add_development_dependency "test-unit", "~> 3.0"
|
62
|
+
s.add_development_dependency "coveralls"
|
63
|
+
s.add_runtime_dependency "rubyzip", "~> 1.1.6"
|
63
64
|
end
|
64
|
-
|
metadata
CHANGED
@@ -1,57 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zip-container
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Haines
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '1.5'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '1.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1
|
33
|
+
version: '10.1'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1
|
40
|
+
version: '10.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rdoc
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 4.
|
47
|
+
version: '4.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: test-unit
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - ~>
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
68
|
+
version: '3.0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: coveralls
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -93,6 +107,7 @@ extra_rdoc_files:
|
|
93
107
|
- ReadMe.rdoc
|
94
108
|
files:
|
95
109
|
- .gitignore
|
110
|
+
- .ruby-env
|
96
111
|
- .ruby-gemset
|
97
112
|
- .ruby-version
|
98
113
|
- .travis.yml
|
@@ -105,6 +120,8 @@ files:
|
|
105
120
|
- examples/verify-zip-container
|
106
121
|
- examples/zip-container-info
|
107
122
|
- lib/zip-container.rb
|
123
|
+
- lib/zip-container/container.rb
|
124
|
+
- lib/zip-container/dir.rb
|
108
125
|
- lib/zip-container/entries/directory.rb
|
109
126
|
- lib/zip-container/entries/entry.rb
|
110
127
|
- lib/zip-container/entries/file.rb
|
@@ -115,16 +132,21 @@ files:
|
|
115
132
|
- lib/zip-container/util.rb
|
116
133
|
- lib/zip-container/version.rb
|
117
134
|
- test/data/compressed_mimetype.container
|
135
|
+
- test/data/dirs/dir-mimetype/mimetype/.gitkeep
|
136
|
+
- test/data/dirs/empty/mimetype
|
137
|
+
- test/data/dirs/null/.gitkeep
|
118
138
|
- test/data/empty.container
|
119
139
|
- test/data/empty.zip
|
120
140
|
- test/data/example.container
|
121
141
|
- test/data/null.file
|
122
142
|
- test/data/subclassed.container
|
123
143
|
- test/helpers/entry_lists.rb
|
124
|
-
- test/
|
144
|
+
- test/tc_create_dir.rb
|
145
|
+
- test/tc_create_file.rb
|
125
146
|
- test/tc_exceptions.rb
|
126
147
|
- test/tc_managed_entries.rb
|
127
|
-
- test/
|
148
|
+
- test/tc_read_dir.rb
|
149
|
+
- test/tc_read_file.rb
|
128
150
|
- test/tc_reserved_names.rb
|
129
151
|
- test/tc_util.rb
|
130
152
|
- test/ts_container.rb
|
@@ -159,16 +181,21 @@ specification_version: 4
|
|
159
181
|
summary: A ZIP Container for use by OCF and UCF implementations
|
160
182
|
test_files:
|
161
183
|
- test/data/compressed_mimetype.container
|
184
|
+
- test/data/dirs/dir-mimetype/mimetype/.gitkeep
|
185
|
+
- test/data/dirs/empty/mimetype
|
186
|
+
- test/data/dirs/null/.gitkeep
|
162
187
|
- test/data/empty.container
|
163
188
|
- test/data/empty.zip
|
164
189
|
- test/data/example.container
|
165
190
|
- test/data/null.file
|
166
191
|
- test/data/subclassed.container
|
167
192
|
- test/helpers/entry_lists.rb
|
168
|
-
- test/
|
193
|
+
- test/tc_create_dir.rb
|
194
|
+
- test/tc_create_file.rb
|
169
195
|
- test/tc_exceptions.rb
|
170
196
|
- test/tc_managed_entries.rb
|
171
|
-
- test/
|
197
|
+
- test/tc_read_dir.rb
|
198
|
+
- test/tc_read_file.rb
|
172
199
|
- test/tc_reserved_names.rb
|
173
200
|
- test/tc_util.rb
|
174
201
|
- test/ts_container.rb
|