rubyzip 1.1.7 → 2.3.2
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 +5 -5
- data/README.md +137 -54
- data/Rakefile +6 -4
- data/lib/zip/central_directory.rb +17 -13
- data/lib/zip/compressor.rb +1 -2
- data/lib/zip/constants.rb +57 -5
- data/lib/zip/crypto/decrypted_io.rb +40 -0
- data/lib/zip/crypto/null_encryption.rb +4 -6
- data/lib/zip/crypto/traditional_encryption.rb +14 -14
- data/lib/zip/decompressor.rb +22 -4
- data/lib/zip/deflater.rb +8 -6
- data/lib/zip/dos_time.rb +17 -13
- data/lib/zip/entry.rb +171 -148
- data/lib/zip/entry_set.rb +16 -14
- data/lib/zip/errors.rb +3 -0
- data/lib/zip/extra_field/generic.rb +14 -13
- data/lib/zip/extra_field/ntfs.rb +18 -16
- data/lib/zip/extra_field/old_unix.rb +12 -11
- data/lib/zip/extra_field/universal_time.rb +46 -16
- data/lib/zip/extra_field/unix.rb +10 -9
- data/lib/zip/extra_field/zip64.rb +15 -12
- data/lib/zip/extra_field/zip64_placeholder.rb +1 -2
- data/lib/zip/extra_field.rb +18 -16
- data/lib/zip/file.rb +147 -115
- data/lib/zip/filesystem.rb +289 -272
- data/lib/zip/inflater.rb +24 -36
- data/lib/zip/input_stream.rb +44 -28
- data/lib/zip/ioextras/abstract_input_stream.rb +24 -17
- data/lib/zip/ioextras/abstract_output_stream.rb +4 -6
- data/lib/zip/ioextras.rb +2 -4
- data/lib/zip/null_compressor.rb +2 -2
- data/lib/zip/null_decompressor.rb +3 -11
- data/lib/zip/null_input_stream.rb +0 -0
- data/lib/zip/output_stream.rb +25 -17
- data/lib/zip/pass_thru_compressor.rb +6 -6
- data/lib/zip/pass_thru_decompressor.rb +14 -24
- data/lib/zip/streamable_directory.rb +3 -3
- data/lib/zip/streamable_stream.rb +7 -11
- data/lib/zip/version.rb +1 -1
- data/lib/zip.rb +15 -6
- data/samples/example.rb +29 -39
- data/samples/example_filesystem.rb +16 -18
- data/samples/example_recursive.rb +31 -25
- data/samples/gtk_ruby_zip.rb +84 -0
- data/samples/qtzip.rb +23 -32
- data/samples/write_simple.rb +10 -13
- data/samples/zipfind.rb +33 -40
- metadata +50 -141
- data/samples/gtkRubyzip.rb +0 -86
- data/test/basic_zip_file_test.rb +0 -64
- data/test/central_directory_entry_test.rb +0 -73
- data/test/central_directory_test.rb +0 -104
- data/test/crypto/null_encryption_test.rb +0 -53
- data/test/crypto/traditional_encryption_test.rb +0 -80
- data/test/data/WarnInvalidDate.zip +0 -0
- data/test/data/file1.txt +0 -46
- data/test/data/file1.txt.deflatedData +0 -0
- data/test/data/file2.txt +0 -1504
- data/test/data/globTest/foo/bar/baz/foo.txt +0 -0
- data/test/data/globTest/foo.txt +0 -0
- data/test/data/globTest/food.txt +0 -0
- data/test/data/globTest.zip +0 -0
- data/test/data/mimetype +0 -1
- data/test/data/notzippedruby.rb +0 -7
- data/test/data/ntfs.zip +0 -0
- data/test/data/rubycode.zip +0 -0
- data/test/data/rubycode2.zip +0 -0
- data/test/data/testDirectory.bin +0 -0
- data/test/data/zip64-sample.zip +0 -0
- data/test/data/zipWithDirs.zip +0 -0
- data/test/data/zipWithEncryption.zip +0 -0
- data/test/deflater_test.rb +0 -67
- data/test/encryption_test.rb +0 -42
- data/test/entry_set_test.rb +0 -138
- data/test/entry_test.rb +0 -165
- data/test/errors_test.rb +0 -36
- data/test/extra_field_test.rb +0 -78
- data/test/file_extract_directory_test.rb +0 -56
- data/test/file_extract_test.rb +0 -90
- data/test/file_split_test.rb +0 -60
- data/test/file_test.rb +0 -559
- data/test/filesystem/dir_iterator_test.rb +0 -62
- data/test/filesystem/directory_test.rb +0 -131
- data/test/filesystem/file_mutating_test.rb +0 -100
- data/test/filesystem/file_nonmutating_test.rb +0 -514
- data/test/filesystem/file_stat_test.rb +0 -66
- data/test/gentestfiles.rb +0 -134
- data/test/inflater_test.rb +0 -14
- data/test/input_stream_test.rb +0 -170
- data/test/ioextras/abstract_input_stream_test.rb +0 -103
- data/test/ioextras/abstract_output_stream_test.rb +0 -106
- data/test/ioextras/fake_io_test.rb +0 -18
- data/test/local_entry_test.rb +0 -156
- data/test/output_stream_test.rb +0 -129
- data/test/pass_thru_compressor_test.rb +0 -31
- data/test/pass_thru_decompressor_test.rb +0 -15
- data/test/settings_test.rb +0 -92
- data/test/test_helper.rb +0 -228
- data/test/unicode_file_names_and_comments_test.rb +0 -52
- data/test/zip64_full_test.rb +0 -53
- data/test/zip64_support_test.rb +0 -15
data/lib/zip/file.rb
CHANGED
@@ -43,58 +43,84 @@ module Zip
|
|
43
43
|
# interface for accessing the filesystem, ie. the File and Dir classes.
|
44
44
|
|
45
45
|
class File < CentralDirectory
|
46
|
-
|
47
|
-
CREATE = 1
|
46
|
+
CREATE = true
|
48
47
|
SPLIT_SIGNATURE = 0x08074b50
|
49
48
|
ZIP64_EOCD_SIGNATURE = 0x06064b50
|
50
|
-
MAX_SEGMENT_SIZE =
|
51
|
-
MIN_SEGMENT_SIZE =
|
49
|
+
MAX_SEGMENT_SIZE = 3_221_225_472
|
50
|
+
MIN_SEGMENT_SIZE = 65_536
|
52
51
|
DATA_BUFFER_SIZE = 8192
|
52
|
+
IO_METHODS = [:tell, :seek, :read, :eof, :close]
|
53
|
+
|
54
|
+
DEFAULT_OPTIONS = {
|
55
|
+
restore_ownership: false,
|
56
|
+
restore_permissions: false,
|
57
|
+
restore_times: false
|
58
|
+
}.freeze
|
53
59
|
|
54
60
|
attr_reader :name
|
55
61
|
|
56
|
-
# default -> false
|
62
|
+
# default -> false.
|
57
63
|
attr_accessor :restore_ownership
|
58
|
-
|
64
|
+
|
65
|
+
# default -> false, but will be set to true in a future version.
|
59
66
|
attr_accessor :restore_permissions
|
60
|
-
|
67
|
+
|
68
|
+
# default -> false, but will be set to true in a future version.
|
61
69
|
attr_accessor :restore_times
|
70
|
+
|
62
71
|
# Returns the zip files comment, if it has one
|
63
72
|
attr_accessor :comment
|
64
73
|
|
65
74
|
# Opens a zip archive. Pass true as the second parameter to create
|
66
75
|
# a new archive if it doesn't exist already.
|
67
|
-
def initialize(
|
76
|
+
def initialize(path_or_io, create = false, buffer = false, options = {})
|
68
77
|
super()
|
69
|
-
|
78
|
+
options = DEFAULT_OPTIONS.merge(options)
|
79
|
+
@name = path_or_io.respond_to?(:path) ? path_or_io.path : path_or_io
|
70
80
|
@comment = ''
|
71
|
-
@create = create
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
@
|
76
|
-
::File.
|
77
|
-
|
81
|
+
@create = create ? true : false # allow any truthy value to mean true
|
82
|
+
|
83
|
+
if ::File.size?(@name.to_s)
|
84
|
+
# There is a file, which exists, that is associated with this zip.
|
85
|
+
@create = false
|
86
|
+
@file_permissions = ::File.stat(@name).mode
|
87
|
+
|
88
|
+
if buffer
|
89
|
+
read_from_stream(path_or_io)
|
90
|
+
else
|
91
|
+
::File.open(@name, 'rb') do |f|
|
92
|
+
read_from_stream(f)
|
93
|
+
end
|
78
94
|
end
|
79
|
-
|
95
|
+
elsif buffer && path_or_io.size > 0
|
96
|
+
# This zip is probably a non-empty StringIO.
|
97
|
+
read_from_stream(path_or_io)
|
98
|
+
elsif @create
|
99
|
+
# This zip is completely new/empty and is to be created.
|
80
100
|
@entry_set = EntrySet.new
|
101
|
+
elsif ::File.zero?(@name)
|
102
|
+
# A file exists, but it is empty.
|
103
|
+
raise Error, "File #{@name} has zero size. Did you mean to pass the create flag?"
|
81
104
|
else
|
82
|
-
|
105
|
+
# Everything is wrong.
|
106
|
+
raise Error, "File #{@name} not found"
|
83
107
|
end
|
108
|
+
|
84
109
|
@stored_entries = @entry_set.dup
|
85
110
|
@stored_comment = @comment
|
86
|
-
@restore_ownership = options[:restore_ownership]
|
87
|
-
@restore_permissions = options[:restore_permissions]
|
88
|
-
@restore_times = options[:restore_times]
|
111
|
+
@restore_ownership = options[:restore_ownership]
|
112
|
+
@restore_permissions = options[:restore_permissions]
|
113
|
+
@restore_times = options[:restore_times]
|
89
114
|
end
|
90
115
|
|
91
116
|
class << self
|
92
|
-
#
|
93
|
-
# to the block and is automatically closed afterwards just as with
|
94
|
-
# ruby's builtin File
|
95
|
-
def open(file_name, create =
|
96
|
-
zf = ::Zip::File.new(file_name, create)
|
117
|
+
# Similar to ::new. If a block is passed the Zip::File object is passed
|
118
|
+
# to the block and is automatically closed afterwards, just as with
|
119
|
+
# ruby's builtin File::open method.
|
120
|
+
def open(file_name, create = false, options = {})
|
121
|
+
zf = ::Zip::File.new(file_name, create, false, options)
|
97
122
|
return zf unless block_given?
|
123
|
+
|
98
124
|
begin
|
99
125
|
yield zf
|
100
126
|
ensure
|
@@ -115,23 +141,24 @@ module Zip
|
|
115
141
|
# (This can be used to extract data from a
|
116
142
|
# downloaded zip archive without first saving it to disk.)
|
117
143
|
def open_buffer(io, options = {})
|
118
|
-
unless
|
119
|
-
raise "Zip::File.open_buffer expects
|
120
|
-
end
|
121
|
-
if io.is_a?(::String)
|
122
|
-
require 'stringio'
|
123
|
-
io = ::StringIO.new(io)
|
124
|
-
elsif io.is_a?(IO)
|
125
|
-
# https://github.com/rubyzip/rubyzip/issues/119
|
126
|
-
io.binmode
|
144
|
+
unless IO_METHODS.map { |method| io.respond_to?(method) }.all? || io.kind_of?(String)
|
145
|
+
raise "Zip::File.open_buffer expects a String or IO-like argument (responds to #{IO_METHODS.join(', ')}). Found: #{io.class}"
|
127
146
|
end
|
147
|
+
|
148
|
+
io = ::StringIO.new(io) if io.kind_of?(::String)
|
149
|
+
|
150
|
+
# https://github.com/rubyzip/rubyzip/issues/119
|
151
|
+
io.binmode if io.respond_to?(:binmode)
|
152
|
+
|
128
153
|
zf = ::Zip::File.new(io, true, true, options)
|
129
|
-
zf
|
154
|
+
return zf unless block_given?
|
155
|
+
|
130
156
|
yield zf
|
157
|
+
|
131
158
|
begin
|
132
159
|
zf.write_buffer(io)
|
133
160
|
rescue IOError => e
|
134
|
-
raise unless e.message ==
|
161
|
+
raise unless e.message == 'not opened for writing'
|
135
162
|
end
|
136
163
|
end
|
137
164
|
|
@@ -141,17 +168,16 @@ module Zip
|
|
141
168
|
# whereas ZipInputStream jumps through the entire archive accessing the
|
142
169
|
# local entry headers (which contain the same information as the
|
143
170
|
# central directory).
|
144
|
-
def foreach(
|
145
|
-
open(
|
146
|
-
|
171
|
+
def foreach(zip_file_name, &block)
|
172
|
+
::Zip::File.open(zip_file_name) do |zip_file|
|
173
|
+
zip_file.each(&block)
|
147
174
|
end
|
148
175
|
end
|
149
176
|
|
150
177
|
def get_segment_size_for_split(segment_size)
|
151
|
-
|
152
|
-
when MIN_SEGMENT_SIZE > segment_size
|
178
|
+
if MIN_SEGMENT_SIZE > segment_size
|
153
179
|
MIN_SEGMENT_SIZE
|
154
|
-
|
180
|
+
elsif MAX_SEGMENT_SIZE < segment_size
|
155
181
|
MAX_SEGMENT_SIZE
|
156
182
|
else
|
157
183
|
segment_size
|
@@ -159,8 +185,10 @@ module Zip
|
|
159
185
|
end
|
160
186
|
|
161
187
|
def get_partial_zip_file_name(zip_file_name, partial_zip_file_name)
|
162
|
-
partial_zip_file_name
|
163
|
-
|
188
|
+
unless partial_zip_file_name.nil?
|
189
|
+
partial_zip_file_name = zip_file_name.sub(/#{::File.basename(zip_file_name)}\z/,
|
190
|
+
partial_zip_file_name + ::File.extname(zip_file_name))
|
191
|
+
end
|
164
192
|
partial_zip_file_name ||= zip_file_name
|
165
193
|
partial_zip_file_name
|
166
194
|
end
|
@@ -181,7 +209,7 @@ module Zip
|
|
181
209
|
def save_splited_part(zip_file, partial_zip_file_name, zip_file_size, szip_file_index, segment_size, segment_count)
|
182
210
|
ssegment_size = zip_file_size - zip_file.pos
|
183
211
|
ssegment_size = segment_size if ssegment_size > segment_size
|
184
|
-
szip_file_name = "#{partial_zip_file_name}.#{'%03d'
|
212
|
+
szip_file_name = "#{partial_zip_file_name}.#{format('%03d', szip_file_index)}"
|
185
213
|
::File.open(szip_file_name, 'wb') do |szip_file|
|
186
214
|
if szip_file_index == 1
|
187
215
|
ssegment_size = put_split_signature(szip_file, segment_size)
|
@@ -191,7 +219,7 @@ module Zip
|
|
191
219
|
segment_bytes_left = ssegment_size - chunk_bytes
|
192
220
|
buffer_size = segment_bytes_left < DATA_BUFFER_SIZE ? segment_bytes_left : DATA_BUFFER_SIZE
|
193
221
|
chunk = zip_file.read(buffer_size)
|
194
|
-
chunk_bytes
|
222
|
+
chunk_bytes += buffer_size
|
195
223
|
szip_file << chunk
|
196
224
|
# Info for track splitting
|
197
225
|
yield segment_count, szip_file_index, chunk_bytes, ssegment_size if block_given?
|
@@ -203,12 +231,14 @@ module Zip
|
|
203
231
|
def split(zip_file_name, segment_size = MAX_SEGMENT_SIZE, delete_zip_file = true, partial_zip_file_name = nil)
|
204
232
|
raise Error, "File #{zip_file_name} not found" unless ::File.exist?(zip_file_name)
|
205
233
|
raise Errno::ENOENT, zip_file_name unless ::File.readable?(zip_file_name)
|
234
|
+
|
206
235
|
zip_file_size = ::File.size(zip_file_name)
|
207
236
|
segment_size = get_segment_size_for_split(segment_size)
|
208
237
|
return if zip_file_size <= segment_size
|
238
|
+
|
209
239
|
segment_count = get_segment_count_for_split(zip_file_size, segment_size)
|
210
240
|
# Checking for correct zip structure
|
211
|
-
|
241
|
+
::Zip::File.open(zip_file_name) {}
|
212
242
|
partial_zip_file_name = get_partial_zip_file_name(zip_file_name, partial_zip_file_name)
|
213
243
|
szip_file_index = 0
|
214
244
|
::File.open(zip_file_name, 'rb') do |zip_file|
|
@@ -222,12 +252,11 @@ module Zip
|
|
222
252
|
end
|
223
253
|
end
|
224
254
|
|
225
|
-
|
226
255
|
# Returns an input stream to the specified entry. If a block is passed
|
227
256
|
# the stream object is passed to the block and the stream is automatically
|
228
257
|
# closed afterwards just as with ruby's builtin File.open method.
|
229
|
-
def get_input_stream(entry, &
|
230
|
-
get_entry(entry).get_input_stream(&
|
258
|
+
def get_input_stream(entry, &a_proc)
|
259
|
+
get_entry(entry).get_input_stream(&a_proc)
|
231
260
|
end
|
232
261
|
|
233
262
|
# Returns an output stream to the specified entry. If entry is not an instance
|
@@ -235,7 +264,11 @@ module Zip
|
|
235
264
|
# specified. If a block is passed the stream object is passed to the block and
|
236
265
|
# the stream is automatically closed afterwards just as with ruby's builtin
|
237
266
|
# File.open method.
|
238
|
-
def get_output_stream(entry, permission_int = nil, comment = nil,
|
267
|
+
def get_output_stream(entry, permission_int = nil, comment = nil,
|
268
|
+
extra = nil, compressed_size = nil, crc = nil,
|
269
|
+
compression_method = nil, size = nil, time = nil,
|
270
|
+
&a_proc)
|
271
|
+
|
239
272
|
new_entry =
|
240
273
|
if entry.kind_of?(Entry)
|
241
274
|
entry
|
@@ -249,7 +282,7 @@ module Zip
|
|
249
282
|
new_entry.unix_perms = permission_int
|
250
283
|
zip_streamable_entry = StreamableStream.new(new_entry)
|
251
284
|
@entry_set << zip_streamable_entry
|
252
|
-
zip_streamable_entry.get_output_stream(&
|
285
|
+
zip_streamable_entry.get_output_stream(&a_proc)
|
253
286
|
end
|
254
287
|
|
255
288
|
# Returns the name of the zip archive
|
@@ -259,19 +292,26 @@ module Zip
|
|
259
292
|
|
260
293
|
# Returns a string containing the contents of the specified entry
|
261
294
|
def read(entry)
|
262
|
-
get_input_stream(entry
|
295
|
+
get_input_stream(entry, &:read)
|
263
296
|
end
|
264
297
|
|
265
298
|
# Convenience method for adding the contents of a file to the archive
|
266
299
|
def add(entry, src_path, &continue_on_exists_proc)
|
267
300
|
continue_on_exists_proc ||= proc { ::Zip.continue_on_exists_proc }
|
268
|
-
check_entry_exists(entry, continue_on_exists_proc,
|
301
|
+
check_entry_exists(entry, continue_on_exists_proc, 'add')
|
269
302
|
new_entry = entry.kind_of?(::Zip::Entry) ? entry : ::Zip::Entry.new(@name, entry.to_s)
|
270
303
|
new_entry.gather_fileinfo_from_srcpath(src_path)
|
271
304
|
new_entry.dirty = true
|
272
305
|
@entry_set << new_entry
|
273
306
|
end
|
274
307
|
|
308
|
+
# Convenience method for adding the contents of a file to the archive
|
309
|
+
# in Stored format (uncompressed)
|
310
|
+
def add_stored(entry, src_path, &continue_on_exists_proc)
|
311
|
+
entry = ::Zip::Entry.new(@name, entry.to_s, nil, nil, nil, nil, ::Zip::Entry::STORED)
|
312
|
+
add(entry, src_path, &continue_on_exists_proc)
|
313
|
+
end
|
314
|
+
|
275
315
|
# Removes the specified entry.
|
276
316
|
def remove(entry)
|
277
317
|
@entry_set.delete(get_entry(entry))
|
@@ -279,19 +319,19 @@ module Zip
|
|
279
319
|
|
280
320
|
# Renames the specified entry.
|
281
321
|
def rename(entry, new_name, &continue_on_exists_proc)
|
282
|
-
|
322
|
+
found_entry = get_entry(entry)
|
283
323
|
check_entry_exists(new_name, continue_on_exists_proc, 'rename')
|
284
|
-
@entry_set.delete(
|
285
|
-
|
286
|
-
@entry_set <<
|
324
|
+
@entry_set.delete(found_entry)
|
325
|
+
found_entry.name = new_name
|
326
|
+
@entry_set << found_entry
|
287
327
|
end
|
288
328
|
|
289
|
-
# Replaces the specified entry with the contents of
|
329
|
+
# Replaces the specified entry with the contents of src_path (from
|
290
330
|
# the file system).
|
291
|
-
def replace(entry,
|
292
|
-
check_file(
|
331
|
+
def replace(entry, src_path)
|
332
|
+
check_file(src_path)
|
293
333
|
remove(entry)
|
294
|
-
add(entry,
|
334
|
+
add(entry, src_path)
|
295
335
|
end
|
296
336
|
|
297
337
|
# Extracts entry to file dest_path.
|
@@ -304,7 +344,8 @@ module Zip
|
|
304
344
|
# Commits changes that has been made since the previous commit to
|
305
345
|
# the zip archive.
|
306
346
|
def commit
|
307
|
-
return
|
347
|
+
return if name.kind_of?(StringIO) || !commit_required?
|
348
|
+
|
308
349
|
on_success_replace do |tmp_file|
|
309
350
|
::Zip::OutputStream.open(tmp_file) do |zos|
|
310
351
|
@entry_set.each do |e|
|
@@ -338,13 +379,19 @@ module Zip
|
|
338
379
|
@entry_set.each do |e|
|
339
380
|
return true if e.dirty
|
340
381
|
end
|
341
|
-
@comment != @stored_comment || @entry_set != @stored_entries || @create
|
382
|
+
@comment != @stored_comment || @entry_set != @stored_entries || @create
|
342
383
|
end
|
343
384
|
|
344
385
|
# Searches for entry with the specified name. Returns nil if
|
345
386
|
# no entry is found. See also get_entry
|
346
387
|
def find_entry(entry_name)
|
347
|
-
@entry_set.find_entry(entry_name)
|
388
|
+
selected_entry = @entry_set.find_entry(entry_name)
|
389
|
+
return if selected_entry.nil?
|
390
|
+
|
391
|
+
selected_entry.restore_ownership = @restore_ownership
|
392
|
+
selected_entry.restore_permissions = @restore_permissions
|
393
|
+
selected_entry.restore_times = @restore_times
|
394
|
+
selected_entry
|
348
395
|
end
|
349
396
|
|
350
397
|
# Searches for entries given a glob
|
@@ -356,78 +403,63 @@ module Zip
|
|
356
403
|
# if no entry is found.
|
357
404
|
def get_entry(entry)
|
358
405
|
selected_entry = find_entry(entry)
|
359
|
-
|
360
|
-
|
361
|
-
end
|
362
|
-
selected_entry.restore_ownership = @restore_ownership
|
363
|
-
selected_entry.restore_permissions = @restore_permissions
|
364
|
-
selected_entry.restore_times = @restore_times
|
406
|
+
raise Errno::ENOENT, entry if selected_entry.nil?
|
407
|
+
|
365
408
|
selected_entry
|
366
409
|
end
|
367
410
|
|
368
411
|
# Creates a directory
|
369
|
-
def mkdir(
|
370
|
-
if find_entry(
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
@entry_set << ::Zip::StreamableDirectory.new(@name, entryName, nil, permissionInt)
|
412
|
+
def mkdir(entry_name, permission = 0o755)
|
413
|
+
raise Errno::EEXIST, "File exists - #{entry_name}" if find_entry(entry_name)
|
414
|
+
|
415
|
+
entry_name = entry_name.dup.to_s
|
416
|
+
entry_name << '/' unless entry_name.end_with?('/')
|
417
|
+
@entry_set << ::Zip::StreamableDirectory.new(@name, entry_name, nil, permission)
|
376
418
|
end
|
377
419
|
|
378
420
|
private
|
379
421
|
|
380
|
-
def
|
381
|
-
|
382
|
-
if
|
422
|
+
def directory?(new_entry, src_path)
|
423
|
+
path_is_directory = ::File.directory?(src_path)
|
424
|
+
if new_entry.directory? && !path_is_directory
|
383
425
|
raise ArgumentError,
|
384
|
-
"entry name '#{
|
385
|
-
|
386
|
-
elsif !
|
387
|
-
|
426
|
+
"entry name '#{new_entry}' indicates directory entry, but " \
|
427
|
+
"'#{src_path}' is not a directory"
|
428
|
+
elsif !new_entry.directory? && path_is_directory
|
429
|
+
new_entry.name += '/'
|
388
430
|
end
|
389
|
-
|
431
|
+
new_entry.directory? && path_is_directory
|
390
432
|
end
|
391
433
|
|
392
|
-
def check_entry_exists(
|
434
|
+
def check_entry_exists(entry_name, continue_on_exists_proc, proc_name)
|
393
435
|
continue_on_exists_proc ||= proc { Zip.continue_on_exists_proc }
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
436
|
+
return unless @entry_set.include?(entry_name)
|
437
|
+
|
438
|
+
if continue_on_exists_proc.call
|
439
|
+
remove get_entry(entry_name)
|
440
|
+
else
|
441
|
+
raise ::Zip::EntryExistsError,
|
442
|
+
proc_name + " failed. Entry #{entry_name} already exists"
|
401
443
|
end
|
402
444
|
end
|
403
445
|
|
404
446
|
def check_file(path)
|
405
|
-
unless ::File.readable?(path)
|
406
|
-
raise Errno::ENOENT, path
|
407
|
-
end
|
447
|
+
raise Errno::ENOENT, path unless ::File.readable?(path)
|
408
448
|
end
|
409
449
|
|
410
450
|
def on_success_replace
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
451
|
+
dirname, basename = ::File.split(name)
|
452
|
+
::Dir::Tmpname.create(basename, dirname) do |tmp_filename|
|
453
|
+
begin
|
454
|
+
if yield tmp_filename
|
455
|
+
::File.rename(tmp_filename, name)
|
456
|
+
::File.chmod(@file_permissions, name) unless @create
|
457
|
+
end
|
458
|
+
ensure
|
459
|
+
::File.unlink(tmp_filename) if ::File.exist?(tmp_filename)
|
419
460
|
end
|
420
461
|
end
|
421
|
-
ensure
|
422
|
-
tmpfile.unlink if tmpfile
|
423
462
|
end
|
424
|
-
|
425
|
-
def get_tempfile
|
426
|
-
temp_file = Tempfile.new(::File.basename(name), ::File.dirname(name))
|
427
|
-
temp_file.binmode
|
428
|
-
temp_file
|
429
|
-
end
|
430
|
-
|
431
463
|
end
|
432
464
|
end
|
433
465
|
|