def self.from_file(file_path, options = {})
zip_path = options.has_key?(:zip_path) ?
expand_path(options[:zip_path]) :
::File.basename(file_path)
follow_symlinks = options.has_key?(:follow_symlinks) ?
options[:follow_symlinks] :
true
begin
stat = follow_symlinks ?
::File.stat(file_path) :
::File.lstat(file_path)
rescue Errno::ENOENT
if ::File.symlink?(file_path) then
raise Zip::EntryError,
"symlink at `#{file_path}' points to a non-existent file `#{::File.readlink(file_path)}'"
else
raise Zip::EntryError, "no such file or directory `#{file_path}'"
end
end
if stat.directory? then
zip_path += '/'
end
if stat.symlink? then
entry = Entry::Symlink.new(zip_path)
entry.link_target = ::File.readlink(file_path)
elsif stat.file? then
entry = Entry::File.new(zip_path)
entry.file_path = file_path
elsif stat.directory? then
entry = Entry::Directory.new(zip_path)
else
raise Zip::EntryError,
"unsupported file type `#{stat.ftype}' for file `#{file_path}'"
end
unless options[:compression_codec].nil? then
if options[:compression_codec].kind_of?(Proc) then
entry.compression_codec = options[:compression_codec][entry].new
else
entry.compression_codec = options[:compression_codec].new
end
end
unless options[:encryption_codec].nil? then
if options[:encryption_codec].kind_of?(Proc) then
entry.encryption_codec = options[:encryption_codec][entry].new
else
entry.encryption_codec = options[:encryption_codec].new
end
end
entry.uid = stat.uid
entry.gid = stat.gid
entry.mtime = stat.mtime
entry.atime = stat.atime
entry.mode = stat.mode
entry
end