lib/signed_form/digestor.rb
require 'set'
module SignedForm
class Digestor
attr_accessor :view_paths
def initialize(template)
@view_paths = Set.new
@views = Set.new
self << template
end
def <<(template)
virtual_path = get_virtual_path(template)
raise Errors::UnableToDigest, "Unable to get virtual path from template" unless virtual_path
@views << virtual_path
@view_paths += template.view_paths.map(&:to_s)
@digest = nil
rescue NoMethodError
raise Errors::UnableToDigest, "Unable get view paths from template"
end
def marshal_dump
[@views.to_a, to_s]
end
def marshal_load(input)
@views, @digest = input
@view_paths = []
@digest.taint
end
def to_s
@digest ||= SignedForm.digest_store.fetch(@views.sort.join(':')) { hash_files(glob_files) }
end
alias_method :digest, :to_s
def refresh
@digest = nil
end
private
def glob_files
globbed_files = []
view_paths.each do |path|
@views.each { |view| globbed_files += Dir["#{path}/#{view}.*"] }
end
globbed_files
end
def hash_files(files)
raise Errors::UnableToDigest, "No files to digest" if files.empty?
md5 = Digest::MD5.new
files.sort.each do |entry|
File.open(entry) { |f| md5 << f.read }
end
md5.to_s
end
def get_virtual_path(template)
template.respond_to?(:virtual_path) ? template.virtual_path : template.instance_variable_get(:@virtual_path)
end
end
end