lib/nanoc/base/compilation/outdatedness_checker.rb in nanoc-4.3.8 vs lib/nanoc/base/compilation/outdatedness_checker.rb in nanoc-4.4.0
- old
+ new
@@ -3,10 +3,12 @@
#
# @api private
class OutdatednessChecker
extend Nanoc::Int::Memoization
+ include Nanoc::Int::ContractsSupport
+
attr_reader :checksum_store
attr_reader :dependency_store
attr_reader :rule_memory_store
attr_reader :site
@@ -29,10 +31,11 @@
@basic_outdatedness_reasons = {}
@outdatedness_reasons = {}
@objects_outdated_due_to_dependencies = {}
end
+ contract C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Layout] => C::Bool
# Checks whether the given object is outdated and therefore needs to be
# recompiled.
#
# @param [Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Layout] obj The object
# whose outdatedness should be checked.
@@ -40,10 +43,11 @@
# @return [Boolean] true if the object is outdated, false otherwise
def outdated?(obj)
!outdatedness_reason_for(obj).nil?
end
+ contract C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Layout] => C::Maybe[Reasons::Generic]
# Calculates the reason why the given object is outdated.
#
# @param [Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Layout] obj The object
# whose outdatedness reason should be calculated.
#
@@ -58,10 +62,11 @@
end
memoize :outdatedness_reason_for
private
+ contract C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Layout] => C::Bool
# Checks whether the given object is outdated and therefore needs to be
# recompiled. This method does not take dependencies into account; use
# {#outdated?} if you want to include dependencies in the outdatedness
# check.
#
@@ -71,10 +76,11 @@
# @return [Boolean] true if the object is outdated, false otherwise
def basic_outdated?(obj)
!basic_outdatedness_reason_for(obj).nil?
end
+ contract C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Layout] => C::Maybe[Reasons::Generic]
# Calculates the reason why the given object is outdated. This method does
# not take dependencies into account; use {#outdatedness_reason_for?} if
# you want to include dependencies in the outdatedness check.
#
# @param [Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Layout] obj The object
@@ -89,11 +95,12 @@
return Reasons::RulesModified if
rule_memory_differs_for(obj)
# Outdated if checksums are missing or different
return Reasons::NotEnoughData unless checksums_available?(obj.item)
- return Reasons::SourceModified unless checksums_identical?(obj.item)
+ return Reasons::ContentModified unless content_checksums_identical?(obj.item)
+ return Reasons::AttributesModified unless attributes_checksums_identical?(obj.item)
# Outdated if compiled file doesn't exist (yet)
return Reasons::NotWritten if obj.raw_path && !File.file?(obj.raw_path)
# Outdated if code snippets outdated
@@ -105,28 +112,30 @@
return Reasons::ConfigurationModified if object_modified?(site.config)
# Not outdated
nil
when Nanoc::Int::Item
- @reps[obj].find { |rep| basic_outdatedness_reason_for(rep) }
+ @reps[obj].lazy.map { |rep| basic_outdatedness_reason_for(rep) }.find { |s| s }
when Nanoc::Int::Layout
# Outdated if rules outdated
return Reasons::RulesModified if
rule_memory_differs_for(obj)
# Outdated if checksums are missing or different
return Reasons::NotEnoughData unless checksums_available?(obj)
- return Reasons::SourceModified unless checksums_identical?(obj)
+ return Reasons::ContentModified unless content_checksums_identical?(obj)
+ return Reasons::AttributesModified unless attributes_checksums_identical?(obj)
# Not outdated
nil
else
raise "do not know how to check outdatedness of #{obj.inspect}"
end
end
memoize :basic_outdatedness_reason_for
+ contract C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Layout], Hamster::Set => C::Bool
# Checks whether the given object is outdated due to dependencies.
#
# @param [Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Layout] obj The object
# whose outdatedness should be checked.
#
@@ -160,45 +169,62 @@
# Done
is_outdated
end
+ contract C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Layout] => C::Bool
# @param [Nanoc::Int::ItemRep, Nanoc::Int::Layout] obj The layout or item
# representation to check the rule memory for
#
# @return [Boolean] true if the rule memory for the given item
# represenation has changed, false otherwise
def rule_memory_differs_for(obj)
!rule_memory_store[obj].eql?(@action_provider.memory_for(obj).serialize)
end
memoize :rule_memory_differs_for
+ contract C::Any => String
# @param obj The object to create a checksum for
#
# @return [String] The digest
def calc_checksum(obj)
Nanoc::Int::Checksummer.calc(obj)
end
memoize :calc_checksum
+ contract C::Any => C::Bool
# @param obj
#
# @return [Boolean] false if either the new or the old checksum for the
# given object is not available, true if both checksums are available
def checksums_available?(obj)
- checksum_store[obj] && calc_checksum(obj)
+ checksum_store[obj] && calc_checksum(obj) ? true : false
end
memoize :checksums_available?
+ contract C::Any => C::Bool
# @param obj
#
# @return [Boolean] false if the old and new checksums for the given
# object differ, true if they are identical
def checksums_identical?(obj)
checksum_store[obj] == calc_checksum(obj)
end
memoize :checksums_identical?
+ contract C::Or[Nanoc::Int::Item, Nanoc::Int::Layout] => C::Bool
+ def content_checksums_identical?(obj)
+ checksum_store.content_checksum_for(obj) == Nanoc::Int::Checksummer.calc_for_content_of(obj)
+ end
+ memoize :content_checksums_identical?
+
+ contract C::Or[Nanoc::Int::Item, Nanoc::Int::Layout] => C::Bool
+ def attributes_checksums_identical?(obj)
+ checksum_store.attributes_checksum_for(obj) == Nanoc::Int::Checksummer.calc_for_attributes_of(obj)
+ end
+ memoize :attributes_checksums_identical?
+
+ contract C::Any => C::Bool
# @param obj
#
# @return [Boolean] true if the old and new checksums for the given object
# are available and identical, false otherwise
def object_modified?(obj)