rubyzip 2.4.1 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Changelog.md +495 -0
- data/LICENSE.md +24 -0
- data/README.md +180 -40
- data/Rakefile +15 -13
- data/lib/zip/central_directory.rb +179 -125
- data/lib/zip/compressor.rb +3 -1
- data/lib/zip/constants.rb +29 -21
- data/lib/zip/crypto/aes_encryption.rb +120 -0
- data/lib/zip/crypto/decrypted_io.rb +21 -15
- data/lib/zip/crypto/encryption.rb +4 -2
- data/lib/zip/crypto/null_encryption.rb +5 -13
- data/lib/zip/crypto/traditional_encryption.rb +10 -6
- data/lib/zip/decompressor.rb +4 -3
- data/lib/zip/deflater.rb +12 -8
- data/lib/zip/dirtyable.rb +32 -0
- data/lib/zip/dos_time.rb +45 -5
- data/lib/zip/entry.rb +392 -266
- data/lib/zip/entry_set.rb +11 -9
- data/lib/zip/errors.rb +136 -16
- data/lib/zip/extra_field/aes.rb +50 -0
- data/lib/zip/extra_field/generic.rb +10 -11
- data/lib/zip/extra_field/ntfs.rb +6 -4
- data/lib/zip/extra_field/old_unix.rb +3 -1
- data/lib/zip/extra_field/universal_time.rb +3 -1
- data/lib/zip/extra_field/unix.rb +5 -3
- data/lib/zip/extra_field/unknown.rb +35 -0
- data/lib/zip/extra_field/zip64.rb +19 -5
- data/lib/zip/extra_field.rb +25 -23
- data/lib/zip/file.rb +174 -267
- data/lib/zip/file_split.rb +91 -0
- data/lib/zip/filesystem/dir.rb +86 -0
- data/lib/zip/filesystem/directory_iterator.rb +48 -0
- data/lib/zip/filesystem/file.rb +263 -0
- data/lib/zip/filesystem/file_stat.rb +110 -0
- data/lib/zip/filesystem/zip_file_name_mapper.rb +81 -0
- data/lib/zip/filesystem.rb +27 -596
- data/lib/zip/inflater.rb +13 -10
- data/lib/zip/input_stream.rb +98 -60
- data/lib/zip/ioextras/abstract_input_stream.rb +146 -58
- data/lib/zip/ioextras/abstract_output_stream.rb +13 -3
- data/lib/zip/ioextras.rb +7 -7
- data/lib/zip/null_compressor.rb +3 -1
- data/lib/zip/null_decompressor.rb +6 -3
- data/lib/zip/null_input_stream.rb +3 -1
- data/lib/zip/output_stream.rb +60 -57
- data/lib/zip/pass_thru_compressor.rb +3 -1
- data/lib/zip/pass_thru_decompressor.rb +12 -9
- data/lib/zip/streamable_directory.rb +3 -1
- data/lib/zip/streamable_stream.rb +4 -1
- data/lib/zip/version.rb +4 -1
- data/lib/zip.rb +25 -22
- data/rubyzip.gemspec +39 -0
- data/samples/example.rb +8 -3
- data/samples/example_filesystem.rb +3 -2
- data/samples/example_recursive.rb +3 -1
- data/samples/gtk_ruby_zip.rb +5 -3
- data/samples/qtzip.rb +7 -6
- data/samples/write_simple.rb +2 -1
- data/samples/zipfind.rb +1 -0
- metadata +86 -52
- data/TODO +0 -15
- data/lib/zip/extra_field/zip64_placeholder.rb +0 -15
data/lib/zip/output_stream.rb
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
##
|
|
1
6
|
module Zip
|
|
2
7
|
# ZipOutputStream is the basic class for writing zip files. It is
|
|
3
8
|
# possible to create a ZipOutputStream object directly, passing
|
|
@@ -16,57 +21,52 @@ module Zip
|
|
|
16
21
|
#
|
|
17
22
|
# java.util.zip.ZipOutputStream is the original inspiration for this
|
|
18
23
|
# class.
|
|
19
|
-
|
|
20
24
|
class OutputStream
|
|
25
|
+
extend Forwardable
|
|
21
26
|
include ::Zip::IOExtras::AbstractOutputStream
|
|
22
27
|
|
|
23
|
-
|
|
28
|
+
def_delegators :@cdir, :comment, :comment=
|
|
24
29
|
|
|
25
30
|
# Opens the indicated zip file. If a file with that name already
|
|
26
31
|
# exists it will be overwritten.
|
|
27
|
-
def initialize(file_name,
|
|
32
|
+
def initialize(file_name, stream: false, encrypter: nil, suppress_extra_fields: false)
|
|
28
33
|
super()
|
|
29
|
-
|
|
30
|
-
Zip.warn_about_v3_api('Zip::OutputStream.new') if dep_stream || !dep_encrypter.nil?
|
|
31
|
-
|
|
32
34
|
@file_name = file_name
|
|
33
|
-
@output_stream = if stream
|
|
34
|
-
iostream = @file_name.dup
|
|
35
|
+
@output_stream = if stream
|
|
36
|
+
iostream = Zip::RUNNING_ON_WINDOWS ? @file_name : @file_name.dup
|
|
35
37
|
iostream.reopen(@file_name)
|
|
36
38
|
iostream.rewind
|
|
37
39
|
iostream
|
|
38
40
|
else
|
|
39
41
|
::File.new(@file_name, 'wb')
|
|
40
42
|
end
|
|
41
|
-
@
|
|
43
|
+
@cdir = ::Zip::CentralDirectory.new
|
|
42
44
|
@compressor = ::Zip::NullCompressor.instance
|
|
43
|
-
@encrypter = encrypter ||
|
|
45
|
+
@encrypter = encrypter || ::Zip::NullEncrypter.new
|
|
46
|
+
@suppress_extra_fields = suppress_extra_fields
|
|
44
47
|
@closed = false
|
|
45
48
|
@current_entry = nil
|
|
46
|
-
@comment = nil
|
|
47
49
|
end
|
|
48
50
|
|
|
49
|
-
# Same as #initialize but if a block is passed the opened
|
|
50
|
-
# stream is passed to the block and closed when the block
|
|
51
|
-
# returns.
|
|
52
51
|
class << self
|
|
53
|
-
|
|
52
|
+
# Same as #initialize but if a block is passed the opened
|
|
53
|
+
# stream is passed to the block and closed when the block
|
|
54
|
+
# returns.
|
|
55
|
+
def open(file_name, encrypter: nil, suppress_extra_fields: false)
|
|
54
56
|
return new(file_name) unless block_given?
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
zos = new(file_name, stream: false, encrypter: (encrypter || dep_encrypter))
|
|
58
|
+
zos = new(file_name, stream: false, encrypter: encrypter,
|
|
59
|
+
suppress_extra_fields: suppress_extra_fields)
|
|
59
60
|
yield zos
|
|
60
61
|
ensure
|
|
61
62
|
zos.close if zos
|
|
62
63
|
end
|
|
63
64
|
|
|
64
65
|
# Same as #open but writes to a filestream instead
|
|
65
|
-
def write_buffer(io = ::StringIO.new,
|
|
66
|
-
Zip.warn_about_v3_api('Zip::OutputStream.write_buffer') unless dep_encrypter.nil?
|
|
67
|
-
|
|
66
|
+
def write_buffer(io = ::StringIO.new, encrypter: nil, suppress_extra_fields: false)
|
|
68
67
|
io.binmode if io.respond_to?(:binmode)
|
|
69
|
-
zos = new(io, stream: true, encrypter:
|
|
68
|
+
zos = new(io, stream: true, encrypter: encrypter,
|
|
69
|
+
suppress_extra_fields: suppress_extra_fields)
|
|
70
70
|
yield zos
|
|
71
71
|
zos.close_buffer
|
|
72
72
|
end
|
|
@@ -78,7 +78,7 @@ module Zip
|
|
|
78
78
|
|
|
79
79
|
finalize_current_entry
|
|
80
80
|
update_local_headers
|
|
81
|
-
|
|
81
|
+
@cdir.write_to_stream(@output_stream, suppress_extra_fields: @suppress_extra_fields)
|
|
82
82
|
@output_stream.close
|
|
83
83
|
@closed = true
|
|
84
84
|
end
|
|
@@ -89,37 +89,41 @@ module Zip
|
|
|
89
89
|
|
|
90
90
|
finalize_current_entry
|
|
91
91
|
update_local_headers
|
|
92
|
-
|
|
92
|
+
@cdir.write_to_stream(@output_stream, suppress_extra_fields: @suppress_extra_fields)
|
|
93
93
|
@closed = true
|
|
94
|
+
@output_stream.flush
|
|
94
95
|
@output_stream
|
|
95
96
|
end
|
|
96
97
|
|
|
97
98
|
# Closes the current entry and opens a new for writing.
|
|
98
99
|
# +entry+ can be a ZipEntry object or a string.
|
|
99
|
-
def put_next_entry(
|
|
100
|
+
def put_next_entry(
|
|
101
|
+
entry_name, comment = '', extra = ExtraField.new,
|
|
102
|
+
compression_method = Entry::DEFLATED, level = Zip.default_compression
|
|
103
|
+
)
|
|
100
104
|
raise Error, 'zip stream is closed' if @closed
|
|
101
105
|
|
|
102
|
-
new_entry =
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
init_next_entry(new_entry
|
|
106
|
+
new_entry =
|
|
107
|
+
if entry_name.kind_of?(Entry) || entry_name.kind_of?(StreamableStream)
|
|
108
|
+
entry_name
|
|
109
|
+
else
|
|
110
|
+
Entry.new(
|
|
111
|
+
@file_name, entry_name.to_s, comment: comment, extra: extra,
|
|
112
|
+
compression_method: compression_method, compression_level: level
|
|
113
|
+
)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
init_next_entry(new_entry)
|
|
113
117
|
@current_entry = new_entry
|
|
114
118
|
end
|
|
115
119
|
|
|
116
|
-
def copy_raw_entry(entry)
|
|
120
|
+
def copy_raw_entry(entry) # :nodoc:
|
|
117
121
|
entry = entry.dup
|
|
118
122
|
raise Error, 'zip stream is closed' if @closed
|
|
119
123
|
raise Error, 'entry is not a ZipEntry' unless entry.kind_of?(Entry)
|
|
120
124
|
|
|
121
125
|
finalize_current_entry
|
|
122
|
-
@
|
|
126
|
+
@cdir << entry
|
|
123
127
|
src_pos = entry.local_header_offset
|
|
124
128
|
entry.write_local_entry(@output_stream)
|
|
125
129
|
@compressor = NullCompressor.instance
|
|
@@ -138,55 +142,54 @@ module Zip
|
|
|
138
142
|
return unless @current_entry
|
|
139
143
|
|
|
140
144
|
finish
|
|
141
|
-
@current_entry.compressed_size = @output_stream.tell -
|
|
142
|
-
@current_entry.local_header_offset -
|
|
145
|
+
@current_entry.compressed_size = @output_stream.tell -
|
|
146
|
+
@current_entry.local_header_offset -
|
|
143
147
|
@current_entry.calculate_local_header_size
|
|
144
148
|
@current_entry.size = @compressor.size
|
|
145
149
|
@current_entry.crc = @compressor.crc
|
|
146
|
-
@output_stream << @encrypter.data_descriptor(
|
|
150
|
+
@output_stream << @encrypter.data_descriptor(
|
|
151
|
+
@current_entry.crc,
|
|
152
|
+
@current_entry.compressed_size,
|
|
153
|
+
@current_entry.size
|
|
154
|
+
)
|
|
147
155
|
@current_entry.gp_flags |= @encrypter.gp_flags
|
|
148
156
|
@current_entry = nil
|
|
149
157
|
@compressor = ::Zip::NullCompressor.instance
|
|
150
158
|
end
|
|
151
159
|
|
|
152
|
-
def init_next_entry(entry
|
|
160
|
+
def init_next_entry(entry)
|
|
153
161
|
finalize_current_entry
|
|
154
|
-
@
|
|
155
|
-
entry.write_local_entry(@output_stream)
|
|
162
|
+
@cdir << entry
|
|
163
|
+
entry.write_local_entry(@output_stream, suppress_extra_fields: @suppress_extra_fields)
|
|
156
164
|
@encrypter.reset!
|
|
157
165
|
@output_stream << @encrypter.header(entry.mtime)
|
|
158
|
-
@compressor = get_compressor(entry
|
|
166
|
+
@compressor = get_compressor(entry)
|
|
159
167
|
end
|
|
160
168
|
|
|
161
|
-
def get_compressor(entry
|
|
169
|
+
def get_compressor(entry)
|
|
162
170
|
case entry.compression_method
|
|
163
171
|
when Entry::DEFLATED
|
|
164
|
-
::Zip::Deflater.new(@output_stream,
|
|
172
|
+
::Zip::Deflater.new(@output_stream, entry.compression_level, @encrypter)
|
|
165
173
|
when Entry::STORED
|
|
166
174
|
::Zip::PassThruCompressor.new(@output_stream)
|
|
167
175
|
else
|
|
168
|
-
raise ::Zip::CompressionMethodError,
|
|
169
|
-
"Invalid compression method: '#{entry.compression_method}'"
|
|
176
|
+
raise ::Zip::CompressionMethodError, entry.compression_method
|
|
170
177
|
end
|
|
171
178
|
end
|
|
172
179
|
|
|
173
180
|
def update_local_headers
|
|
174
181
|
pos = @output_stream.pos
|
|
175
|
-
@
|
|
182
|
+
@cdir.each do |entry|
|
|
176
183
|
@output_stream.pos = entry.local_header_offset
|
|
177
|
-
entry.write_local_entry(@output_stream,
|
|
184
|
+
entry.write_local_entry(@output_stream, suppress_extra_fields: @suppress_extra_fields,
|
|
185
|
+
rewrite: true)
|
|
178
186
|
end
|
|
179
187
|
@output_stream.pos = pos
|
|
180
188
|
end
|
|
181
189
|
|
|
182
|
-
def write_central_directory
|
|
183
|
-
cdir = CentralDirectory.new(@entry_set, @comment)
|
|
184
|
-
cdir.write_to_stream(@output_stream)
|
|
185
|
-
end
|
|
186
|
-
|
|
187
190
|
protected
|
|
188
191
|
|
|
189
|
-
def finish
|
|
192
|
+
def finish # :nodoc:
|
|
190
193
|
@compressor.finish
|
|
191
194
|
end
|
|
192
195
|
|
|
@@ -1,26 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Zip
|
|
2
|
-
class PassThruDecompressor < Decompressor
|
|
4
|
+
class PassThruDecompressor < Decompressor # :nodoc:all
|
|
3
5
|
def initialize(*args)
|
|
4
6
|
super
|
|
5
7
|
@read_so_far = 0
|
|
6
8
|
end
|
|
7
9
|
|
|
8
|
-
def read(
|
|
9
|
-
return (
|
|
10
|
+
def read(maxlen = nil)
|
|
11
|
+
return (maxlen.nil? || maxlen.zero? ? '' : nil) if eof?
|
|
10
12
|
|
|
11
|
-
if
|
|
12
|
-
|
|
13
|
+
if maxlen.nil? || (@read_so_far + maxlen) > decompressed_size
|
|
14
|
+
maxlen = decompressed_size - @read_so_far
|
|
13
15
|
end
|
|
14
16
|
|
|
15
|
-
@read_so_far +=
|
|
16
|
-
input_stream.read(
|
|
17
|
+
@read_so_far += maxlen
|
|
18
|
+
input_stream.read(maxlen)
|
|
17
19
|
end
|
|
18
20
|
|
|
19
|
-
def eof
|
|
21
|
+
def eof?
|
|
20
22
|
@read_so_far >= decompressed_size
|
|
21
23
|
end
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
# Alias for compatibility. Remove for version 4.
|
|
26
|
+
alias eof eof?
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_STORE, ::Zip::PassThruDecompressor)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Zip
|
|
2
4
|
class StreamableStream < DelegateClass(Entry) # :nodoc:all
|
|
3
5
|
def initialize(entry)
|
|
4
|
-
super
|
|
6
|
+
super
|
|
5
7
|
@temp_file = Tempfile.new(::File.basename(name))
|
|
6
8
|
@temp_file.binmode
|
|
7
9
|
end
|
|
@@ -42,6 +44,7 @@ module Zip
|
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
def clean_up
|
|
47
|
+
super
|
|
45
48
|
@temp_file.unlink
|
|
46
49
|
end
|
|
47
50
|
end
|
data/lib/zip/version.rb
CHANGED
data/lib/zip.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'English'
|
|
2
4
|
require 'delegate'
|
|
3
5
|
require 'singleton'
|
|
@@ -5,6 +7,7 @@ require 'tempfile'
|
|
|
5
7
|
require 'fileutils'
|
|
6
8
|
require 'stringio'
|
|
7
9
|
require 'zlib'
|
|
10
|
+
require 'zip/version'
|
|
8
11
|
require 'zip/constants'
|
|
9
12
|
require 'zip/dos_time'
|
|
10
13
|
require 'zip/ioextras'
|
|
@@ -27,33 +30,21 @@ require 'zip/crypto/decrypted_io'
|
|
|
27
30
|
require 'zip/crypto/encryption'
|
|
28
31
|
require 'zip/crypto/null_encryption'
|
|
29
32
|
require 'zip/crypto/traditional_encryption'
|
|
33
|
+
require 'zip/crypto/aes_encryption'
|
|
30
34
|
require 'zip/inflater'
|
|
31
35
|
require 'zip/deflater'
|
|
32
36
|
require 'zip/streamable_stream'
|
|
33
37
|
require 'zip/streamable_directory'
|
|
34
38
|
require 'zip/errors'
|
|
35
39
|
|
|
40
|
+
# Rubyzip is a ruby module for reading and writing zip files.
|
|
41
|
+
#
|
|
42
|
+
# The main entry points are File, InputStream and OutputStream. For a
|
|
43
|
+
# file/directory interface in the style of the standard ruby ::File and
|
|
44
|
+
# ::Dir APIs then `require 'zip/filesystem'` and see FileSystem.
|
|
36
45
|
module Zip
|
|
37
|
-
V3_API_WARNING_MSG = <<~END_MSG
|
|
38
|
-
You have called '%s' (from %s).
|
|
39
|
-
This method is changing or deprecated in version 3.0.0. Please see
|
|
40
|
-
https://github.com/rubyzip/rubyzip/wiki/Updating-to-version-3.x
|
|
41
|
-
for more information.
|
|
42
|
-
END_MSG
|
|
43
|
-
|
|
44
|
-
def self.warn_about_v3_api(method)
|
|
45
|
-
return unless ENV['RUBYZIP_V3_API_WARN']
|
|
46
|
-
|
|
47
|
-
loc = caller_locations(2, 1)[0]
|
|
48
|
-
from = "#{loc.path.split('/').last}:#{loc.lineno}"
|
|
49
|
-
warn format(V3_API_WARNING_MSG, method, from)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
if ENV['RUBYZIP_V3_API_WARN'] && RUBY_VERSION < '3.0'
|
|
53
|
-
warn 'RubyZip 3.0 will require Ruby 3.0 or later.'
|
|
54
|
-
end
|
|
55
|
-
|
|
56
46
|
extend self
|
|
47
|
+
|
|
57
48
|
attr_accessor :unicode_names,
|
|
58
49
|
:on_exists_proc,
|
|
59
50
|
:continue_on_exists_proc,
|
|
@@ -65,19 +56,31 @@ module Zip
|
|
|
65
56
|
:force_entry_names_encoding,
|
|
66
57
|
:validate_entry_sizes
|
|
67
58
|
|
|
68
|
-
|
|
59
|
+
DEFAULT_RESTORE_OPTIONS = {
|
|
60
|
+
restore_ownership: false,
|
|
61
|
+
restore_permissions: true,
|
|
62
|
+
restore_times: true
|
|
63
|
+
}.freeze # :nodoc:
|
|
64
|
+
|
|
65
|
+
# :nodoc:
|
|
66
|
+
# Remove this when JRuby#3962 is fixed.
|
|
67
|
+
ZLIB_FLUSHING_STRATEGY = defined?(JRUBY_VERSION) ? Zlib::SYNC_FLUSH : Zlib::NO_FLUSH
|
|
68
|
+
|
|
69
|
+
def reset! # :nodoc:
|
|
69
70
|
@_ran_once = false
|
|
70
71
|
@unicode_names = false
|
|
71
72
|
@on_exists_proc = false
|
|
72
73
|
@continue_on_exists_proc = false
|
|
73
74
|
@sort_entries = false
|
|
74
|
-
@default_compression =
|
|
75
|
-
@write_zip64_support =
|
|
75
|
+
@default_compression = Zlib::DEFAULT_COMPRESSION
|
|
76
|
+
@write_zip64_support = true
|
|
76
77
|
@warn_invalid_date = true
|
|
77
78
|
@case_insensitive_match = false
|
|
79
|
+
@force_entry_names_encoding = nil
|
|
78
80
|
@validate_entry_sizes = true
|
|
79
81
|
end
|
|
80
82
|
|
|
83
|
+
# Set options for RubyZip in one block.
|
|
81
84
|
def setup
|
|
82
85
|
yield self unless @_ran_once
|
|
83
86
|
@_ran_once = true
|
data/rubyzip.gemspec
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/zip/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = 'rubyzip'
|
|
7
|
+
s.version = Zip::VERSION
|
|
8
|
+
s.authors = ['Robert Haines', 'John Lees-Miller', 'Alexander Simonov']
|
|
9
|
+
s.email = [
|
|
10
|
+
'hainesr@gmail.com', 'jdleesmiller@gmail.com', 'alex@simonov.me'
|
|
11
|
+
]
|
|
12
|
+
s.homepage = 'http://github.com/rubyzip/rubyzip'
|
|
13
|
+
s.platform = Gem::Platform::RUBY
|
|
14
|
+
s.summary = 'rubyzip is a ruby module for reading and writing zip files'
|
|
15
|
+
s.files = Dir.glob('{samples,lib}/**/*.rb') +
|
|
16
|
+
%w[LICENSE.md README.md Changelog.md Rakefile rubyzip.gemspec]
|
|
17
|
+
s.require_paths = ['lib']
|
|
18
|
+
s.license = 'BSD-2-Clause'
|
|
19
|
+
|
|
20
|
+
s.metadata = {
|
|
21
|
+
'bug_tracker_uri' => 'https://github.com/rubyzip/rubyzip/issues',
|
|
22
|
+
'changelog_uri' => "https://github.com/rubyzip/rubyzip/blob/v#{s.version}/Changelog.md",
|
|
23
|
+
'documentation_uri' => "https://www.rubydoc.info/gems/rubyzip/#{s.version}",
|
|
24
|
+
'source_code_uri' => "https://github.com/rubyzip/rubyzip/tree/v#{s.version}",
|
|
25
|
+
'wiki_uri' => 'https://github.com/rubyzip/rubyzip/wiki',
|
|
26
|
+
'rubygems_mfa_required' => 'true'
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
s.required_ruby_version = '>= 3.0'
|
|
30
|
+
|
|
31
|
+
s.add_development_dependency 'minitest', '~> 5.25'
|
|
32
|
+
s.add_development_dependency 'rake', '~> 13.2'
|
|
33
|
+
s.add_development_dependency 'rdoc', '~> 6.11'
|
|
34
|
+
s.add_development_dependency 'rubocop', '~> 1.80.2'
|
|
35
|
+
s.add_development_dependency 'rubocop-performance', '~> 1.26.0'
|
|
36
|
+
s.add_development_dependency 'rubocop-rake', '~> 0.7.1'
|
|
37
|
+
s.add_development_dependency 'simplecov', '~> 0.22.0'
|
|
38
|
+
s.add_development_dependency 'simplecov-lcov', '~> 0.8'
|
|
39
|
+
end
|
data/samples/example.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$LOAD_PATH << '../lib'
|
|
4
5
|
system('zip example.zip example.rb gtk_ruby_zip.rb')
|
|
@@ -20,7 +21,8 @@ end
|
|
|
20
21
|
|
|
21
22
|
zf = Zip::File.new('example.zip')
|
|
22
23
|
zf.each_with_index do |entry, index|
|
|
23
|
-
puts "entry #{index} is #{entry.name}, size = #{entry.size},
|
|
24
|
+
puts "entry #{index} is #{entry.name}, size = #{entry.size}, " \
|
|
25
|
+
"compressed size = #{entry.compressed_size}"
|
|
24
26
|
# use zf.get_input_stream(entry) to get a ZipInputStream for the entry
|
|
25
27
|
# entry can be the ZipEntry object or any object which has a to_s method that
|
|
26
28
|
# returns the name of the entry.
|
|
@@ -70,8 +72,11 @@ part_zips_count = Zip::File.split('large_zip_file.zip', 2_097_152, false)
|
|
|
70
72
|
puts "Zip file splitted in #{part_zips_count} parts"
|
|
71
73
|
|
|
72
74
|
# Track splitting an archive
|
|
73
|
-
Zip::File.split(
|
|
74
|
-
|
|
75
|
+
Zip::File.split(
|
|
76
|
+
'large_zip_file.zip', 1_048_576, true, 'part_zip_file'
|
|
77
|
+
) do |part_count, part_index, chunk_bytes, segment_bytes|
|
|
78
|
+
puts "#{part_index} of #{part_count} part splitting: " \
|
|
79
|
+
"#{(chunk_bytes.to_f / segment_bytes * 100).to_i}%"
|
|
75
80
|
end
|
|
76
81
|
|
|
77
82
|
# For other examples, look at zip.rb and ziptest.rb
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$LOAD_PATH << '../lib'
|
|
4
5
|
|
|
@@ -6,9 +7,9 @@ require 'zip/filesystem'
|
|
|
6
7
|
|
|
7
8
|
EXAMPLE_ZIP = 'filesystem.zip'
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
FileUtils.rm_f(EXAMPLE_ZIP)
|
|
10
11
|
|
|
11
|
-
Zip::File.open(EXAMPLE_ZIP,
|
|
12
|
+
Zip::File.open(EXAMPLE_ZIP, create: true) do |zf|
|
|
12
13
|
zf.file.open('file1.txt', 'w') { |os| os.write 'first file1.txt' }
|
|
13
14
|
zf.dir.mkdir('dir1')
|
|
14
15
|
zf.dir.chdir('dir1')
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'zip'
|
|
2
4
|
|
|
3
5
|
# This is a simple example which uses rubyzip to
|
|
@@ -21,7 +23,7 @@ class ZipFileGenerator
|
|
|
21
23
|
def write
|
|
22
24
|
entries = Dir.entries(@input_dir) - %w[. ..]
|
|
23
25
|
|
|
24
|
-
::Zip::File.open(@output_file,
|
|
26
|
+
::Zip::File.open(@output_file, create: true) do |zipfile|
|
|
25
27
|
write_entries entries, '', zipfile
|
|
26
28
|
end
|
|
27
29
|
end
|
data/samples/gtk_ruby_zip.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$LOAD_PATH << '../lib'
|
|
4
5
|
|
|
@@ -9,7 +10,7 @@ require 'zip'
|
|
|
9
10
|
|
|
10
11
|
class MainApp < Gtk::Window
|
|
11
12
|
def initialize
|
|
12
|
-
super
|
|
13
|
+
super
|
|
13
14
|
set_usize(400, 256)
|
|
14
15
|
set_title('rubyzip')
|
|
15
16
|
signal_connect(Gtk::Window::SIGNAL_DESTROY) { Gtk.main_quit }
|
|
@@ -42,7 +43,8 @@ class MainApp < Gtk::Window
|
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
class ButtonPanel < Gtk::HButtonBox
|
|
45
|
-
attr_reader :
|
|
46
|
+
attr_reader :extract_button, :open_button
|
|
47
|
+
|
|
46
48
|
def initialize
|
|
47
49
|
super
|
|
48
50
|
set_layout(Gtk::BUTTONBOX_START)
|
|
@@ -72,7 +74,7 @@ class MainApp < Gtk::Window
|
|
|
72
74
|
@zipfile.each do |entry|
|
|
73
75
|
@clist.append([entry.name,
|
|
74
76
|
entry.size.to_s,
|
|
75
|
-
|
|
77
|
+
"#{100.0 * entry.compressedSize / entry.size}%"])
|
|
76
78
|
end
|
|
77
79
|
end
|
|
78
80
|
end
|
data/samples/qtzip.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$VERBOSE = true
|
|
4
5
|
|
|
@@ -6,14 +7,14 @@ $LOAD_PATH << '../lib'
|
|
|
6
7
|
|
|
7
8
|
require 'Qt'
|
|
8
9
|
system('rbuic -o zipdialogui.rb zipdialogui.ui')
|
|
9
|
-
require 'zipdialogui
|
|
10
|
+
require 'zipdialogui'
|
|
10
11
|
require 'zip'
|
|
11
12
|
|
|
12
13
|
a = Qt::Application.new(ARGV)
|
|
13
14
|
|
|
14
15
|
class ZipDialog < ZipDialogUI
|
|
15
16
|
def initialize
|
|
16
|
-
super
|
|
17
|
+
super
|
|
17
18
|
connect(child('add_button'), SIGNAL('clicked()'),
|
|
18
19
|
self, SLOT('add_files()'))
|
|
19
20
|
connect(child('extract_button'), SIGNAL('clicked()'),
|
|
@@ -65,14 +66,14 @@ class ZipDialog < ZipDialogUI
|
|
|
65
66
|
end
|
|
66
67
|
puts "selected_items.size = #{selected_items.size}"
|
|
67
68
|
puts "unselected_items.size = #{unselected_items.size}"
|
|
68
|
-
items =
|
|
69
|
+
items = selected_items.empty? ? unselected_items : selected_items
|
|
69
70
|
puts "items.size = #{items.size}"
|
|
70
71
|
|
|
71
72
|
d = Qt::FileDialog.get_existing_directory(nil, self)
|
|
72
|
-
if
|
|
73
|
-
puts 'No directory chosen'
|
|
74
|
-
else
|
|
73
|
+
if d
|
|
75
74
|
zipfile { |zf| items.each { |e| zf.extract(e, File.join(d, e)) } }
|
|
75
|
+
else
|
|
76
|
+
puts 'No directory chosen'
|
|
76
77
|
end
|
|
77
78
|
end
|
|
78
79
|
|
data/samples/write_simple.rb
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$LOAD_PATH << '../lib'
|
|
4
5
|
|
|
5
6
|
require 'zip'
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
Zip::OutputStream.open('simple.zip') do |zos|
|
|
8
9
|
zos.put_next_entry 'entry.txt'
|
|
9
10
|
zos.puts 'Hello world'
|
|
10
11
|
end
|