class Nanoc::Int::OutdatednessChecker

Responsible for determining whether an item or a layout is outdated.

@api private

Constants

Reasons

Attributes

checksum_store[R]
dependency_store[R]
rule_memory_store[R]
site[R]

Public Class Methods

new(site:, checksum_store:, dependency_store:, rule_memory_store:, action_provider:, reps:) click to toggle source

@param [Nanoc::Int::Site] site @param [Nanoc::Int::ChecksumStore] #checksum_store @param [Nanoc::Int::DependencyStore] #dependency_store @param [Nanoc::Int::RuleMemoryStore] #rule_memory_store @param [Nanoc::Int::ActionProvider] action_provider @param [Nanoc::Int::ItemRepRepo] reps

# File lib/nanoc/base/compilation/outdatedness_checker.rb, line 21
def initialize(site,, checksum_store,, dependency_store,, rule_memory_store,, action_provider,, reps))
  @site = site
  @checksum_store = checksum_store
  @dependency_store = dependency_store
  @rule_memory_store = rule_memory_store
  @action_provider = action_provider
  @reps = reps

  @basic_outdatedness_reasons = {}
  @outdatedness_reasons = {}
  @objects_outdated_due_to_dependencies = {}
end

Public Instance Methods

outdated?(obj) click to toggle source

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.

@return [Boolean] true if the object is outdated, false otherwise

# File lib/nanoc/base/compilation/outdatedness_checker.rb, line 41
def outdated?(obj)
  !outdatedness_reason_for(obj).nil?
end
outdatedness_reason_for(obj) click to toggle source

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.

@return [Reasons::Generic, nil] The reason why the

given object is outdated, or nil if the object is not outdated.
# File lib/nanoc/base/compilation/outdatedness_checker.rb, line 52
def outdatedness_reason_for(obj)
  reason = basic_outdatedness_reason_for(obj)
  if reason.nil? && outdated_due_to_dependencies?(obj)
    reason = Reasons::DependenciesOutdated
  end
  reason
end

Private Instance Methods

basic_outdated?(obj) click to toggle source

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.

@param [Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Layout] obj The object

whose outdatedness should be checked.

@return [Boolean] true if the object is outdated, false otherwise

# File lib/nanoc/base/compilation/outdatedness_checker.rb, line 72
def basic_outdated?(obj)
  !basic_outdatedness_reason_for(obj).nil?
end
basic_outdatedness_reason_for(obj) click to toggle source

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

whose outdatedness reason should be calculated.

@return [Reasons::Generic, nil] The reason why the

given object is outdated, or nil if the object is not outdated.
# File lib/nanoc/base/compilation/outdatedness_checker.rb, line 85
def basic_outdatedness_reason_for(obj)
  case obj
  when Nanoc::Int::ItemRep
    # 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.item)
    return Reasons::SourceModified unless 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
    return Reasons::CodeSnippetsModified if site.code_snippets.any? do |cs|
      object_modified?(cs)
    end

    # Outdated if configuration outdated
    return Reasons::ConfigurationModified if object_modified?(site.config)

    # Not outdated
    return nil
  when Nanoc::Int::Item
    @reps[obj].find { |rep| basic_outdatedness_reason_for(rep) }
  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)

    # Not outdated
    return nil
  else
    raise "do not know how to check outdatedness of #{obj.inspect}"
  end
end
calc_checksum(obj) click to toggle source

@param obj The object to create a checksum for

@return [String] The digest

# File lib/nanoc/base/compilation/outdatedness_checker.rb, line 178
def calc_checksum(obj)
  Nanoc::Int::Checksummer.calc(obj)
end
checksums_available?(obj) click to toggle source

@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
# File lib/nanoc/base/compilation/outdatedness_checker.rb, line 187
def checksums_available?(obj)
  checksum_store[obj] && calc_checksum(obj)
end
checksums_identical?(obj) click to toggle source

@param obj

@return [Boolean] false if the old and new checksums for the given

object differ, true if they are identical
# File lib/nanoc/base/compilation/outdatedness_checker.rb, line 196
def checksums_identical?(obj)
  checksum_store[obj] == calc_checksum(obj)
end
object_modified?(obj) click to toggle source

@param obj

@return [Boolean] true if the old and new checksums for the given object

are available and identical, false otherwise
# File lib/nanoc/base/compilation/outdatedness_checker.rb, line 205
def object_modified?(obj)
  !checksums_available?(obj) || !checksums_identical?(obj)
end
outdated_due_to_dependencies?(obj, processed = Set.new) click to toggle source

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.

@param [Set] processed The collection of items that has been visited

during this outdatedness check. This is used to prevent checks for
items that (indirectly) depend on their own from looping
indefinitely. It should not be necessary to pass this a custom value.

@return [Boolean] true if the object is outdated, false otherwise

# File lib/nanoc/base/compilation/outdatedness_checker.rb, line 139
def outdated_due_to_dependencies?(obj, processed = Set.new)
  # Convert from rep to item if necessary
  obj = obj.item if obj.is_a?(Nanoc::Int::ItemRep)

  # Get from cache
  if @objects_outdated_due_to_dependencies.key?(obj)
    return @objects_outdated_due_to_dependencies[obj]
  end

  # Check processed
  # Don’t return true; the false will be or’ed into a true if there
  # really is a dependency that is causing outdatedness.
  return false if processed.include?(obj)

  # Calculate
  is_outdated = dependency_store.objects_causing_outdatedness_of(obj).any? do |other|
    other.nil? || basic_outdated?(other) || outdated_due_to_dependencies?(other, processed.merge([obj]))
  end

  # Cache
  @objects_outdated_due_to_dependencies[obj] = is_outdated

  # Done
  is_outdated
end
rule_memory_differs_for(obj) click to toggle source

@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
# File lib/nanoc/base/compilation/outdatedness_checker.rb, line 170
def rule_memory_differs_for(obj)
  !rule_memory_store[obj].eql?(@action_provider.memory_for(obj).serialize)
end