module Omnibus::Digestable
Public Class Methods
# File lib/omnibus/digestable.rb, line 24 def self.included(other) other.send(:include, Logging) end
Public Instance Methods
Calculate the digest of the file at the given path. Files are read in binary chunks to prevent Ruby from exploding.
@param [String] path
the path of the file to digest
@param [Symbol] type
the type of digest to use
@return [String]
the hexdigest of the file at the path
# File lib/omnibus/digestable.rb, line 40 def digest(path, type = :md5) digest = digest_from_type(type) update_with_file_contents(digest, path) digest.hexdigest end
Calculate the digest of a directory at the given path. Each file in the directory is read in binary chunks to prevent excess memory usage. Filesystem entries of all types are included in the digest, including directories, links, and sockets. The contents of non-file entries are represented as:
$type $path
while the contents of regular files are represented as:
file $path
and then appended by the binary contents of the file/
@param [String] path
the path of the directory to digest
@param [Symbol] type
the type of digest to use
@param [Hash] options
options to pass through to the FileSyncer when scanning for files
@return [String]
the hexdigest of the directory
# File lib/omnibus/digestable.rb, line 72 def digest_directory(path, type = :md5, options = {}) digest = digest_from_type(type) log.info(log_key) { "Digesting #{path} with #{type}" } FileSyncer.all_files_under(path, options).each do |filename| # Calculate the filename relative to the given path. Since directories # are SHAed according to their filepath, two difference directories on # disk would have different SHAs even if they had the same content. relative = Pathname.new(filename).relative_path_from(Pathname.new(path)) case ftype = File.ftype(filename) when "file" update_with_string(digest, "#{ftype} #{relative}") update_with_file_contents(digest, filename) else update_with_string(digest, "#{ftype} #{relative}") end end digest.hexdigest end
Private Instance Methods
Create a new instance of the {Digest} class that corresponds to the given type.
@param [#to_s] type
the type of digest to use
@return [~Digest]
an instance of the digest class
# File lib/omnibus/digestable.rb, line 105 def digest_from_type(type) id = type.to_s.upcase instance = OpenSSL::Digest.const_get(id).new end
Update the digest with the given contents of the file, reading in small chunks to reduce memory. This method will update the given digest
parameter, but returns nothing.
@param [Digest] digest
the digest to update
@param [String] filename
the path to the file on disk to read
@return [void]
# File lib/omnibus/digestable.rb, line 122 def update_with_file_contents(digest, filename) File.open(filename) do |io| while (chunk = io.read(1024 * 8)) digest.update(chunk) end end end
Update the digest with the given string. This method will update the given digest
parameter, but returns nothing.
@param [Digest] digest
the digest to update
@param [String] string
the string to read
@return [void]
# File lib/omnibus/digestable.rb, line 141 def update_with_string(digest, string) digest.update(string) end