Permalink
Browse files

Merge pull request rubyzip#25 from 2potatocakes/master

Added better support for windows mingw users
Need more testing on windows.
  • Loading branch information...
simonoff committed Feb 7, 2012
2 parents f826268 + 3f8b14f commit 5d0b4db5b38c16735c35c4ac276053b421495a45
Showing with 181 additions and 170 deletions.
  1. +1 −1 TODO
  2. +3 −2 lib/zip/constants.rb
  3. +3 −3 lib/zip/zip_entry.rb
  4. +2 −1 lib/zip/zip_file.rb
  5. +8 −10 lib/zip/zip_input_stream.rb
  6. +2 −3 lib/zip/zip_output_stream.rb
  7. +48 −43 test/gentestfiles.rb
  8. +43 −29 test/zipfilesystemtest.rb
  9. +71 −78 test/ziptest.rb
View
2 TODO
@@ -4,7 +4,7 @@
* Suggestion: Add ZipFile/ZipInputStream example that demonstrates extracting all entries.
* Suggestion: ZipFile#extract destination should default to "."
* Suggestion: ZipEntry should have extract(), get_input_stream() methods etc
* SUggestion: ZipInputStream/ZipOutputStream should accept an IO object in addition to a filename.
* Suggestion: ZipInputStream/ZipOutputStream should accept an IO object in addition to a filename.
* (is buffering used anywhere with write?)
* Inflater.sysread should pass the buffer to produce_input.
* Implement ZipFsDir.glob
View
@@ -1,7 +1,8 @@
module Zip
VERSION = '0.9.4'
VERSION = '0.9.5'
RUBY_MINOR_VERSION = RUBY_VERSION.split(".")[1].to_i
RUNNING_ON_WINDOWS = RbConfig::CONFIG['host_os'] =~ /^win|mswin/i
RUNNING_ON_WINDOWS = RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/i
# Ruby 1.7.x compatibility
# In ruby 1.6.x and 1.8.0 reading from an empty stream returns
# an empty string the first time and then nil.
View
@@ -62,7 +62,7 @@ class ZipEntry
# Returns the character encoding used for name and comment
def name_encoding
(@gp_flags & 0b100000000000) != 0 ? "utf8" : "CP437//"
(@gp_flags & 0b100000000000) != 0 ? "UTF-8" : "CP437//"
end
# Returns the name in the encoding specified by enc
@@ -140,7 +140,7 @@ def time
if @extra["UniversalTime"]
@extra["UniversalTime"].mtime
else
# Atandard time field in central directory has local time
# Standard time field in central directory has local time
# under archive creator. Then, we can't get timezone.
@time
end
@@ -635,4 +635,4 @@ def create_symlink(destPath)
# Copyright (C) 2002, 2003 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.
# modify it under the terms of the ruby license.
View
@@ -177,7 +177,8 @@ def rename(entry, newName, &continueOnExistsProc)
# the file system).
def replace(entry, srcPath)
check_file(srcPath)
add(remove(entry), srcPath)
remove(entry)
add(entry, srcPath)
end
# Extracts entry to file destPath.
@@ -88,8 +88,7 @@ def ZipInputStream.open_buffer(io)
# no more entries.
def get_next_entry
@archiveIO.seek(@currentEntry.next_header_offset,
IO::SEEK_SET) if @currentEntry
@archiveIO.seek(@currentEntry.next_header_offset, IO::SEEK_SET) if @currentEntry
open_entry
end
@@ -116,16 +115,15 @@ def eof
def open_entry
@currentEntry = ZipEntry.read_local_entry(@archiveIO)
if (@currentEntry == nil)
@decompressor = NullDecompressor.instance
if @currentEntry.nil?
@decompressor = NullDecompressor.instance
elsif @currentEntry.compression_method == ZipEntry::STORED
@decompressor = PassThruDecompressor.new(@archiveIO,
@currentEntry.size)
@decompressor = PassThruDecompressor.new(@archiveIO, @currentEntry.size)
elsif @currentEntry.compression_method == ZipEntry::DEFLATED
@decompressor = Inflater.new(@archiveIO)
@decompressor = Inflater.new(@archiveIO)
else
raise ZipCompressionMethodError,
"Unsupported compression method #{@currentEntry.compression_method}"
raise ZipCompressionMethodError,
"Unsupported compression method #{@currentEntry.compression_method}"
end
flush
return @currentEntry
@@ -143,4 +141,4 @@ def input_finished?
# Copyright (C) 2002, 2003 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.
# modify it under the terms of the ruby license.
@@ -101,11 +101,10 @@ def copy_raw_entry(entry)
src_pos = entry.local_entry_offset
entry.write_local_entry(@outputStream)
@compressor = NullCompressor.instance
entry.get_raw_input_stream {
|is|
entry.get_raw_input_stream do |is|
is.seek(src_pos, IO::SEEK_SET)
IOExtras.copy_stream_n(@outputStream, is, entry.compressed_size)
}
end
@compressor = NullCompressor.instance
@currentEntry = nil
end
View
@@ -22,37 +22,33 @@ def TestFiles.create_test_files(recreate)
Dir.mkdir "data/generated" rescue Errno::EEXIST
ASCII_TEST_FILES.each_with_index {
|filename, index|
create_random_ascii(filename, 1E4 * (index+1))
}
ASCII_TEST_FILES.each_with_index do |filename, index|
create_random_ascii(filename, 1E4 * (index+1))
end
BINARY_TEST_FILES.each_with_index {
|filename, index|
create_random_binary(filename, 1E4 * (index+1))
}
BINARY_TEST_FILES.each_with_index do |filename, index|
create_random_binary(filename, 1E4 * (index+1))
end
ensure_dir(EMPTY_TEST_DIR)
end
end
private
def TestFiles.create_random_ascii(filename, size)
File.open(filename, "wb") {
|file|
File.open(filename, "wb") do |file|
while (file.tell < size)
file << rand
file << rand
end
}
end
end
def TestFiles.create_random_binary(filename, size)
File.open(filename, "wb") {
|file|
File.open(filename, "wb") do |file|
while (file.tell < size)
file << [rand].pack("V")
file << [rand].pack("V")
end
}
end
end
def TestFiles.ensure_dir(name)
@@ -90,57 +86,66 @@ def TestZipFile.create_test_zips(recreate)
files.index("short.txt") &&
files.index("longAscii.txt") &&
files.index("longBinary.bin") ))
raise "failed to create test zip '#{TEST_ZIP1.zip_name}'" unless
system("zip #{TEST_ZIP1.zip_name} data/file2.txt")
raise "failed to remove entry from '#{TEST_ZIP1.zip_name}'" unless
system("zip #{TEST_ZIP1.zip_name} -d data/file2.txt")
raise "failed to create test zip '#{TEST_ZIP1.zip_name}'" unless
system("zip #{TEST_ZIP1.zip_name} data/file2.txt")
raise "failed to remove entry from '#{TEST_ZIP1.zip_name}'" unless
system("zip #{TEST_ZIP1.zip_name} -d data/file2.txt")
File.open("data/generated/empty.txt", "w") {}
File.open("data/generated/empty_chmod640.txt", "w") { |f| f.chmod(0640) }
File.open("data/generated/short.txt", "w") { |file| file << "ABCDEF" }
ziptestTxt=""
File.open("data/file2.txt") { |file| ziptestTxt=file.read }
File.open("data/generated/longAscii.txt", "w") {
|file|
while (file.tell < 1E5)
file << ziptestTxt
end
}
File.open("data/generated/longAscii.txt", "w") do |file|
while (file.tell < 1E5)
file << ziptestTxt
end
end
testBinaryPattern=""
File.open("data/generated/empty.zip") { |file| testBinaryPattern=file.read }
testBinaryPattern *= 4
File.open("data/generated/longBinary.bin", "wb") {
|file|
while (file.tell < 3E5)
file << testBinaryPattern << rand << "\0"
end
}
raise "failed to create test zip '#{TEST_ZIP2.zip_name}'" unless
system("zip #{TEST_ZIP2.zip_name} #{TEST_ZIP2.entry_names.join(' ')}")
File.open("data/generated/longBinary.bin", "wb") do |file|
while (file.tell < 3E5)
file << testBinaryPattern << rand << "\0"
end
end
raise "failed to create test zip '#{TEST_ZIP2.zip_name}'" unless
system("zip #{TEST_ZIP2.zip_name} #{TEST_ZIP2.entry_names.join(' ')}")
if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless
system("echo #{TEST_ZIP2.comment}| zip -z #{TEST_ZIP2.zip_name}\"")
else
# without bash system interprets everything after echo as parameters to
# echo including | zip -z ...
raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless
system("bash -c \"echo #{TEST_ZIP2.comment} | zip -z #{TEST_ZIP2.zip_name}\"")
raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless
system("bash -c \"echo #{TEST_ZIP2.comment} | zip -z #{TEST_ZIP2.zip_name}\"")
end
raise "failed to create test zip '#{TEST_ZIP3.zip_name}'" unless
system("zip #{TEST_ZIP3.zip_name} #{TEST_ZIP3.entry_names.join(' ')}")
raise "failed to create test zip '#{TEST_ZIP3.zip_name}'" unless
system("zip #{TEST_ZIP3.zip_name} #{TEST_ZIP3.entry_names.join(' ')}")
raise "failed to create test zip '#{TEST_ZIP4.zip_name}'" unless
system("zip #{TEST_ZIP4.zip_name} #{TEST_ZIP4.entry_names.join(' ')}")
raise "failed to create test zip '#{TEST_ZIP4.zip_name}'" unless
system("zip #{TEST_ZIP4.zip_name} #{TEST_ZIP4.entry_names.join(' ')}")
end
rescue
raise $!.to_s +
rescue
# If there are any Windows developers wanting to use a command line zip.exe
# to help create the following files, there's a free one available from
# http://stahlworks.com/dev/index.php?tool=zipunzip
# that works with the above code
raise $!.to_s +
"\n\nziptest.rb requires the Info-ZIP program 'zip' in the path\n" +
"to create test data. If you don't have it you can download\n" +
"the necessary test files at http://sf.net/projects/rubyzip."
end
TEST_ZIP1 = TestZipFile.new("data/generated/empty.zip", [])
TEST_ZIP2 = TestZipFile.new("data/generated/5entry.zip", %w{ data/generated/longAscii.txt data/generated/empty.txt data/generated/empty_chmod640.txt data/generated/short.txt data/generated/longBinary.bin},
TEST_ZIP2 = TestZipFile.new("data/generated/5entry.zip", %w{ data/generated/longAscii.txt data/generated/empty.txt data/generated/empty_chmod640.txt data/generated/short.txt data/generated/longBinary.bin},
"my zip comment")
TEST_ZIP3 = TestZipFile.new("data/generated/test1.zip", %w{ data/file1.txt })
TEST_ZIP4 = TestZipFile.new("data/generated/zipWithDir.zip", [ "data/file1.txt",
View
@@ -432,39 +432,46 @@ def test_pipe
end
def test_foreach
ZipFile.open("data/generated/zipWithDir.zip") {
|zf|
ZipFile.open("data/generated/zipWithDir.zip") do |zf|
ref = []
File.foreach("data/file1.txt") { |e| ref << e }
index = 0
zf.file.foreach("data/file1.txt") {
|l|
assert_equal(ref[index], l)
zf.file.foreach("data/file1.txt") do |l|
#Ruby replaces \n with \r\n automatically on windows
newline = Zip::RUNNING_ON_WINDOWS ? l.gsub(/\r\n/, "\n") : l
assert_equal(ref[index], newline)
index = index.next
}
end
assert_equal(ref.size, index)
}
end
ZipFile.open("data/generated/zipWithDir.zip") {
|zf|
ZipFile.open("data/generated/zipWithDir.zip") do |zf|
ref = []
File.foreach("data/file1.txt", " ") { |e| ref << e }
index = 0
zf.file.foreach("data/file1.txt", " ") {
|l|
assert_equal(ref[index], l)
zf.file.foreach("data/file1.txt", " ") do |l|
#Ruby replaces \n with \r\n automatically on windows
newline = Zip::RUNNING_ON_WINDOWS ? l.gsub(/\r\n/, "\n") : l
assert_equal(ref[index], newline)
index = index.next
}
end
assert_equal(ref.size, index)
}
end
end
def test_popen
cmd = /mswin/i =~ RUBY_PLATFORM ? 'dir' : 'ls'
assert_equal(File.popen(cmd) { |f| f.read },
@zipFile.file.popen(cmd) { |f| f.read })
if Zip::RUNNING_ON_WINDOWS
#This is pretty much projectile vomit but it allows the test to be
#run on windows also
system_dir = File.popen('dir') { |f| f.read }.gsub(/Dir\(s\).*$/, '')
zipfile_dir = @zipFile.file.popen('dir') { |f| f.read }.gsub(/Dir\(s\).*$/, '')
assert_equal(system_dir, zipfile_dir)
else
assert_equal(File.popen('ls') { |f| f.read },
@zipFile.file.popen('ls') { |f| f.read })
end
end
# Can be added later
@@ -473,19 +480,26 @@ def test_popen
# end
def test_readlines
ZipFile.open("data/generated/zipWithDir.zip") {
|zf|
assert_equal(File.readlines("data/file1.txt"),
zf.file.readlines("data/file1.txt"))
}
ZipFile.open("data/generated/zipWithDir.zip") do |zf|
orig_file = File.readlines("data/file1.txt")
zip_file = zf.file.readlines("data/file1.txt")
#Ruby replaces \n with \r\n automatically on windows
zip_file.each { |l| l.gsub!(/\r\n/, "\n") } if Zip::RUNNING_ON_WINDOWS
assert_equal(orig_file, zip_file)
end
end
def test_read
ZipFile.open("data/generated/zipWithDir.zip") {
|zf|
assert_equal(File.read("data/file1.txt"),
zf.file.read("data/file1.txt"))
}
ZipFile.open("data/generated/zipWithDir.zip") do |zf|
orig_file = File.read("data/file1.txt")
#Ruby replaces \n with \r\n automatically on windows
zip_file = Zip::RUNNING_ON_WINDOWS ? \
zf.file.read("data/file1.txt").gsub(/\r\n/, "\n") : zf.file.read("data/file1.txt")
assert_equal(orig_file, zip_file)
end
end
end
Oops, something went wrong.

0 comments on commit 5d0b4db

Please sign in to comment.