rubyzip 2.1.0 → 3.6.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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +538 -0
  3. data/LICENSE.md +24 -0
  4. data/README.md +235 -48
  5. data/Rakefile +17 -12
  6. data/lib/rubyzip.rb +3 -0
  7. data/lib/zip/central_directory.rb +196 -123
  8. data/lib/zip/compressor.rb +3 -1
  9. data/lib/zip/constants.rb +81 -21
  10. data/lib/zip/crypto/aes_encryption.rb +123 -0
  11. data/lib/zip/crypto/decrypted_io.rb +52 -0
  12. data/lib/zip/crypto/encryption.rb +4 -2
  13. data/lib/zip/crypto/null_encryption.rb +5 -13
  14. data/lib/zip/crypto/traditional_encryption.rb +22 -16
  15. data/lib/zip/decompressor.rb +21 -2
  16. data/lib/zip/deflater.rb +12 -8
  17. data/lib/zip/dirtyable.rb +32 -0
  18. data/lib/zip/dos_time.rb +79 -14
  19. data/lib/zip/entry.rb +430 -249
  20. data/lib/zip/entry_set.rb +13 -9
  21. data/lib/zip/errors.rb +152 -15
  22. data/lib/zip/extra_field/aes.rb +50 -0
  23. data/lib/zip/extra_field/generic.rb +17 -17
  24. data/lib/zip/extra_field/ntfs.rb +10 -4
  25. data/lib/zip/extra_field/old_unix.rb +8 -4
  26. data/lib/zip/extra_field/universal_time.rb +6 -1
  27. data/lib/zip/extra_field/unix.rb +9 -5
  28. data/lib/zip/extra_field/unknown.rb +35 -0
  29. data/lib/zip/extra_field/zip64.rb +23 -7
  30. data/lib/zip/extra_field.rb +31 -27
  31. data/lib/zip/file.rb +211 -241
  32. data/lib/zip/file_split.rb +91 -0
  33. data/lib/zip/filesystem/dir.rb +86 -0
  34. data/lib/zip/filesystem/directory_iterator.rb +48 -0
  35. data/lib/zip/filesystem/file.rb +263 -0
  36. data/lib/zip/filesystem/file_stat.rb +110 -0
  37. data/lib/zip/filesystem/zip_file_name_mapper.rb +81 -0
  38. data/lib/zip/filesystem.rb +32 -585
  39. data/lib/zip/inflater.rb +28 -37
  40. data/lib/zip/input_stream.rb +113 -54
  41. data/lib/zip/ioextras/abstract_input_stream.rb +154 -55
  42. data/lib/zip/ioextras/abstract_output_stream.rb +13 -3
  43. data/lib/zip/ioextras.rb +12 -9
  44. data/lib/zip/null_compressor.rb +3 -1
  45. data/lib/zip/null_decompressor.rb +7 -12
  46. data/lib/zip/null_input_stream.rb +3 -1
  47. data/lib/zip/output_stream.rb +76 -51
  48. data/lib/zip/pass_thru_compressor.rb +5 -3
  49. data/lib/zip/pass_thru_decompressor.rb +17 -23
  50. data/lib/zip/streamable_directory.rb +6 -4
  51. data/lib/zip/streamable_stream.rb +9 -5
  52. data/lib/zip/version.rb +4 -1
  53. data/lib/zip.rb +31 -5
  54. data/rubyzip.gemspec +39 -0
  55. data/samples/example.rb +9 -4
  56. data/samples/example_filesystem.rb +4 -3
  57. data/samples/example_recursive.rb +3 -1
  58. data/samples/gtk_ruby_zip.rb +23 -21
  59. data/samples/qtzip.rb +13 -12
  60. data/samples/write_simple.rb +3 -4
  61. data/samples/zipfind.rb +24 -22
  62. metadata +84 -28
  63. data/TODO +0 -15
  64. data/lib/zip/extra_field/zip64_placeholder.rb +0 -15
data/lib/zip/ioextras.rb CHANGED
@@ -1,31 +1,34 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Zip
2
- module IOExtras #:nodoc:
4
+ module IOExtras # :nodoc:
3
5
  CHUNK_SIZE = 131_072
4
6
 
5
- RANGE_ALL = 0..-1
6
-
7
7
  class << self
8
8
  def copy_stream(ostream, istream)
9
- ostream.write(istream.read(CHUNK_SIZE, '')) until istream.eof?
9
+ ostream.write(istream.read(CHUNK_SIZE, +'')) until istream.eof?
10
10
  end
11
11
 
12
12
  def copy_stream_n(ostream, istream, nbytes)
13
13
  toread = nbytes
14
14
  while toread > 0 && !istream.eof?
15
- tr = toread > CHUNK_SIZE ? CHUNK_SIZE : toread
16
- ostream.write(istream.read(tr, ''))
17
- toread -= tr
15
+ tr = [toread, CHUNK_SIZE].min
16
+ chunk = istream.read(tr, +'')
17
+ break if !chunk || chunk.empty?
18
+
19
+ ostream.write(chunk)
20
+ toread -= chunk.bytesize
18
21
  end
19
22
  end
20
23
  end
21
24
 
22
25
  # Implements kind_of? in order to pretend to be an IO object
23
- module FakeIO
26
+ module FakeIO # :nodoc:
24
27
  def kind_of?(object)
25
28
  object == IO || super
26
29
  end
27
30
  end
28
- end # IOExtras namespace module
31
+ end
29
32
  end
30
33
 
31
34
  require 'zip/ioextras/abstract_input_stream'
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Zip
2
- class NullCompressor < Compressor #:nodoc:all
4
+ class NullCompressor < Compressor # :nodoc:all
3
5
  include Singleton
4
6
 
5
7
  def <<(_data)
@@ -1,24 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Zip
2
- module NullDecompressor #:nodoc:all
4
+ module NullDecompressor # :nodoc:all
3
5
  module_function
4
6
 
5
- def sysread(_numberOfBytes = nil, _buf = nil)
6
- nil
7
- end
8
-
9
- def produce_input
7
+ def read(_length = nil, _outbuf = nil)
10
8
  nil
11
9
  end
12
10
 
13
- def input_finished?
14
- true
15
- end
16
-
17
- def eof
11
+ def eof?
18
12
  true
19
13
  end
20
14
 
21
- alias eof? eof
15
+ # Alias for compatibility. Remove for version 4.
16
+ alias eof eof?
22
17
  end
23
18
  end
24
19
 
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Zip
2
- module NullInputStream #:nodoc:all
4
+ module NullInputStream # :nodoc:all
3
5
  include ::Zip::NullDecompressor
4
6
  include ::Zip::IOExtras::AbstractInputStream
5
7
  end
@@ -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,48 +21,58 @@ 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
- attr_accessor :comment
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, stream = false, encrypter = nil)
32
+ def initialize(file_name, stream: false, encrypter: nil, suppress_extra_fields: false)
28
33
  super()
29
34
  @file_name = file_name
30
35
  @output_stream = if stream
31
- iostream = @file_name.dup
36
+ iostream = Zip::RUNNING_ON_WINDOWS ? @file_name : @file_name.dup
32
37
  iostream.reopen(@file_name)
33
38
  iostream.rewind
34
39
  iostream
35
40
  else
36
41
  ::File.new(@file_name, 'wb')
37
42
  end
38
- @entry_set = ::Zip::EntrySet.new
43
+ @cdir = ::Zip::CentralDirectory.new
39
44
  @compressor = ::Zip::NullCompressor.instance
40
45
  @encrypter = encrypter || ::Zip::NullEncrypter.new
46
+ @suppress_extra_fields = suppress_extra_fields
41
47
  @closed = false
42
48
  @current_entry = nil
43
- @comment = nil
44
49
  end
45
50
 
46
- # Same as #initialize but if a block is passed the opened
47
- # stream is passed to the block and closed when the block
48
- # returns.
49
51
  class << self
50
- def open(file_name, encrypter = nil)
51
- return new(file_name) unless block_given?
52
- zos = new(file_name, false, encrypter)
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)
56
+ unless block_given?
57
+ return new(
58
+ file_name,
59
+ encrypter: encrypter,
60
+ suppress_extra_fields: suppress_extra_fields
61
+ )
62
+ end
63
+
64
+ zos = new(file_name, stream: false, encrypter: encrypter,
65
+ suppress_extra_fields: suppress_extra_fields)
53
66
  yield zos
54
67
  ensure
55
68
  zos.close if zos
56
69
  end
57
70
 
58
71
  # Same as #open but writes to a filestream instead
59
- def write_buffer(io = ::StringIO.new(''), encrypter = nil)
60
- zos = new(io, true, encrypter)
72
+ def write_buffer(io = ::StringIO.new, encrypter: nil, suppress_extra_fields: false)
73
+ io.binmode if io.respond_to?(:binmode)
74
+ zos = new(io, stream: true, encrypter: encrypter,
75
+ suppress_extra_fields: suppress_extra_fields)
61
76
  yield zos
62
77
  zos.close_buffer
63
78
  end
@@ -66,9 +81,10 @@ module Zip
66
81
  # Closes the stream and writes the central directory to the zip file
67
82
  def close
68
83
  return if @closed
84
+
69
85
  finalize_current_entry
70
86
  update_local_headers
71
- write_central_directory
87
+ @cdir.write_to_stream(@output_stream, suppress_extra_fields: @suppress_extra_fields)
72
88
  @output_stream.close
73
89
  @closed = true
74
90
  end
@@ -76,37 +92,44 @@ module Zip
76
92
  # Closes the stream and writes the central directory to the zip file
77
93
  def close_buffer
78
94
  return @output_stream if @closed
95
+
79
96
  finalize_current_entry
80
97
  update_local_headers
81
- write_central_directory
98
+ @cdir.write_to_stream(@output_stream, suppress_extra_fields: @suppress_extra_fields)
82
99
  @closed = true
100
+ @output_stream.flush
83
101
  @output_stream
84
102
  end
85
103
 
86
104
  # Closes the current entry and opens a new for writing.
87
105
  # +entry+ can be a ZipEntry object or a string.
88
- def put_next_entry(entry_name, comment = nil, extra = nil, compression_method = Entry::DEFLATED, level = Zip.default_compression)
106
+ def put_next_entry(
107
+ entry_name, comment = '', extra = ExtraField.new,
108
+ compression_method = Entry::DEFLATED, level = Zip.default_compression
109
+ )
89
110
  raise Error, 'zip stream is closed' if @closed
90
- new_entry = if entry_name.kind_of?(Entry)
91
- entry_name
92
- else
93
- Entry.new(@file_name, entry_name.to_s)
94
- end
95
- new_entry.comment = comment unless comment.nil?
96
- unless extra.nil?
97
- new_entry.extra = extra.is_a?(ExtraField) ? extra : ExtraField.new(extra.to_s)
98
- end
99
- new_entry.compression_method = compression_method unless compression_method.nil?
100
- init_next_entry(new_entry, level)
111
+
112
+ new_entry =
113
+ if entry_name.kind_of?(Entry) || entry_name.kind_of?(StreamableStream)
114
+ entry_name
115
+ else
116
+ Entry.new(
117
+ @file_name, entry_name.to_s, comment: comment, extra: extra,
118
+ compression_method: compression_method, compression_level: level
119
+ )
120
+ end
121
+
122
+ init_next_entry(new_entry)
101
123
  @current_entry = new_entry
102
124
  end
103
125
 
104
- def copy_raw_entry(entry)
126
+ def copy_raw_entry(entry) # :nodoc:
105
127
  entry = entry.dup
106
128
  raise Error, 'zip stream is closed' if @closed
107
- raise Error, 'entry is not a ZipEntry' unless entry.is_a?(Entry)
129
+ raise Error, 'entry is not a ZipEntry' unless entry.kind_of?(Entry)
130
+
108
131
  finalize_current_entry
109
- @entry_set << entry
132
+ @cdir << entry
110
133
  src_pos = entry.local_header_offset
111
134
  entry.write_local_entry(@output_stream)
112
135
  @compressor = NullCompressor.instance
@@ -123,54 +146,56 @@ module Zip
123
146
 
124
147
  def finalize_current_entry
125
148
  return unless @current_entry
149
+
126
150
  finish
127
- @current_entry.compressed_size = @output_stream.tell - @current_entry.local_header_offset - @current_entry.calculate_local_header_size
151
+ @current_entry.compressed_size = @output_stream.tell -
152
+ @current_entry.local_header_offset -
153
+ @current_entry.calculate_local_header_size
128
154
  @current_entry.size = @compressor.size
129
155
  @current_entry.crc = @compressor.crc
130
- @output_stream << @encrypter.data_descriptor(@current_entry.crc, @current_entry.compressed_size, @current_entry.size)
156
+ @output_stream << @encrypter.data_descriptor(
157
+ @current_entry.crc,
158
+ @current_entry.compressed_size,
159
+ @current_entry.size
160
+ )
131
161
  @current_entry.gp_flags |= @encrypter.gp_flags
132
162
  @current_entry = nil
133
163
  @compressor = ::Zip::NullCompressor.instance
134
164
  end
135
165
 
136
- def init_next_entry(entry, level = Zip.default_compression)
166
+ def init_next_entry(entry)
137
167
  finalize_current_entry
138
- @entry_set << entry
139
- entry.write_local_entry(@output_stream)
168
+ @cdir << entry
169
+ entry.write_local_entry(@output_stream, suppress_extra_fields: @suppress_extra_fields)
140
170
  @encrypter.reset!
141
171
  @output_stream << @encrypter.header(entry.mtime)
142
- @compressor = get_compressor(entry, level)
172
+ @compressor = get_compressor(entry)
143
173
  end
144
174
 
145
- def get_compressor(entry, level)
175
+ def get_compressor(entry)
146
176
  case entry.compression_method
147
- when Entry::DEFLATED then
148
- ::Zip::Deflater.new(@output_stream, level, @encrypter)
149
- when Entry::STORED then
177
+ when Entry::DEFLATED
178
+ ::Zip::Deflater.new(@output_stream, entry.compression_level, @encrypter)
179
+ when Entry::STORED
150
180
  ::Zip::PassThruCompressor.new(@output_stream)
151
181
  else
152
- raise ::Zip::CompressionMethodError,
153
- "Invalid compression method: '#{entry.compression_method}'"
182
+ raise ::Zip::CompressionMethodError, entry.compression_method
154
183
  end
155
184
  end
156
185
 
157
186
  def update_local_headers
158
187
  pos = @output_stream.pos
159
- @entry_set.each do |entry|
188
+ @cdir.each do |entry|
160
189
  @output_stream.pos = entry.local_header_offset
161
- entry.write_local_entry(@output_stream, true)
190
+ entry.write_local_entry(@output_stream, suppress_extra_fields: @suppress_extra_fields,
191
+ rewrite: true)
162
192
  end
163
193
  @output_stream.pos = pos
164
194
  end
165
195
 
166
- def write_central_directory
167
- cdir = CentralDirectory.new(@entry_set, @comment)
168
- cdir.write_to_stream(@output_stream)
169
- end
170
-
171
196
  protected
172
197
 
173
- def finish
198
+ def finish # :nodoc:
174
199
  @compressor.finish
175
200
  end
176
201
 
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Zip
2
- class PassThruCompressor < Compressor #:nodoc:all
3
- def initialize(outputStream)
4
+ class PassThruCompressor < Compressor # :nodoc:all
5
+ def initialize(output_stream)
4
6
  super()
5
- @output_stream = outputStream
7
+ @output_stream = output_stream
6
8
  @crc = Zlib.crc32
7
9
  @size = 0
8
10
  end
@@ -1,38 +1,32 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Zip
2
- class PassThruDecompressor < Decompressor #:nodoc:all
3
- def initialize(input_stream, chars_to_read)
4
- super(input_stream)
5
- @chars_to_read = chars_to_read
4
+ class PassThruDecompressor < Decompressor # :nodoc:all
5
+ def initialize(*args)
6
+ super
6
7
  @read_so_far = 0
7
- @has_returned_empty_string = false
8
8
  end
9
9
 
10
- def sysread(number_of_bytes = nil, buf = '')
11
- if input_finished?
12
- has_returned_empty_string_val = @has_returned_empty_string
13
- @has_returned_empty_string = true
14
- return '' unless has_returned_empty_string_val
15
- return
16
- end
10
+ def read(maxlen = nil)
11
+ return (maxlen.nil? || maxlen.zero? ? '' : nil) if eof?
17
12
 
18
- if number_of_bytes.nil? || @read_so_far + number_of_bytes > @chars_to_read
19
- number_of_bytes = @chars_to_read - @read_so_far
13
+ if maxlen.nil? || (@read_so_far + maxlen) > decompressed_size
14
+ maxlen = decompressed_size - @read_so_far
20
15
  end
21
- @read_so_far += number_of_bytes
22
- @input_stream.read(number_of_bytes, buf)
23
- end
24
16
 
25
- def produce_input
26
- sysread(::Zip::Decompressor::CHUNK_SIZE)
17
+ @read_so_far += maxlen
18
+ input_stream.read(maxlen)
27
19
  end
28
20
 
29
- def input_finished?
30
- @read_so_far >= @chars_to_read
21
+ def eof?
22
+ @read_so_far >= decompressed_size
31
23
  end
32
24
 
33
- alias eof input_finished?
34
- alias eof? input_finished?
25
+ # Alias for compatibility. Remove for version 4.
26
+ alias eof eof?
35
27
  end
28
+
29
+ ::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_STORE, ::Zip::PassThruDecompressor)
36
30
  end
37
31
 
38
32
  # Copyright (C) 2002, 2003 Thomas Sondergaard
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Zip
2
- class StreamableDirectory < Entry
3
- def initialize(zipfile, entry, srcPath = nil, permissionInt = nil)
4
+ class StreamableDirectory < Entry # :nodoc:
5
+ def initialize(zipfile, entry, src_path = nil, permission = nil)
4
6
  super(zipfile, entry)
5
7
 
6
8
  @ftype = :directory
7
- entry.get_extra_attributes_from_path(srcPath) if srcPath
8
- @unix_perms = permissionInt if permissionInt
9
+ entry.get_extra_attributes_from_path(src_path) if src_path
10
+ @unix_perms = permission if permission
9
11
  end
10
12
  end
11
13
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Zip
2
- class StreamableStream < DelegateClass(Entry) # nodoc:all
4
+ class StreamableStream < DelegateClass(Entry) # :nodoc:all
3
5
  def initialize(entry)
4
- super(entry)
6
+ super
5
7
  @temp_file = Tempfile.new(::File.basename(name))
6
8
  @temp_file.binmode
7
9
  end
@@ -22,6 +24,7 @@ module Zip
22
24
  unless @temp_file.closed?
23
25
  raise StandardError, "cannot open entry for reading while its open for writing - #{name}"
24
26
  end
27
+
25
28
  @temp_file.open # reopens tempfile from top
26
29
  @temp_file.binmode
27
30
  if block_given?
@@ -35,12 +38,13 @@ module Zip
35
38
  end
36
39
  end
37
40
 
38
- def write_to_zip_output_stream(aZipOutputStream)
39
- aZipOutputStream.put_next_entry(self)
40
- get_input_stream { |is| ::Zip::IOExtras.copy_stream(aZipOutputStream, is) }
41
+ def write_to_zip_output_stream(output_stream)
42
+ output_stream.put_next_entry(self)
43
+ get_input_stream { |is| ::Zip::IOExtras.copy_stream(output_stream, is) }
41
44
  end
42
45
 
43
46
  def clean_up
47
+ super
44
48
  @temp_file.unlink
45
49
  end
46
50
  end
data/lib/zip/version.rb CHANGED
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Zip
2
- VERSION = '2.1.0'
4
+ # The version of the Rubyzip library.
5
+ VERSION = '3.6.0'
3
6
  end
data/lib/zip.rb CHANGED
@@ -1,9 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
1
4
  require 'delegate'
2
5
  require 'singleton'
3
6
  require 'tempfile'
4
7
  require 'fileutils'
5
8
  require 'stringio'
6
9
  require 'zlib'
10
+ require 'zip/version'
11
+ require 'zip/constants'
7
12
  require 'zip/dos_time'
8
13
  require 'zip/ioextras'
9
14
  require 'rbconfig'
@@ -21,18 +26,25 @@ require 'zip/null_compressor'
21
26
  require 'zip/null_input_stream'
22
27
  require 'zip/pass_thru_compressor'
23
28
  require 'zip/pass_thru_decompressor'
29
+ require 'zip/crypto/decrypted_io'
24
30
  require 'zip/crypto/encryption'
25
31
  require 'zip/crypto/null_encryption'
26
32
  require 'zip/crypto/traditional_encryption'
33
+ require 'zip/crypto/aes_encryption'
27
34
  require 'zip/inflater'
28
35
  require 'zip/deflater'
29
36
  require 'zip/streamable_stream'
30
37
  require 'zip/streamable_directory'
31
- require 'zip/constants'
32
38
  require 'zip/errors'
33
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.
34
45
  module Zip
35
46
  extend self
47
+
36
48
  attr_accessor :unicode_names,
37
49
  :on_exists_proc,
38
50
  :continue_on_exists_proc,
@@ -42,21 +54,35 @@ module Zip
42
54
  :warn_invalid_date,
43
55
  :case_insensitive_match,
44
56
  :force_entry_names_encoding,
45
- :validate_entry_sizes
57
+ :validate_entry_sizes,
58
+ :validate_declared_number_of_entries
59
+
60
+ DEFAULT_RESTORE_OPTIONS = {
61
+ restore_ownership: false,
62
+ restore_permissions: true,
63
+ restore_times: true
64
+ }.freeze # :nodoc:
65
+
66
+ # :nodoc:
67
+ # Remove this when JRuby#3962 is fixed.
68
+ ZLIB_FLUSHING_STRATEGY = defined?(JRUBY_VERSION) ? Zlib::SYNC_FLUSH : Zlib::NO_FLUSH
46
69
 
47
- def reset!
70
+ def reset! # :nodoc:
48
71
  @_ran_once = false
49
72
  @unicode_names = false
50
73
  @on_exists_proc = false
51
74
  @continue_on_exists_proc = false
52
75
  @sort_entries = false
53
- @default_compression = ::Zlib::DEFAULT_COMPRESSION
54
- @write_zip64_support = false
76
+ @default_compression = Zlib::DEFAULT_COMPRESSION
77
+ @write_zip64_support = true
55
78
  @warn_invalid_date = true
56
79
  @case_insensitive_match = false
80
+ @force_entry_names_encoding = nil
57
81
  @validate_entry_sizes = true
82
+ @validate_declared_number_of_entries = false # Set this to `true` in v4.0.0?
58
83
  end
59
84
 
85
+ # Set options for RubyZip in one block.
60
86
  def setup
61
87
  yield self unless @_ran_once
62
88
  @_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,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- $: << '../lib'
4
+ $LOAD_PATH << '../lib'
4
5
  system('zip example.zip example.rb gtk_ruby_zip.rb')
5
6
 
6
7
  require 'zip'
@@ -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}, compressed size = #{entry.compressed_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('large_zip_file.zip', 1_048_576, true, 'part_zip_file') do |part_count, part_index, chunk_bytes, segment_bytes|
74
- puts "#{part_index} of #{part_count} part splitting: #{(chunk_bytes.to_f / segment_bytes.to_f * 100).to_i}%"
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,14 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- $: << '../lib'
4
+ $LOAD_PATH << '../lib'
4
5
 
5
6
  require 'zip/filesystem'
6
7
 
7
8
  EXAMPLE_ZIP = 'filesystem.zip'
8
9
 
9
- File.delete(EXAMPLE_ZIP) if File.exist?(EXAMPLE_ZIP)
10
+ FileUtils.rm_f(EXAMPLE_ZIP)
10
11
 
11
- Zip::File.open(EXAMPLE_ZIP, Zip::File::CREATE) do |zf|
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, ::Zip::File::CREATE) do |zipfile|
26
+ ::Zip::File.open(@output_file, create: true) do |zipfile|
25
27
  write_entries entries, '', zipfile
26
28
  end
27
29
  end