blob: 779a29521de086229c4c0093d567e4cadc458952 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with this
# work for additional information regarding copyright ownership. The ASF
# licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
require 'zip'
if RUBY_VERSION >= '1.9.0' # Required to properly load RubyZip under Ruby 1.9
$LOADED_FEATURES.unshift 'ftools'
require 'fileutils'
def File.move(source, dest)
FileUtils.move source, dest
end
def File.rm_rf(path)
FileUtils.rm_rf path
end
end
module Zip #:nodoc:
class CentralDirectory #:nodoc:
# Patch to add entries in alphabetical order.
def write_to_stream(io)
offset = io.tell
@entry_set.sort { |a,b| a.name <=> b.name }.each { |entry| entry.write_c_dir_entry(io) }
eocd_offset = io.tell
cdir_size = eocd_offset - offset
write_e_o_c_d(io, offset, cdir_size)
end
end
class File
# :call-seq:
# exist() => boolean
#
# Returns true if this entry exists.
def exist?(entry_name)
!!find_entry(entry_name)
end
end
class Entry
# :call-seq:
# exist() => boolean
#
# Returns true if this entry exists.
def exist?()
File.open(zipfile) { |zip| zip.exist?(@name) }
end
# :call-seq:
# empty?() => boolean
#
# Returns true if this entry is empty.
def empty?()
File.open(zipfile) { |zip| zip.read(@name) }.empty?
end
# :call-seq:
# contain(patterns*) => boolean
#
# Returns true if this ZIP file entry matches against all the arguments. An argument may be
# a string or regular expression.
def contain?(*patterns)
content = File.open(zipfile) { |zip| zip.read(@name) }
patterns.map { |pattern| Regexp === pattern ? pattern : Regexp.new(Regexp.escape(pattern.to_s)) }.
all? { |pattern| content =~ pattern }
end
# Override of write_c_dir_entry to fix comments being set to a fixnum instead of string
def write_c_dir_entry(io) #:nodoc:all
case @fstype
when FSTYPE_UNIX
ft = nil
case @ftype
when :file
ft = 010
@unix_perms ||= 0644
when :directory
ft = 004
@unix_perms ||= 0755
when :symlink
ft = 012
@unix_perms ||= 0755
else
raise ZipInternalError, "unknown file type #{self.inspect}"
end
@external_file_attributes = (ft << 12 | (@unix_perms & 07777)) << 16
end
io <<
[0x02014b50,
@version, # version of encoding software
@fstype, # filesystem type
10, # @versionNeededToExtract
0, # @gp_flags
@compression_method,
@time.to_binary_dos_time, # @lastModTime
@time.to_binary_dos_date, # @lastModDate
@crc,
@compressed_size,
@size,
@name ? @name.length : 0,
@extra ? @extra.c_dir_size : 0,
@comment ? comment.to_s.length : 0,
0, # disk number start
@internal_file_attributes, # file type (binary=0, text=1)
@external_file_attributes, # native filesystem attributes
@local_header_offset,
@name,
@extra,
@comment
].pack('VCCvvvvvVVVvvvvvVV')
io << @name
io << (@extra ? @extra.to_c_dir_bin : "")
io << @comment
end
# Override write_c_dir_entry to fix comments being set to a fixnum instead of string
def write_c_dir_entry(io) #:nodoc:all
@comment = "" if @comment.nil? || @comment == -1 # Hack fix @comment being nil or fixnum -1
case @fstype
when FSTYPE_UNIX
ft = nil
case @ftype
when :file
ft = 010
@unix_perms ||= 0644
when :directory
ft = 004
@unix_perms ||= 0755
when :symlink
ft = 012
@unix_perms ||= 0755
else
raise ZipInternalError, "unknown file type #{self.inspect}"
end
@external_file_attributes = (ft << 12 | (@unix_perms & 07777)) << 16
end
io <<
[0x02014b50,
@version, # version of encoding software
@fstype, # filesystem type
10, # @versionNeededToExtract
0, # @gp_flags
@compression_method,
@time.to_binary_dos_time, # @lastModTime
@time.to_binary_dos_date, # @lastModDate
@crc,
@compressed_size,
@size,
@name ? @name.length : 0,
@extra ? @extra.c_dir_size : 0,
@comment ? @comment.length : 0,
0, # disk number start
@internal_file_attributes, # file type (binary=0, text=1)
@external_file_attributes, # native filesystem attributes
@local_header_offset,
@name,
@extra,
@comment].pack('VCCvvvvvVVVvvvvvVV')
io << @name
io << (@extra ? @extra.to_c_dir_bin : "")
io << @comment
end
end
end