# File lib/archive/zip/entry.rb, line 136
    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

      # Avoid repeatedly stat'ing the file by storing the stat structure once.
      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

      # Ensure that zip paths for directories end with '/'.
      if stat.directory? then
        zip_path += '/'
      end

      # Instantiate the entry.
      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

      # Set the compression and encryption codecs.
      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

      # Set the entry's metadata.
      entry.uid = stat.uid
      entry.gid = stat.gid
      entry.mtime = stat.mtime
      entry.atime = stat.atime
      entry.mode = stat.mode

      entry
    end