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)