Update minimum ruby version to 3.0.

All rubies before 3.0 are EOL and this is a major version bump, so it's
the right time to do this.
This commit is contained in:
Robert Haines 2024-03-01 22:14:48 +00:00
parent b1ee5cf272
commit 1c06454985
38 changed files with 114 additions and 121 deletions

View File

@ -12,7 +12,7 @@ jobs:
- name: Install and set up ruby - name: Install and set up ruby
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1
with: with:
ruby-version: '2.6' ruby-version: '3.0'
bundler-cache: true bundler-cache: true
- name: Rubocop - name: Rubocop

View File

@ -8,10 +8,10 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu] os: [ubuntu]
ruby: ['2.5', '2.6', '2.7', '3.0', '3.1', '3.2', '3.3', head, jruby, jruby-head, truffleruby, truffleruby-head] ruby: ['3.0', '3.1', '3.2', '3.3', head, jruby, jruby-head, truffleruby, truffleruby-head]
include: include:
- { os: macos , ruby: '2.5' } - { os: macos , ruby: '3.0' }
- { os: windows, ruby: '2.5' } - { os: windows, ruby: '3.0' }
# head builds # head builds
- { os: windows, ruby: ucrt } - { os: windows, ruby: ucrt }
- { os: windows, ruby: mswin } - { os: windows, ruby: mswin }

View File

@ -8,7 +8,7 @@ inherit_from: .rubocop_todo.yml
# we get errors if our ruby version doesn't match. # we get errors if our ruby version doesn't match.
AllCops: AllCops:
SuggestExtensions: false SuggestExtensions: false
TargetRubyVersion: 2.5 TargetRubyVersion: 3.0
NewCops: enable NewCops: enable
# Allow this in this file because adding the extra lines is pointless. # Allow this in this file because adding the extra lines is pointless.

View File

@ -6,6 +6,9 @@
# Note that changes in the inspected code, or installation of new # Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again. # versions of RuboCop, may require this file to be generated again.
Gemspec/DevelopmentDependencies:
Enabled: false
# Offense count: 7 # Offense count: 7
Lint/MissingSuper: Lint/MissingSuper:
Exclude: Exclude:

View File

@ -19,7 +19,7 @@ RDoc::Task.new do |rdoc|
rdoc.rdoc_files.include('README.md', 'lib/**/*.rb') rdoc.rdoc_files.include('README.md', 'lib/**/*.rb')
rdoc.options << '--markup=markdown' rdoc.options << '--markup=markdown'
rdoc.options << '--tab-width=2' rdoc.options << '--tab-width=2'
rdoc.options << "-t Rubyzip version #{::Zip::VERSION}" rdoc.options << "-t Rubyzip version #{Zip::VERSION}"
end end
RuboCop::RakeTask.new RuboCop::RakeTask.new

View File

@ -65,7 +65,7 @@ module Zip
@on_exists_proc = false @on_exists_proc = false
@continue_on_exists_proc = false @continue_on_exists_proc = false
@sort_entries = false @sort_entries = false
@default_compression = ::Zlib::DEFAULT_COMPRESSION @default_compression = Zlib::DEFAULT_COMPRESSION
@write_zip64_support = true @write_zip64_support = true
@warn_invalid_date = true @warn_invalid_date = true
@case_insensitive_match = false @case_insensitive_match = false

View File

@ -28,7 +28,7 @@ module Zip
mark_dirty :<<, :comment=, :delete mark_dirty :<<, :comment=, :delete
def initialize(entries = EntrySet.new, comment = '') #:nodoc: def initialize(entries = EntrySet.new, comment = '') # :nodoc:
super(dirty_on_create: false) super(dirty_on_create: false)
@entry_set = entries.kind_of?(EntrySet) ? entries : EntrySet.new(entries) @entry_set = entries.kind_of?(EntrySet) ? entries : EntrySet.new(entries)
@comment = comment @comment = comment
@ -39,7 +39,7 @@ module Zip
read_central_directory_entries(io) read_central_directory_entries(io)
end end
def write_to_stream(io) #:nodoc: def write_to_stream(io) # :nodoc:
cdir_offset = io.tell cdir_offset = io.tell
@entry_set.each { |entry| entry.write_c_dir_entry(io) } @entry_set.each { |entry| entry.write_c_dir_entry(io) }
eocd_offset = io.tell eocd_offset = io.tell
@ -61,7 +61,7 @@ module Zip
@size @size
end end
def ==(other) #:nodoc: def ==(other) # :nodoc:
return false unless other.kind_of?(CentralDirectory) return false unless other.kind_of?(CentralDirectory)
@entry_set.entries.sort == other.entries.sort && comment == other.comment @entry_set.entries.sort == other.entries.sort && comment == other.comment
@ -69,7 +69,7 @@ module Zip
private private
def write_e_o_c_d(io, offset, cdir_size) #:nodoc: def write_e_o_c_d(io, offset, cdir_size) # :nodoc:
tmp = [ tmp = [
END_OF_CD_SIG, END_OF_CD_SIG,
0, # @numberOfThisDisk 0, # @numberOfThisDisk
@ -84,7 +84,7 @@ module Zip
io << @comment io << @comment
end end
def write_64_e_o_c_d(io, offset, cdir_size) #:nodoc: def write_64_e_o_c_d(io, offset, cdir_size) # :nodoc:
tmp = [ tmp = [
ZIP64_END_OF_CD_SIG, ZIP64_END_OF_CD_SIG,
44, # size of zip64 end of central directory record (excludes signature and field itself) 44, # size of zip64 end of central directory record (excludes signature and field itself)
@ -110,7 +110,7 @@ module Zip
io << tmp.pack('VVQ<V') io << tmp.pack('VVQ<V')
end end
def unpack_64_e_o_c_d(buffer) #:nodoc: def unpack_64_e_o_c_d(buffer) # :nodoc:
_, # ZIP64_END_OF_CD_SIG. We know we have this at this point. _, # ZIP64_END_OF_CD_SIG. We know we have this at this point.
@size_of_zip64_e_o_c_d, @size_of_zip64_e_o_c_d,
@version_made_by, @version_made_by,
@ -134,14 +134,14 @@ module Zip
end end
end end
def unpack_64_eocd_locator(buffer) #:nodoc: def unpack_64_eocd_locator(buffer) # :nodoc:
_, # ZIP64_EOCD_LOCATOR_SIG. We know we have this at this point. _, # ZIP64_EOCD_LOCATOR_SIG. We know we have this at this point.
_, zip64_eocd_offset, = buffer.unpack('VVQ<V') _, zip64_eocd_offset, = buffer.unpack('VVQ<V')
zip64_eocd_offset zip64_eocd_offset
end end
def unpack_e_o_c_d(buffer) #:nodoc: def unpack_e_o_c_d(buffer) # :nodoc:
_, # END_OF_CD_SIG. We know we have this at this point. _, # END_OF_CD_SIG. We know we have this at this point.
num_disk, num_disk,
num_disk_cdir, num_disk_cdir,
@ -165,7 +165,7 @@ module Zip
end end
end end
def read_central_directory_entries(io) #:nodoc: def read_central_directory_entries(io) # :nodoc:
# `StringIO` doesn't raise `EINVAL` if you seek beyond the current end, # `StringIO` doesn't raise `EINVAL` if you seek beyond the current end,
# so we need to catch that *and* query `io#eof?` here. # so we need to catch that *and* query `io#eof?` here.
eof = false eof = false
@ -209,7 +209,7 @@ module Zip
io.read(e_len) io.read(e_len)
end end
def read_eocds(io) #:nodoc: def read_eocds(io) # :nodoc:
base_location, data = eocd_data(io) base_location, data = eocd_data(io)
eocd_location = data.rindex([END_OF_CD_SIG].pack('V')) eocd_location = data.rindex([END_OF_CD_SIG].pack('V'))

View File

@ -28,7 +28,7 @@ module Zip
def update_keys(num) def update_keys(num)
@key0 = ~Zlib.crc32(num, ~@key0) @key0 = ~Zlib.crc32(num, ~@key0)
@key1 = ((@key1 + (@key0 & 0xff)) * 134_775_813 + 1) & 0xffffffff @key1 = (((@key1 + (@key0 & 0xff)) * 134_775_813) + 1) & 0xffffffff
@key2 = ~Zlib.crc32((@key1 >> 24).chr, ~@key2) @key2 = ~Zlib.crc32((@key1 >> 24).chr, ~@key2)
end end

View File

@ -185,12 +185,12 @@ module Zip
# Dynamic checkers # Dynamic checkers
%w[directory file symlink].each do |k| %w[directory file symlink].each do |k|
define_method "#{k}?" do define_method :"#{k}?" do
file_type_is?(k.to_sym) file_type_is?(k.to_sym)
end end
end end
def name_is_directory? #:nodoc:all def name_is_directory? # :nodoc:all
@name.end_with?('/') @name.end_with?('/')
end end
@ -207,7 +207,7 @@ module Zip
::File.absolute_path(cleanpath.to_s, root).match?(/([A-Z]:)?#{naive}/i) ::File.absolute_path(cleanpath.to_s, root).match?(/([A-Z]:)?#{naive}/i)
end end
def local_entry_offset #:nodoc:all def local_entry_offset # :nodoc:all
local_header_offset + @local_header_size local_header_offset + @local_header_size
end end
@ -223,7 +223,7 @@ module Zip
@comment ? @comment.bytesize : 0 @comment ? @comment.bytesize : 0
end end
def calculate_local_header_size #:nodoc:all def calculate_local_header_size # :nodoc:all
LOCAL_ENTRY_STATIC_HEADER_LENGTH + name_size + extra_size LOCAL_ENTRY_STATIC_HEADER_LENGTH + name_size + extra_size
end end
@ -239,12 +239,12 @@ module Zip
"Local header size changed (#{@local_header_size} -> #{new_size})" "Local header size changed (#{@local_header_size} -> #{new_size})"
end end
def cdir_header_size #:nodoc:all def cdir_header_size # :nodoc:all
CDIR_ENTRY_STATIC_HEADER_LENGTH + name_size + CDIR_ENTRY_STATIC_HEADER_LENGTH + name_size +
(@extra ? @extra.c_dir_size : 0) + comment_size (@extra ? @extra.c_dir_size : 0) + comment_size
end end
def next_header_offset #:nodoc:all def next_header_offset # :nodoc:all
local_entry_offset + compressed_size local_entry_offset + compressed_size
end end
@ -266,7 +266,7 @@ module Zip
raise "unknown file type #{inspect}" unless directory? || file? || symlink? raise "unknown file type #{inspect}" unless directory? || file? || symlink?
__send__("create_#{ftype}", extract_path, &block) __send__(:"create_#{ftype}", extract_path, &block)
self self
end end
@ -275,7 +275,7 @@ module Zip
end end
class << self class << self
def read_c_dir_entry(io) #:nodoc:all def read_c_dir_entry(io) # :nodoc:all
path = if io.respond_to?(:path) path = if io.respond_to?(:path)
io.path io.path
else else
@ -314,7 +314,7 @@ module Zip
@extra_length = buf.unpack('VCCvvvvVVVvv') @extra_length = buf.unpack('VCCvvvvVVVvv')
end end
def read_local_entry(io) #:nodoc:all def read_local_entry(io) # :nodoc:all
@dirty = false # No changes at this point. @dirty = false # No changes at this point.
@local_header_offset = io.tell @local_header_offset = io.tell
@ -371,7 +371,7 @@ module Zip
@extra ? @extra.local_size : 0].pack('VvvvvvVVVvv') @extra ? @extra.local_size : 0].pack('VvvvvvVVVvv')
end end
def write_local_entry(io, rewrite: false) #:nodoc:all def write_local_entry(io, rewrite: false) # :nodoc:all
prep_local_zip64_extra prep_local_zip64_extra
verify_local_header_size! if rewrite verify_local_header_size! if rewrite
@local_header_offset = io.tell @local_header_offset = io.tell
@ -463,7 +463,7 @@ module Zip
end end
end end
def read_c_dir_entry(io) #:nodoc:all def read_c_dir_entry(io) # :nodoc:all
@dirty = false # No changes at this point. @dirty = false # No changes at this point.
static_sized_fields_buf = io.read(::Zip::CDIR_ENTRY_STATIC_HEADER_LENGTH) static_sized_fields_buf = io.read(::Zip::CDIR_ENTRY_STATIC_HEADER_LENGTH)
check_c_dir_entry_static_header_length(static_sized_fields_buf) check_c_dir_entry_static_header_length(static_sized_fields_buf)
@ -556,7 +556,7 @@ module Zip
].pack('VCCvvvvvVVVvvvvvVV') ].pack('VCCvvvvvVVVvvvvvVV')
end end
def write_c_dir_entry(io) #:nodoc:all def write_c_dir_entry(io) # :nodoc:all
prep_cdir_zip64_extra prep_cdir_zip64_extra
case @fstype case @fstype
@ -574,7 +574,7 @@ module Zip
end end
unless ft.nil? unless ft.nil?
@external_file_attributes = (ft << 12 | (@unix_perms & 0o7777)) << 16 @external_file_attributes = ((ft << 12) | (@unix_perms & 0o7777)) << 16
end end
end end
@ -639,7 +639,7 @@ module Zip
if name_is_directory? if name_is_directory?
raise ArgumentError, raise ArgumentError,
"entry name '#{newEntry}' indicates directory entry, but " \ "entry name '#{newEntry}' indicates directory entry, but " \
"'#{src_path}' is not a directory" "'#{src_path}' is not a directory"
end end
:file :file
when 'directory' when 'directory'
@ -649,7 +649,7 @@ module Zip
if name_is_directory? if name_is_directory?
raise ArgumentError, raise ArgumentError,
"entry name '#{newEntry}' indicates directory entry, but " \ "entry name '#{newEntry}' indicates directory entry, but " \
"'#{src_path}' is not a directory" "'#{src_path}' is not a directory"
end end
:symlink :symlink
else else
@ -661,7 +661,7 @@ module Zip
get_extra_attributes_from_path(@filepath) get_extra_attributes_from_path(@filepath)
end end
def write_to_zip_output_stream(zip_output_stream) #:nodoc:all def write_to_zip_output_stream(zip_output_stream) # :nodoc:all
if ftype == :directory if ftype == :directory
zip_output_stream.put_next_entry(self) zip_output_stream.put_next_entry(self)
elsif @filepath elsif @filepath
@ -749,7 +749,7 @@ module Zip
# apply missing data from the zip64 extra information field, if present # apply missing data from the zip64 extra information field, if present
# (required when file sizes exceed 2**32, but can be used for all files) # (required when file sizes exceed 2**32, but can be used for all files)
def parse_zip64_extra(for_local_header) #:nodoc:all def parse_zip64_extra(for_local_header) # :nodoc:all
return unless zip64? return unless zip64?
if for_local_header if for_local_header

View File

@ -61,12 +61,12 @@ module Zip
end end
def glob(pattern, flags = ::File::FNM_PATHNAME | ::File::FNM_DOTMATCH | ::File::FNM_EXTGLOB) def glob(pattern, flags = ::File::FNM_PATHNAME | ::File::FNM_DOTMATCH | ::File::FNM_EXTGLOB)
entries.map do |entry| entries.filter_map do |entry|
next nil unless ::File.fnmatch(pattern, entry.name.chomp('/'), flags) next nil unless ::File.fnmatch(pattern, entry.name.chomp('/'), flags)
yield(entry) if block_given? yield(entry) if block_given?
entry entry
end.compact end
end end
protected protected

View File

@ -43,7 +43,7 @@ module Zip
def message def message
"Cannot create file or directory '#{@destination}'. " \ "Cannot create file or directory '#{@destination}'. " \
'A file already exists with that name.' 'A file already exists with that name.'
end end
end end
@ -111,8 +111,8 @@ module Zip
def message def message
"The local header of this entry ('#{@entry.name}') does not contain " \ "The local header of this entry ('#{@entry.name}') does not contain " \
'the correct metadata for `Zip::InputStream` to be able to ' \ 'the correct metadata for `Zip::InputStream` to be able to ' \
'uncompress it. Please use `Zip::File` instead of `Zip::InputStream`.' 'uncompress it. Please use `Zip::File` instead of `Zip::InputStream`.'
end end
end end
end end

View File

@ -21,8 +21,8 @@ module Zip
def extra_field_type_unknown(binstr, len, index, local) def extra_field_type_unknown(binstr, len, index, local)
self['Unknown'] ||= Unknown.new self['Unknown'] ||= Unknown.new
if !len || len + 4 > binstr[index..-1].bytesize if !len || len + 4 > binstr[index..].bytesize
self['Unknown'].merge(binstr[index..-1], local: local) self['Unknown'].merge(binstr[index..], local: local)
return return
end end

View File

@ -21,17 +21,17 @@ module Zip
return false return false
end end
[binstr[2, 2].unpack1('v'), binstr[4..-1]] [binstr[2, 2].unpack1('v'), binstr[4..]]
end end
def to_local_bin def to_local_bin
s = pack_for_local s = pack_for_local
self.class.const_get(:HEADER_ID) + [s.bytesize].pack('v') << s (self.class.const_get(:HEADER_ID) + [s.bytesize].pack('v')) << s
end end
def to_c_dir_bin def to_c_dir_bin
s = pack_for_c_dir s = pack_for_c_dir
self.class.const_get(:HEADER_ID) + [s.bytesize].pack('v') << s (self.class.const_get(:HEADER_ID) + [s.bytesize].pack('v')) << s
end end
end end
end end

View File

@ -25,7 +25,7 @@ module Zip
size, content = initial_parse(binstr) size, content = initial_parse(binstr)
(size && content) || return (size && content) || return
content = content[4..-1] content = content[4..]
tags = parse_tags(content) tags = parse_tags(content)
tag1 = tags[1] tag1 = tags[1]
@ -86,7 +86,7 @@ module Zip
end end
def from_ntfs_time(ntfs_time) def from_ntfs_time(ntfs_time)
::Zip::DOSTime.at(ntfs_time / WINDOWS_TICK - SEC_TO_UNIX_EPOCH) ::Zip::DOSTime.at((ntfs_time / WINDOWS_TICK) - SEC_TO_UNIX_EPOCH)
end end
def to_ntfs_time(time) def to_ntfs_time(time)

View File

@ -356,7 +356,7 @@ module Zip
# This zip is probably a non-empty StringIO. # This zip is probably a non-empty StringIO.
@create = false @create = false
@cdir.read_from_stream(path_or_io) @cdir.read_from_stream(path_or_io)
elsif !@create && ::File.zero?(@name) elsif !@create && ::File.empty?(@name)
# A file exists, but it is empty, and we've said we're # A file exists, but it is empty, and we've said we're
# NOT creating a new zip. # NOT creating a new zip.
raise Error, "File #{@name} has zero size. Did you mean to pass the create flag?" raise Error, "File #{@name} has zero size. Did you mean to pass the create flag?"

View File

@ -7,13 +7,7 @@ module Zip
DATA_BUFFER_SIZE = 8192 DATA_BUFFER_SIZE = 8192
def get_segment_size_for_split(segment_size) def get_segment_size_for_split(segment_size)
if MIN_SEGMENT_SIZE > segment_size segment_size.clamp(MIN_SEGMENT_SIZE, MAX_SEGMENT_SIZE)
MIN_SEGMENT_SIZE
elsif MAX_SEGMENT_SIZE < segment_size
MAX_SEGMENT_SIZE
else
segment_size
end
end end
def get_partial_zip_file_name(zip_file_name, partial_zip_file_name) def get_partial_zip_file_name(zip_file_name, partial_zip_file_name)

View File

@ -45,8 +45,8 @@ module Zip
entries entries
end end
def glob(*args, &block) def glob(...)
@mapped_zip.glob(*args, &block) @mapped_zip.glob(...)
end end
def foreach(directory_name) def foreach(directory_name)

View File

@ -74,7 +74,7 @@ module Zip
private private
def expand_to_entry(path) def expand_to_entry(path)
expand_path(path)[1..-1] expand_path(path)[1..]
end end
end end
end end

View File

@ -144,8 +144,7 @@ module Zip
'A password is required to decode this zip file' 'A password is required to decode this zip file'
end end
if @current_entry.incomplete? && @current_entry.compressed_size == 0 \ if @current_entry.incomplete? && @current_entry.compressed_size == 0 && !@complete_entry
&& !@complete_entry
raise StreamingError, @current_entry raise StreamingError, @current_entry
end end
@ -166,8 +165,8 @@ module Zip
return ::Zip::NullDecompressor if @current_entry.nil? return ::Zip::NullDecompressor if @current_entry.nil?
decompressed_size = decompressed_size =
if @current_entry.incomplete? && @current_entry.crc == 0 \ if @current_entry.incomplete? && @current_entry.crc == 0 &&
&& @current_entry.size == 0 && @complete_entry @current_entry.size == 0 && @complete_entry
@complete_entry.size @complete_entry.size
else else
@current_entry.size @current_entry.size

View File

@ -12,7 +12,7 @@ module Zip
def copy_stream_n(ostream, istream, nbytes) def copy_stream_n(ostream, istream, nbytes)
toread = nbytes toread = nbytes
while toread > 0 && !istream.eof? while toread > 0 && !istream.eof?
tr = toread > CHUNK_SIZE ? CHUNK_SIZE : toread tr = [toread, CHUNK_SIZE].min
ostream.write(istream.read(tr, +'')) ostream.write(istream.read(tr, +''))
toread -= tr toread -= tr
end end

View File

@ -76,13 +76,13 @@ module Zip
a_sep_string = "#{$INPUT_RECORD_SEPARATOR}#{$INPUT_RECORD_SEPARATOR}" if a_sep_string.empty? a_sep_string = "#{$INPUT_RECORD_SEPARATOR}#{$INPUT_RECORD_SEPARATOR}" if a_sep_string.empty?
buffer_index = 0 buffer_index = 0
over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes) over_limit = number_of_bytes && @output_buffer.bytesize >= number_of_bytes
while (match_index = @output_buffer.index(a_sep_string, buffer_index)).nil? && !over_limit while (match_index = @output_buffer.index(a_sep_string, buffer_index)).nil? && !over_limit
buffer_index = [buffer_index, @output_buffer.bytesize - a_sep_string.bytesize].max buffer_index = [buffer_index, @output_buffer.bytesize - a_sep_string.bytesize].max
return @output_buffer.empty? ? nil : flush if input_finished? return @output_buffer.empty? ? nil : flush if input_finished?
@output_buffer << produce_input @output_buffer << produce_input
over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes) over_limit = number_of_bytes && @output_buffer.bytesize >= number_of_bytes
end end
sep_index = [ sep_index = [
match_index + a_sep_string.bytesize, match_index + a_sep_string.bytesize,

View File

@ -139,8 +139,8 @@ module Zip
return unless @current_entry return unless @current_entry
finish finish
@current_entry.compressed_size = @output_stream.tell - \ @current_entry.compressed_size = @output_stream.tell -
@current_entry.local_header_offset - \ @current_entry.local_header_offset -
@current_entry.calculate_local_header_size @current_entry.calculate_local_header_size
@current_entry.size = @compressor.size @current_entry.size = @compressor.size
@current_entry.crc = @compressor.crc @current_entry.crc = @compressor.crc

View File

@ -4,7 +4,7 @@ require_relative 'lib/zip/version'
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = 'rubyzip' s.name = 'rubyzip'
s.version = ::Zip::VERSION s.version = Zip::VERSION
s.authors = ['Robert Haines', 'John Lees-Miller', 'Alexander Simonov'] s.authors = ['Robert Haines', 'John Lees-Miller', 'Alexander Simonov']
s.email = [ s.email = [
'hainesr@gmail.com', 'jdleesmiller@gmail.com', 'alex@simonov.me' 'hainesr@gmail.com', 'jdleesmiller@gmail.com', 'alex@simonov.me'
@ -18,21 +18,22 @@ Gem::Specification.new do |s|
s.license = 'BSD-2-Clause' s.license = 'BSD-2-Clause'
s.metadata = { s.metadata = {
'bug_tracker_uri' => 'https://github.com/rubyzip/rubyzip/issues', 'bug_tracker_uri' => 'https://github.com/rubyzip/rubyzip/issues',
'changelog_uri' => "https://github.com/rubyzip/rubyzip/blob/v#{s.version}/Changelog.md", 'changelog_uri' => "https://github.com/rubyzip/rubyzip/blob/v#{s.version}/Changelog.md",
'documentation_uri' => "https://www.rubydoc.info/gems/rubyzip/#{s.version}", 'documentation_uri' => "https://www.rubydoc.info/gems/rubyzip/#{s.version}",
'source_code_uri' => "https://github.com/rubyzip/rubyzip/tree/v#{s.version}", 'source_code_uri' => "https://github.com/rubyzip/rubyzip/tree/v#{s.version}",
'wiki_uri' => 'https://github.com/rubyzip/rubyzip/wiki' 'wiki_uri' => 'https://github.com/rubyzip/rubyzip/wiki',
'rubygems_mfa_required' => 'true'
} }
s.required_ruby_version = '>= 2.5' s.required_ruby_version = '>= 3.0'
s.add_development_dependency 'minitest', '~> 5.4' s.add_development_dependency 'minitest', '~> 5.22.0'
s.add_development_dependency 'rake', '~> 12.3.3' s.add_development_dependency 'rake', '~> 13.1.0'
s.add_development_dependency 'rdoc', '~> 6.4.0' s.add_development_dependency 'rdoc', '~> 6.6.2'
s.add_development_dependency 'rubocop', '~> 1.12.0' s.add_development_dependency 'rubocop', '~> 1.61.0'
s.add_development_dependency 'rubocop-performance', '~> 1.10.0' s.add_development_dependency 'rubocop-performance', '~> 1.20.0'
s.add_development_dependency 'rubocop-rake', '~> 0.5.0' s.add_development_dependency 'rubocop-rake', '~> 0.6.0'
s.add_development_dependency 'simplecov', '~> 0.18.0' s.add_development_dependency 'simplecov', '~> 0.22.0'
s.add_development_dependency 'simplecov-lcov', '~> 0.8' s.add_development_dependency 'simplecov-lcov', '~> 0.8'
end end

View File

@ -7,7 +7,7 @@ require 'zip/filesystem'
EXAMPLE_ZIP = 'filesystem.zip' EXAMPLE_ZIP = 'filesystem.zip'
File.delete(EXAMPLE_ZIP) if File.exist?(EXAMPLE_ZIP) FileUtils.rm_f(EXAMPLE_ZIP)
Zip::File.open(EXAMPLE_ZIP, create: true) do |zf| Zip::File.open(EXAMPLE_ZIP, create: true) do |zf|
zf.file.open('file1.txt', 'w') { |os| os.write 'first file1.txt' } zf.file.open('file1.txt', 'w') { |os| os.write 'first file1.txt' }

View File

@ -5,7 +5,7 @@ $LOAD_PATH << '../lib'
require 'zip' require 'zip'
::Zip::OutputStream.open('simple.zip') do |zos| Zip::OutputStream.open('simple.zip') do |zos|
zos.put_next_entry 'entry.txt' zos.put_next_entry 'entry.txt'
zos.puts 'Hello world' zos.puts 'Hello world'
end end

View File

@ -18,7 +18,7 @@ class ZipCaseSensitivityTest < MiniTest::Test
def test_add_case_sensitive def test_add_case_sensitive
::Zip.case_insensitive_match = false ::Zip.case_insensitive_match = false
SRC_FILES.each { |fn, _en| assert(::File.exist?(fn)) } SRC_FILES.each { |(fn, _en)| assert(::File.exist?(fn)) }
zf = ::Zip::File.new(EMPTY_FILENAME, create: true) zf = ::Zip::File.new(EMPTY_FILENAME, create: true)
SRC_FILES.each { |fn, en| zf.add(en, fn) } SRC_FILES.each { |fn, en| zf.add(en, fn) }
@ -37,7 +37,7 @@ class ZipCaseSensitivityTest < MiniTest::Test
def test_add_case_insensitive def test_add_case_insensitive
::Zip.case_insensitive_match = true ::Zip.case_insensitive_match = true
SRC_FILES.each { |fn, _en| assert(::File.exist?(fn)) } SRC_FILES.each { |(fn, _en)| assert(::File.exist?(fn)) }
zf = ::Zip::File.new(EMPTY_FILENAME, create: true) zf = ::Zip::File.new(EMPTY_FILENAME, create: true)
error = assert_raises Zip::EntryExistsError do error = assert_raises Zip::EntryExistsError do
@ -50,7 +50,7 @@ class ZipCaseSensitivityTest < MiniTest::Test
def test_add_case_sensitive_read_case_insensitive def test_add_case_sensitive_read_case_insensitive
::Zip.case_insensitive_match = false ::Zip.case_insensitive_match = false
SRC_FILES.each { |fn, _en| assert(::File.exist?(fn)) } SRC_FILES.each { |(fn, _en)| assert(::File.exist?(fn)) }
zf = ::Zip::File.new(EMPTY_FILENAME, create: true) zf = ::Zip::File.new(EMPTY_FILENAME, create: true)
SRC_FILES.each { |fn, en| zf.add(en, fn) } SRC_FILES.each { |fn, en| zf.add(en, fn) }

View File

@ -49,7 +49,7 @@ class DeflaterTest < MiniTest::Test
private private
def load_file(filename) def load_file(filename)
File.open(filename, 'rb', &:read) File.binread(filename)
end end
def deflate(data, filename) def deflate(data, filename)

View File

@ -16,7 +16,7 @@ class EncryptionTest < MiniTest::Test
end end
def test_encrypt def test_encrypt
content = File.open(INPUT_FILE1, 'r').read content = File.read(INPUT_FILE1)
test_filename = 'top_secret_file.txt' test_filename = 'top_secret_file.txt'
password = 'swordfish' password = 'swordfish'
@ -58,11 +58,11 @@ class EncryptionTest < MiniTest::Test
entry = zis.get_next_entry entry = zis.get_next_entry
assert_equal 'file1.txt', entry.name assert_equal 'file1.txt', entry.name
assert_equal 1_327, entry.size assert_equal 1_327, entry.size
assert_equal ::File.open(INPUT_FILE1, 'r').read, zis.read assert_equal ::File.read(INPUT_FILE1), zis.read
entry = zis.get_next_entry entry = zis.get_next_entry
assert_equal 'file2.txt', entry.name assert_equal 'file2.txt', entry.name
assert_equal 41_234, entry.size assert_equal 41_234, entry.size
assert_equal ::File.open(INPUT_FILE2, 'r').read, zis.read assert_equal ::File.read(INPUT_FILE2), zis.read
end end
end end
end end

View File

@ -22,7 +22,7 @@ class ZipFileExtractDirectoryTest < MiniTest::Test
super super
Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
File.delete(TEST_OUT_NAME) if File.exist? TEST_OUT_NAME FileUtils.rm_f(TEST_OUT_NAME)
end end
def test_extract_directory def test_extract_directory

View File

@ -38,7 +38,7 @@ class ZipFileExtractTest < MiniTest::Test
def test_extract_exists def test_extract_exists
text = 'written text' text = 'written text'
::File.open(EXTRACTED_FILENAME, 'w') { |f| f.write(text) } ::File.write(EXTRACTED_FILENAME, text)
assert_raises(::Zip::DestinationExistsError) do assert_raises(::Zip::DestinationExistsError) do
::Zip::File.open(TEST_ZIP.zip_name) do |zf| ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
@ -53,7 +53,7 @@ class ZipFileExtractTest < MiniTest::Test
def test_extract_exists_overwrite def test_extract_exists_overwrite
text = 'written text' text = 'written text'
::File.open(EXTRACTED_FILENAME, 'w') { |f| f.write(text) } ::File.write(EXTRACTED_FILENAME, text)
called_correctly = false called_correctly = false
::Zip::File.open(TEST_ZIP.zip_name) do |zf| ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
@ -123,9 +123,7 @@ class ZipFileExtractTest < MiniTest::Test
assert data.include?(true_size_bytes) assert data.include?(true_size_bytes)
data.gsub! true_size_bytes, fake_size_bytes data.gsub! true_size_bytes, fake_size_bytes
File.open(fake_zip, 'wb') do |file| File.binwrite(fake_zip, data)
file.write data
end
Dir.chdir tmp do Dir.chdir tmp do
::Zip::File.open(fake_zip) do |zf| ::Zip::File.open(fake_zip) do |zf|
@ -187,9 +185,7 @@ class ZipFileExtractTest < MiniTest::Test
assert data.include?(true_size_bytes) assert data.include?(true_size_bytes)
data.gsub! true_size_bytes, fake_size_bytes data.gsub! true_size_bytes, fake_size_bytes
File.open(fake_zip, 'wb') do |file| File.binwrite(fake_zip, data)
file.write data
end
Dir.chdir tmp do Dir.chdir tmp do
::Zip::File.open(fake_zip) do |zf| ::Zip::File.open(fake_zip) do |zf|

View File

@ -15,10 +15,10 @@ class ZipFileSplitTest < MiniTest::Test
def teardown def teardown
File.delete(TEST_ZIP.zip_name) File.delete(TEST_ZIP.zip_name)
File.delete(UNSPLITTED_FILENAME) if File.exist?(UNSPLITTED_FILENAME) FileUtils.rm_f(UNSPLITTED_FILENAME)
Dir["#{TEST_ZIP.zip_name}.*"].each do |zip_file_name| Dir["#{TEST_ZIP.zip_name}.*"].each do |zip_file_name|
File.delete(zip_file_name) if File.exist?(zip_file_name) FileUtils.rm_f(zip_file_name)
end end
end end
@ -33,7 +33,7 @@ class ZipFileSplitTest < MiniTest::Test
return if result.nil? return if result.nil?
Dir["#{TEST_ZIP.zip_name}.*"].sort.each_with_index do |zip_file_name, index| Dir["#{TEST_ZIP.zip_name}.*"].each_with_index do |zip_file_name, index|
File.open(zip_file_name, 'rb') do |zip_file| File.open(zip_file_name, 'rb') do |zip_file|
zip_file.read([::Zip::SPLIT_FILE_SIGNATURE].pack('V').size) if index.zero? zip_file.read([::Zip::SPLIT_FILE_SIGNATURE].pack('V').size) if index.zero?
File.open(UNSPLITTED_FILENAME, 'ab') do |file| File.open(UNSPLITTED_FILENAME, 'ab') do |file|

View File

@ -22,7 +22,7 @@ class ZipFileTest < MiniTest::Test
zf.comment = comment zf.comment = comment
end end
::File.open(EMPTY_FILENAME, 'wb') { |file| file.write buffer.string } ::File.binwrite(EMPTY_FILENAME, buffer.string)
zf_read = ::Zip::File.new(EMPTY_FILENAME) zf_read = ::Zip::File.new(EMPTY_FILENAME)
assert_equal(comment, zf_read.comment) assert_equal(comment, zf_read.comment)
@ -105,7 +105,7 @@ class ZipFileTest < MiniTest::Test
assert_equal(entry.time, custom_entry_args[:time]) assert_equal(entry.time, custom_entry_args[:time])
zf.get_output_stream('entry.bin') do |os| zf.get_output_stream('entry.bin') do |os|
os.write(::File.open('test/data/generated/5entry.zip', 'rb').read) os.write(::File.binread('test/data/generated/5entry.zip'))
end end
end end
@ -113,7 +113,7 @@ class ZipFileTest < MiniTest::Test
assert_equal(count + 3, zf.size) assert_equal(count + 3, zf.size)
assert_equal('Putting stuff in new_entry.txt', zf.read('new_entry.txt')) assert_equal('Putting stuff in new_entry.txt', zf.read('new_entry.txt'))
assert_equal('Putting stuff in data/generated/empty.txt', zf.read('test/data/generated/empty.txt')) assert_equal('Putting stuff in data/generated/empty.txt', zf.read('test/data/generated/empty.txt'))
assert_equal(File.open('test/data/generated/5entry.zip', 'rb').read, zf.read('entry.bin')) assert_equal(File.binread('test/data/generated/5entry.zip'), zf.read('entry.bin'))
end end
end end
@ -693,7 +693,7 @@ class ZipFileTest < MiniTest::Test
old_name = zf.entries.first old_name = zf.entries.first
zf.rename(old_name, new_name) zf.rename(old_name, new_name)
buffer = zf.write_buffer(::StringIO.new) buffer = zf.write_buffer(::StringIO.new)
File.open(TEST_ZIP.zip_name, 'wb') { |f| f.write buffer.string } File.binwrite(TEST_ZIP.zip_name, buffer.string)
zf_read = ::Zip::File.new(TEST_ZIP.zip_name) zf_read = ::Zip::File.new(TEST_ZIP.zip_name)
refute_nil(zf_read.entries.detect { |e| e.name == new_name }) refute_nil(zf_read.entries.detect { |e| e.name == new_name })
assert_nil(zf_read.entries.detect { |e| e.name == old_name }) assert_nil(zf_read.entries.detect { |e| e.name == old_name })

View File

@ -406,7 +406,7 @@ class FileNonmutatingTest < MiniTest::Test
zf.file.foreach('test/data/file1.txt') do |l| zf.file.foreach('test/data/file1.txt') do |l|
# Ruby replaces \n with \r\n automatically on windows # Ruby replaces \n with \r\n automatically on windows
newline = Zip::RUNNING_ON_WINDOWS ? l.gsub(/\r\n/, "\n") : l newline = Zip::RUNNING_ON_WINDOWS ? l.gsub("\r\n", "\n") : l
assert_equal(ref[index], newline) assert_equal(ref[index], newline)
index = index.next index = index.next
end end
@ -420,7 +420,7 @@ class FileNonmutatingTest < MiniTest::Test
zf.file.foreach('test/data/file1.txt', ' ') do |l| zf.file.foreach('test/data/file1.txt', ' ') do |l|
# Ruby replaces \n with \r\n automatically on windows # Ruby replaces \n with \r\n automatically on windows
newline = Zip::RUNNING_ON_WINDOWS ? l.gsub(/\r\n/, "\n") : l newline = Zip::RUNNING_ON_WINDOWS ? l.gsub("\r\n", "\n") : l
assert_equal(ref[index], newline) assert_equal(ref[index], newline)
index = index.next index = index.next
end end
@ -486,7 +486,7 @@ class FileNonmutatingTest < MiniTest::Test
zip_file = zf.file.readlines('test/data/file1.txt') zip_file = zf.file.readlines('test/data/file1.txt')
# Ruby replaces \n with \r\n automatically on windows # Ruby replaces \n with \r\n automatically on windows
zip_file.each { |l| l.gsub!(/\r\n/, "\n") } if Zip::RUNNING_ON_WINDOWS zip_file.each { |l| l.gsub!("\r\n", "\n") } if Zip::RUNNING_ON_WINDOWS
assert_equal(orig_file, zip_file) assert_equal(orig_file, zip_file)
end end
@ -498,7 +498,7 @@ class FileNonmutatingTest < MiniTest::Test
# Ruby replaces \n with \r\n automatically on windows # Ruby replaces \n with \r\n automatically on windows
zip_file = if Zip::RUNNING_ON_WINDOWS zip_file = if Zip::RUNNING_ON_WINDOWS
zf.file.read('test/data/file1.txt').gsub(/\r\n/, "\n") zf.file.read('test/data/file1.txt').gsub("\r\n", "\n")
else else
zf.file.read('test/data/file1.txt') zf.file.read('test/data/file1.txt')
end end

View File

@ -20,7 +20,7 @@ class TestFiles
class << self class << self
def create_test_files def create_test_files
Dir.mkdir 'test/data/generated' unless Dir.exist?('test/data/generated') FileUtils.mkdir_p 'test/data/generated'
ASCII_TEST_FILES.each_with_index do |filename, index| ASCII_TEST_FILES.each_with_index do |filename, index|
create_random_ascii(filename, 1E4 * (index + 1)) create_random_ascii(filename, 1E4 * (index + 1))

View File

@ -29,7 +29,7 @@ class ZipOutputStreamTest < MiniTest::Test
zos.comment = TEST_ZIP.comment zos.comment = TEST_ZIP.comment
write_test_zip(zos) write_test_zip(zos)
end end
File.open(TEST_ZIP.zip_name, 'wb') { |f| f.write buffer.string } File.binwrite(TEST_ZIP.zip_name, buffer.string)
assert_test_zip_contents(TEST_ZIP) assert_test_zip_contents(TEST_ZIP)
end end
@ -50,7 +50,7 @@ class ZipOutputStreamTest < MiniTest::Test
end end
tmp_file.rewind tmp_file.rewind
File.open(TEST_ZIP.zip_name, 'wb') { |f| f.write(tmp_file.read) } File.binwrite(TEST_ZIP.zip_name, tmp_file.read)
tmp_file.unlink tmp_file.unlink
assert_test_zip_contents(TEST_ZIP) assert_test_zip_contents(TEST_ZIP)
@ -75,7 +75,7 @@ class ZipOutputStreamTest < MiniTest::Test
zos.comment = TEST_ZIP.comment zos.comment = TEST_ZIP.comment
write_test_zip(zos) write_test_zip(zos)
end end
File.open(TEST_ZIP.zip_name, 'wb') { |f| f.write buffer.string } File.binwrite(TEST_ZIP.zip_name, buffer.string)
assert_test_zip_contents(TEST_ZIP) assert_test_zip_contents(TEST_ZIP)
end end

View File

@ -12,7 +12,7 @@ class ZipSettingsTest < MiniTest::Test
super super
Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
File.delete(TEST_OUT_NAME) if File.exist? TEST_OUT_NAME FileUtils.rm_f(TEST_OUT_NAME)
end end
def teardown def teardown

View File

@ -14,11 +14,11 @@ class StoredSupportTest < MiniTest::Test
entry = zis.get_next_entry entry = zis.get_next_entry
assert_equal 'file1.txt', entry.name assert_equal 'file1.txt', entry.name
assert_equal 1_327, entry.size assert_equal 1_327, entry.size
assert_equal ::File.open(INPUT_FILE1, 'r').read, zis.read assert_equal ::File.read(INPUT_FILE1), zis.read
entry = zis.get_next_entry entry = zis.get_next_entry
assert_equal 'file2.txt', entry.name assert_equal 'file2.txt', entry.name
assert_equal 41_234, entry.size assert_equal 41_234, entry.size
assert_equal ::File.open(INPUT_FILE2, 'r').read, zis.read assert_equal ::File.read(INPUT_FILE2), zis.read
end end
end end
@ -29,11 +29,11 @@ class StoredSupportTest < MiniTest::Test
entry = zis.get_next_entry entry = zis.get_next_entry
assert_equal 'file1.txt', entry.name assert_equal 'file1.txt', entry.name
assert_equal 1_327, entry.size assert_equal 1_327, entry.size
assert_equal ::File.open(INPUT_FILE1, 'r').read, zis.read assert_equal ::File.read(INPUT_FILE1), zis.read
entry = zis.get_next_entry entry = zis.get_next_entry
assert_equal 'file2.txt', entry.name assert_equal 'file2.txt', entry.name
assert_equal 41_234, entry.size assert_equal 41_234, entry.size
assert_equal ::File.open(INPUT_FILE2, 'r').read, zis.read assert_equal ::File.read(INPUT_FILE2), zis.read
end end
end end
end end

View File

@ -12,7 +12,7 @@ require 'gentestfiles'
TestFiles.create_test_files TestFiles.create_test_files
TestZipFile.create_test_zips TestZipFile.create_test_zips
::MiniTest.after_run do MiniTest.after_run do
FileUtils.rm_rf('test/data/generated') FileUtils.rm_rf('test/data/generated')
end end
@ -137,7 +137,7 @@ module CommonZipFileFixture
TEST_ZIP.zip_name = 'test/data/generated/5entry_copy.zip' TEST_ZIP.zip_name = 'test/data/generated/5entry_copy.zip'
def setup def setup
File.delete(EMPTY_FILENAME) if File.exist?(EMPTY_FILENAME) FileUtils.rm_f(EMPTY_FILENAME)
FileUtils.cp(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name) FileUtils.cp(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
end end
end end