def archive(paths, options = {})
raise IOError, 'non-writable archive' unless writable?
raise IOError, 'closed archive' if closed?
paths = [paths] unless paths.kind_of?(Enumerable)
paths = paths.collect do |path|
basename = File.basename(path)
if basename == '.' || basename == '..' then
Dir.entries(path).reject do |e|
e == '.' || e == '..'
end.collect do |e|
File.join(path, e)
end
else
path
end
end.flatten.uniq
options[:path_prefix] = '' unless options.has_key?(:path_prefix)
options[:recursion] = true unless options.has_key?(:recursion)
options[:directories] = true unless options.has_key?(:directories)
options[:symlinks] = false unless options.has_key?(:symlinks)
options[:flatten] = false unless options.has_key?(:flatten)
if options[:flatten] then
options[:path_prefix] = ''
options[:directories] = false
end
options[:path_prefix] = Entry.expand_path(options[:path_prefix].to_s)
paths.each do |path|
zip_entry_path = File.basename(path)
zip_entry_path += '/' if File.directory?(path)
unless options[:path_prefix].empty? then
zip_entry_path = "#{options[:path_prefix]}/#{zip_entry_path}"
end
begin
zip_entry = Zip::Entry.from_file(
path,
options.merge(
:zip_path => zip_entry_path,
:follow_symlinks => options.has_key?(:follow_symlinks) ?
options[:follow_symlinks] :
! options[:symlinks]
)
)
rescue StandardError => error
unless options[:on_error].nil? then
case options[:on_error][path, error]
when :retry
retry
when :skip
next
else
raise
end
else
raise
end
end
if (zip_entry.symlink? && ! options[:symlinks]) ||
(! options[:exclude].nil? && options[:exclude][zip_entry]) then
next
end
if options[:password].kind_of?(String) then
zip_entry.password = options[:password]
elsif ! options[:password].nil? then
zip_entry.password = options[:password][zip_entry]
end
if (! zip_entry.directory? || options[:directories]) then
add_entry(zip_entry)
end
if zip_entry.directory? && options[:recursion] then
archive(
Dir.entries(path).reject do |e|
e == '.' || e == '..'
end.collect do |e|
File.join(path, e)
end,
options.merge(:path_prefix => zip_entry_path)
)
end
end
nil
end