247 lines
8.1 KiB
Ruby
Executable File
247 lines
8.1 KiB
Ruby
Executable File
#
|
|
# File:: %RS_TOOLSLIB%/pipeline/projectutil/data_zip.rb
|
|
# Description:: Zip file functions.
|
|
#
|
|
# Author:: David Muir <david.muir@rockstarnorth.com>
|
|
# Date:: 24 June 2011
|
|
#
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Uses
|
|
#-----------------------------------------------------------------------------
|
|
require 'pipeline/log/log'
|
|
require 'pipeline/os/path'
|
|
include Pipeline
|
|
require 'time'
|
|
require 'zip/zip'
|
|
include Zip
|
|
|
|
require 'pipeline/util/rubyzip2_mtime_fix'
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Implementation
|
|
#-----------------------------------------------------------------------------
|
|
module Pipeline
|
|
module ProjectUtil
|
|
|
|
@@zip_log = Pipeline::Log::new( 'data_zip' )
|
|
|
|
#
|
|
# == Description
|
|
# Extract the content of a ZIP file to a destination directory. The
|
|
# optional block is executed for each file that is extracted specifying the
|
|
# full path of the extracted file.
|
|
#
|
|
# ZIP sub-directories are preserved in the destination directory.
|
|
#
|
|
# The filenames of the extracted files are return in an Array.
|
|
#
|
|
# == Example Usage
|
|
# See %RS_TOOLSLIB%/util/data_extract_zip.rb.
|
|
#
|
|
def ProjectUtil::data_zip_extract( filename, destination, overwrite = false, filter = '*.*', &block )
|
|
dest_files = []
|
|
|
|
FileUtils::mkdir_p( destination ) unless ( File::directory?( destination ) )
|
|
Dir::chdir( destination ) do
|
|
ZipFile::open( filename ) do |zf|
|
|
|
|
zf.each do |entry|
|
|
# Skip filenames that do not match filter.
|
|
next unless ::File::fnmatch( filter, entry.name, File::FNM_CASEFOLD )
|
|
|
|
dir = OS::Path::get_directory( entry.name )
|
|
FileUtils::mkdir_p( dir ) unless ( dir.nil? or 0 == dir.size or File::directory?( dir ) )
|
|
entry.extract do
|
|
overwrite
|
|
end
|
|
|
|
# Local time.
|
|
dest_file = OS::Path::combine( destination, entry.name )
|
|
mtime = ( entry.time )
|
|
File::utime( mtime, mtime, dest_file )
|
|
dest_files << dest_file
|
|
yield( dest_file ) if ( block_given? )
|
|
end
|
|
end
|
|
end
|
|
dest_files
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Extract the contents of a ZIP file to a destination directory. The
|
|
# block is executed with each ZipEntry object as a parameter; if the block
|
|
# returns true then the file is extracted, otherwise the file is not extracted.
|
|
# If the 'overwrite' parameter is used, the block still needs to evaluate
|
|
# to true for the file to be written.
|
|
#
|
|
# ZIP sub-directories are preserved in the destination directory.
|
|
#
|
|
# The filenames of the extracted files are return in an Array.
|
|
#
|
|
# == Example Usage
|
|
# DHM TODO
|
|
#
|
|
def ProjectUtil::data_zip_extract2( filename, destination, overwrite = false, filter = '*.*', &block )
|
|
dest_files = []
|
|
|
|
FileUtils::mkdir_p( destination ) unless ( File::directory?( destination ) )
|
|
Dir::chdir( destination ) do
|
|
ZipFile::open( filename ) do |zf|
|
|
|
|
zf.each do |entry|
|
|
# Skip filenames that do not match filter.
|
|
next unless ::File::fnmatch( filter, entry.name, File::FNM_CASEFOLD )
|
|
|
|
dir = OS::Path::get_directory( entry.name )
|
|
FileUtils::mkdir_p( dir ) unless ( dir.nil? or 0 == dir.size or File::directory?( dir ) )
|
|
if ( block_given? and ( yield entry ) ) then
|
|
entry.extract do
|
|
overwrite
|
|
end
|
|
else
|
|
entry.extract do
|
|
overwrite
|
|
end
|
|
end
|
|
|
|
# Local time.
|
|
dest_file = OS::Path::combine( destination, entry.name )
|
|
mtime = ( entry.time )
|
|
File::utime( mtime, mtime, dest_file )
|
|
dest_files << dest_file
|
|
end
|
|
end
|
|
end
|
|
dest_files
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Extract the contents of a ZIP file to a destination directory. Only
|
|
# files newer than the destination files are overwritten; this can be forced
|
|
# by setting 'overwrite' to true.
|
|
#
|
|
# ZIP sub-directories are preserved in the destination directory.
|
|
#
|
|
# The filenames of the extracted files are return in an Array.
|
|
#
|
|
# == Example Usage
|
|
# DHM TODO
|
|
#
|
|
def ProjectUtil::data_zip_extract3( filename, destination, overwrite = false, filter = '*.*', &block )
|
|
|
|
ProjectUtil::data_zip_extract2( filename, destination, overwrite, filter ) do |entry|
|
|
destination_file = OS::Path::combine( destination, entry.name )
|
|
|
|
if ( File::exists?( destination_file ) ) then
|
|
# Destination file exists; extract if its modified date is
|
|
# earlier than the modified date of the zip entry.
|
|
mtime = File::mtime( destination_file )
|
|
( ( mtime <=> entry.time ) < 0 )
|
|
else
|
|
# Destination file does not exist so we should extract.
|
|
true
|
|
end
|
|
end
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Return Array of filenames within the zip file. Also yields each
|
|
# filename to the block, if given.
|
|
#
|
|
def ProjectUtil::data_zip_filelist( filename, &block )
|
|
dest_files = []
|
|
|
|
ZipFile::foreach( filename ) do |zf|
|
|
yield( zf.name ) if ( block_given? )
|
|
dest_files << zf.name
|
|
end
|
|
dest_files
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Create a ZIP file; from the specific file list.
|
|
#
|
|
# file_list is an Array; of either file path Strings or Hash objects
|
|
# containing two keys, :src, :dst specifying source file and destination
|
|
# path in the zip file.
|
|
#
|
|
# User-block is yielded for each file added (with filename as parameter).
|
|
#
|
|
# == Example Usage
|
|
# See %RS_TOOLSLIB%/util/data_mk_generic_zip.rb
|
|
#
|
|
def ProjectUtil::data_zip_create( filename, file_list, compress = true, &block )
|
|
|
|
directory = OS::Path::get_directory( filename )
|
|
FileUtils::mkdir_p( directory ) if ( not File::directory?( directory ) )
|
|
|
|
# Delete the existing Zip file if it exists.
|
|
FileUtils::rm( filename ) if ( File::exists?( filename ) )
|
|
|
|
# Create the Zip file and write our entries.
|
|
ZipFile::open( filename, ZipFile::CREATE ) do |zf|
|
|
|
|
file_list.each do |path|
|
|
if ( path.is_a?( String ) and File::file?( path ) ) then
|
|
if ( not File::exists?( path ) ) then
|
|
@@zip_log.error( "File #{path} does not exist. Skipping." )
|
|
next
|
|
end
|
|
|
|
entry = zf.add( OS::Path::get_filename( path ), path ) do
|
|
true # continue on exists (overwrite)
|
|
end
|
|
entry.time = File::mtime( File::expand_path( path ) ).getlocal
|
|
entry.compression_method = ZipEntry::DEFLATED if ( compress )
|
|
entry.compression_method = ZipEntry::STORED unless ( compress )
|
|
yield( path ) if ( block_given? )
|
|
|
|
elsif ( path.is_a?( Hash ) and path.has_key?( :src ) and path.has_key?( :dst ) )
|
|
if ( not File::exists?( path[:src] ) ) then
|
|
@@zip_log.error( "File #{path} does not exist. Skipping." )
|
|
next
|
|
end
|
|
|
|
entry = zf.add( path[:dst], path[:src] ) do
|
|
true # continue on exists (overwrite)
|
|
end
|
|
entry.time = File::mtime( File::expand_path( path[:src] ) ).getlocal
|
|
entry.compression_method = ZipEntry::DEFLATED if ( compress )
|
|
entry.compression_method = ZipEntry::STORED unless ( compress )
|
|
yield( path ) if ( block_given? )
|
|
|
|
else
|
|
@@zip_log.error( "Misformed entry in file_list (#{path.class}, '#{path.to_s}')." )
|
|
end
|
|
end
|
|
zf.comment = "Created by #{__FILE__} on #{DateTime::now}"
|
|
@@zip_log.info( "Zip file #{filename} created (#{file_list.size} entries)." )
|
|
|
|
zf.close()
|
|
end
|
|
true
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Read the contents of a file into memory and return its content as a
|
|
# String.
|
|
#
|
|
def ProjectUtil::data_zip_readfile( filename, contained_filename )
|
|
|
|
data = nil
|
|
ZipFile::open( filename ) do |zf|
|
|
|
|
data = zf.read( contained_filename )
|
|
end
|
|
end
|
|
|
|
end # ProjectUtil module
|
|
end # Pipeline module
|
|
|
|
# %RS_TOOLSLIB%/pipeline/projectutil/data_zip.rb |