nanoc 4.7.3 → 4.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -5
- data/NEWS.md +7 -0
- data/lib/nanoc/base/entities.rb +1 -1
- data/lib/nanoc/base/entities/{rule_memory.rb → action_sequence.rb} +19 -1
- data/lib/nanoc/base/entities/outdatedness_reasons.rb +12 -4
- data/lib/nanoc/base/entities/outdatedness_status.rb +1 -1
- data/lib/nanoc/base/repos.rb +1 -1
- data/lib/nanoc/base/repos/{rule_memory_store.rb → action_sequence_store.rb} +12 -12
- data/lib/nanoc/base/repos/checksum_store.rb +3 -3
- data/lib/nanoc/base/services/action_provider.rb +1 -9
- data/lib/nanoc/base/services/checksummer.rb +4 -2
- data/lib/nanoc/base/services/compiler.rb +11 -11
- data/lib/nanoc/base/services/compiler/phases/recalculate.rb +3 -3
- data/lib/nanoc/base/services/compiler/stages/cleanup.rb +1 -1
- data/lib/nanoc/base/services/compiler/stages/compile_reps.rb +3 -3
- data/lib/nanoc/base/services/compiler/stages/determine_outdatedness.rb +7 -2
- data/lib/nanoc/base/services/compiler_loader.rb +3 -3
- data/lib/nanoc/base/services/item_rep_builder.rb +4 -2
- data/lib/nanoc/base/services/item_rep_router.rb +7 -2
- data/lib/nanoc/base/services/outdatedness_checker.rb +30 -7
- data/lib/nanoc/base/services/outdatedness_rule.rb +7 -4
- data/lib/nanoc/base/services/outdatedness_rules.rb +9 -161
- data/lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb +34 -0
- data/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb +26 -0
- data/lib/nanoc/base/services/outdatedness_rules/configuration_modified.rb +23 -0
- data/lib/nanoc/base/services/outdatedness_rules/content_modified.rb +15 -0
- data/lib/nanoc/base/services/outdatedness_rules/not_written.rb +11 -0
- data/lib/nanoc/base/services/outdatedness_rules/paths_modified.rb +20 -0
- data/lib/nanoc/base/services/outdatedness_rules/rules_modified.rb +13 -0
- data/lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb +20 -0
- data/lib/nanoc/rule_dsl.rb +1 -1
- data/lib/nanoc/rule_dsl/action_provider.rb +7 -11
- data/lib/nanoc/rule_dsl/{rule_memory_calculator.rb → action_sequence_calculator.rb} +21 -39
- data/lib/nanoc/rule_dsl/recording_executor.rb +7 -7
- data/lib/nanoc/spec.rb +7 -7
- data/lib/nanoc/version.rb +1 -1
- data/spec/nanoc/base/checksummer_spec.rb +20 -0
- data/spec/nanoc/base/compiler_spec.rb +7 -10
- data/spec/nanoc/base/entities/action_sequence_spec.rb +278 -0
- data/spec/nanoc/base/repos/checksum_store_spec.rb +22 -2
- data/spec/nanoc/base/services/compiler/stages/cleanup_spec.rb +2 -2
- data/spec/nanoc/base/services/compiler/stages/compile_reps_spec.rb +5 -9
- data/spec/nanoc/base/services/executor_spec.rb +5 -5
- data/spec/nanoc/base/services/item_rep_router_spec.rb +36 -18
- data/spec/nanoc/base/services/outdatedness_checker_spec.rb +74 -30
- data/spec/nanoc/base/services/outdatedness_rules_spec.rb +78 -18
- data/spec/nanoc/helpers/rendering_spec.rb +4 -4
- data/spec/nanoc/rule_dsl/{rule_memory_calculator_spec.rb → action_sequence_calculator_spec.rb} +6 -61
- data/spec/nanoc/rule_dsl/recording_executor_spec.rb +45 -45
- data/test/base/test_outdatedness_checker.rb +1 -1
- data/test/rule_dsl/test_action_provider.rb +3 -3
- metadata +15 -7
- data/spec/nanoc/base/entities/rule_memory_spec.rb +0 -167
| @@ -16,11 +16,13 @@ module Nanoc::Int | |
| 16 16 | 
             
                    end
         | 
| 17 17 | 
             
                  end
         | 
| 18 18 |  | 
| 19 | 
            -
                  Nanoc::Int::ItemRepRouter.new(@reps, @action_provider, @site).run
         | 
| 19 | 
            +
                  action_sequences = Nanoc::Int::ItemRepRouter.new(@reps, @action_provider, @site).run
         | 
| 20 20 |  | 
| 21 21 | 
             
                  @reps.each do |rep|
         | 
| 22 | 
            -
                    rep.snapshot_defs =  | 
| 22 | 
            +
                    rep.snapshot_defs = action_sequences[rep].snapshots_defs
         | 
| 23 23 | 
             
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  action_sequences
         | 
| 24 26 | 
             
                end
         | 
| 25 27 | 
             
              end
         | 
| 26 28 | 
             
            end
         | 
| @@ -24,6 +24,7 @@ module Nanoc::Int | |
| 24 24 | 
             
                end
         | 
| 25 25 |  | 
| 26 26 | 
             
                def run
         | 
| 27 | 
            +
                  action_sequences = {}
         | 
| 27 28 | 
             
                  assigned_paths = {}
         | 
| 28 29 | 
             
                  @reps.each do |rep|
         | 
| 29 30 | 
             
                    # Sigh. We route reps twice, because the first time, the paths might not have converged
         | 
| @@ -31,16 +32,20 @@ module Nanoc::Int | |
| 31 32 | 
             
                    # I can think of. For details, see
         | 
| 32 33 | 
             
                    # https://github.com/nanoc/nanoc/pull/1085#issuecomment-280628426.
         | 
| 33 34 |  | 
| 34 | 
            -
                    @action_provider. | 
| 35 | 
            +
                    @action_provider.action_sequence_for(rep).paths.each do |(snapshot_names, paths)|
         | 
| 35 36 | 
             
                      route_rep(rep, paths, snapshot_names, {})
         | 
| 36 37 | 
             
                    end
         | 
| 37 38 |  | 
| 38 | 
            -
                    @action_provider. | 
| 39 | 
            +
                    mem = @action_provider.action_sequence_for(rep)
         | 
| 40 | 
            +
                    action_sequences[rep] = mem
         | 
| 41 | 
            +
                    mem.paths.each do |(snapshot_names, paths)|
         | 
| 39 42 | 
             
                      route_rep(rep, paths, snapshot_names, assigned_paths)
         | 
| 40 43 | 
             
                    end
         | 
| 41 44 |  | 
| 42 45 | 
             
                    # TODO: verify that paths converge
         | 
| 43 46 | 
             
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  action_sequences
         | 
| 44 49 | 
             
                end
         | 
| 45 50 |  | 
| 46 51 | 
             
                contract Nanoc::Int::ItemRep, C::IterOf[String], C::IterOf[Symbol], C::HashOf[String => Nanoc::Int::ItemRep] => C::Any
         | 
| @@ -81,26 +81,34 @@ module Nanoc::Int | |
| 81 81 |  | 
| 82 82 | 
             
                attr_reader :checksum_store
         | 
| 83 83 | 
             
                attr_reader :dependency_store
         | 
| 84 | 
            -
                attr_reader : | 
| 84 | 
            +
                attr_reader :action_sequence_store
         | 
| 85 85 | 
             
                attr_reader :action_provider
         | 
| 86 86 | 
             
                attr_reader :site
         | 
| 87 87 |  | 
| 88 88 | 
             
                Reasons = Nanoc::Int::OutdatednessReasons
         | 
| 89 89 |  | 
| 90 | 
            +
                C_OBJ = C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Layout]
         | 
| 91 | 
            +
             | 
| 90 92 | 
             
                # FIXME: Replace C::Any with proper types
         | 
| 91 | 
            -
                contract C::KeywordArgs[site: Nanoc::Int::Site, checksum_store: Nanoc::Int::ChecksumStore, dependency_store: Nanoc::Int::DependencyStore,  | 
| 92 | 
            -
                def initialize(site:, checksum_store:, dependency_store:,  | 
| 93 | 
            +
                contract C::KeywordArgs[site: Nanoc::Int::Site, checksum_store: Nanoc::Int::ChecksumStore, dependency_store: Nanoc::Int::DependencyStore, action_sequence_store: Nanoc::Int::ActionSequenceStore, action_provider: C::Any, reps: Nanoc::Int::ItemRepRepo] => C::Any
         | 
| 94 | 
            +
                def initialize(site:, checksum_store:, dependency_store:, action_sequence_store:, action_provider:, reps:)
         | 
| 93 95 | 
             
                  @site = site
         | 
| 94 96 | 
             
                  @checksum_store = checksum_store
         | 
| 95 97 | 
             
                  @dependency_store = dependency_store
         | 
| 96 | 
            -
                  @ | 
| 98 | 
            +
                  @action_sequence_store = action_sequence_store
         | 
| 97 99 | 
             
                  @action_provider = action_provider
         | 
| 98 100 | 
             
                  @reps = reps
         | 
| 99 101 |  | 
| 100 102 | 
             
                  @objects_outdated_due_to_dependencies = {}
         | 
| 101 103 | 
             
                end
         | 
| 102 104 |  | 
| 103 | 
            -
                 | 
| 105 | 
            +
                def action_sequence_for(rep)
         | 
| 106 | 
            +
                  # TODO: Pass in action_sequences instead
         | 
| 107 | 
            +
                  @action_provider.action_sequence_for(rep)
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
                memoize :action_sequence_for
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                contract C_OBJ, C::Maybe[C::HashOf[C_OBJ => Nanoc::Int::ActionSequence]] => C::Bool
         | 
| 104 112 | 
             
                # Checks whether the given object is outdated and therefore needs to be
         | 
| 105 113 | 
             
                # recompiled.
         | 
| 106 114 | 
             
                #
         | 
| @@ -108,7 +116,8 @@ module Nanoc::Int | |
| 108 116 | 
             
                #   whose outdatedness should be checked.
         | 
| 109 117 | 
             
                #
         | 
| 110 118 | 
             
                # @return [Boolean] true if the object is outdated, false otherwise
         | 
| 111 | 
            -
                def outdated?(obj)
         | 
| 119 | 
            +
                def outdated?(obj, _action_sequences = nil)
         | 
| 120 | 
            +
                  # TODO: use action_sequences
         | 
| 112 121 | 
             
                  !outdatedness_reason_for(obj).nil?
         | 
| 113 122 | 
             
                end
         | 
| 114 123 |  | 
| @@ -176,7 +185,21 @@ module Nanoc::Int | |
| 176 185 | 
             
                  return true if dependency.from.nil?
         | 
| 177 186 |  | 
| 178 187 | 
             
                  status = basic.outdatedness_status_for(dependency.from)
         | 
| 179 | 
            -
             | 
| 188 | 
            +
             | 
| 189 | 
            +
                  active = status.props.active & dependency.props.active
         | 
| 190 | 
            +
                  if attributes_unaffected?(status, dependency)
         | 
| 191 | 
            +
                    active.delete(:attributes)
         | 
| 192 | 
            +
                  end
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                  active.any?
         | 
| 195 | 
            +
                end
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                def attributes_unaffected?(status, dependency)
         | 
| 198 | 
            +
                  attr_reason = status.reasons.find do |r|
         | 
| 199 | 
            +
                    r.is_a?(Nanoc::Int::OutdatednessReasons::AttributesModified)
         | 
| 200 | 
            +
                  end
         | 
| 201 | 
            +
             | 
| 202 | 
            +
                  attr_reason && dependency.props.attributes.is_a?(Enumerable) && (dependency.props.attributes & attr_reason.attributes).empty?
         | 
| 180 203 | 
             
                end
         | 
| 181 204 | 
             
              end
         | 
| 182 205 | 
             
            end
         | 
| @@ -12,7 +12,7 @@ module Nanoc::Int | |
| 12 12 | 
             
                end
         | 
| 13 13 |  | 
| 14 14 | 
             
                def apply(_obj, _outdatedness_checker)
         | 
| 15 | 
            -
                  raise NotImplementedError.new('Nanoc::Int::OutdatednessRule subclasses must implement  | 
| 15 | 
            +
                  raise NotImplementedError.new('Nanoc::Int::OutdatednessRule subclasses must implement #apply')
         | 
| 16 16 | 
             
                end
         | 
| 17 17 |  | 
| 18 18 | 
             
                contract C::None => String
         | 
| @@ -20,9 +20,12 @@ module Nanoc::Int | |
| 20 20 | 
             
                  "#{self.class.name}(#{reason})"
         | 
| 21 21 | 
             
                end
         | 
| 22 22 |  | 
| 23 | 
            -
                 | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 23 | 
            +
                def self.affects_props(*names)
         | 
| 24 | 
            +
                  @affected_props = Set.new(names)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def self.affected_props
         | 
| 28 | 
            +
                  @affected_props
         | 
| 26 29 | 
             
                end
         | 
| 27 30 | 
             
              end
         | 
| 28 31 | 
             
            end
         | 
| @@ -1,166 +1,14 @@ | |
| 1 1 | 
             
            module Nanoc::Int
         | 
| 2 2 | 
             
              # @api private
         | 
| 3 3 | 
             
              module OutdatednessRules
         | 
| 4 | 
            -
                class CodeSnippetsModified < OutdatednessRule
         | 
| 5 | 
            -
                  extend Nanoc::Int::Memoization
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                  include Nanoc::Int::ContractsSupport
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                  def reason
         | 
| 10 | 
            -
                    Nanoc::Int::OutdatednessReasons::CodeSnippetsModified
         | 
| 11 | 
            -
                  end
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                  def apply(_obj, outdatedness_checker)
         | 
| 14 | 
            -
                    if any_snippets_modified?(outdatedness_checker)
         | 
| 15 | 
            -
                      Nanoc::Int::OutdatednessReasons::CodeSnippetsModified
         | 
| 16 | 
            -
                    end
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                  private
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                  def any_snippets_modified?(outdatedness_checker)
         | 
| 22 | 
            -
                    outdatedness_checker.site.code_snippets.any? do |cs|
         | 
| 23 | 
            -
                      ch_old = outdatedness_checker.checksum_store[cs]
         | 
| 24 | 
            -
                      ch_new = Nanoc::Int::Checksummer.calc(cs)
         | 
| 25 | 
            -
                      ch_old != ch_new
         | 
| 26 | 
            -
                    end
         | 
| 27 | 
            -
                  end
         | 
| 28 | 
            -
                  memoize :any_snippets_modified?
         | 
| 29 | 
            -
                end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                class ConfigurationModified < OutdatednessRule
         | 
| 32 | 
            -
                  extend Nanoc::Int::Memoization
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                  def reason
         | 
| 35 | 
            -
                    Nanoc::Int::OutdatednessReasons::ConfigurationModified
         | 
| 36 | 
            -
                  end
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                  def apply(_obj, outdatedness_checker)
         | 
| 39 | 
            -
                    if config_modified?(outdatedness_checker)
         | 
| 40 | 
            -
                      Nanoc::Int::OutdatednessReasons::ConfigurationModified
         | 
| 41 | 
            -
                    end
         | 
| 42 | 
            -
                  end
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                  private
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                  def config_modified?(outdatedness_checker)
         | 
| 47 | 
            -
                    obj = outdatedness_checker.site.config
         | 
| 48 | 
            -
                    ch_old = outdatedness_checker.checksum_store[obj]
         | 
| 49 | 
            -
                    ch_new = Nanoc::Int::Checksummer.calc(obj)
         | 
| 50 | 
            -
                    ch_old != ch_new
         | 
| 51 | 
            -
                  end
         | 
| 52 | 
            -
                  memoize :config_modified?
         | 
| 53 | 
            -
                end
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                class NotWritten < OutdatednessRule
         | 
| 56 | 
            -
                  def reason
         | 
| 57 | 
            -
                    Nanoc::Int::OutdatednessReasons::NotWritten
         | 
| 58 | 
            -
                  end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                  def apply(obj, _outdatedness_checker)
         | 
| 61 | 
            -
                    if obj.raw_paths.values.flatten.compact.any? { |fn| !File.file?(fn) }
         | 
| 62 | 
            -
                      Nanoc::Int::OutdatednessReasons::NotWritten
         | 
| 63 | 
            -
                    end
         | 
| 64 | 
            -
                  end
         | 
| 65 | 
            -
                end
         | 
| 66 | 
            -
             | 
| 67 | 
            -
                class ContentModified < OutdatednessRule
         | 
| 68 | 
            -
                  def reason
         | 
| 69 | 
            -
                    Nanoc::Int::OutdatednessReasons::ContentModified
         | 
| 70 | 
            -
                  end
         | 
| 71 | 
            -
             | 
| 72 | 
            -
                  def apply(obj, outdatedness_checker)
         | 
| 73 | 
            -
                    obj = obj.item if obj.is_a?(Nanoc::Int::ItemRep)
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                    ch_old = outdatedness_checker.checksum_store.content_checksum_for(obj)
         | 
| 76 | 
            -
                    ch_new = Nanoc::Int::Checksummer.calc_for_content_of(obj)
         | 
| 77 | 
            -
                    if ch_old != ch_new
         | 
| 78 | 
            -
                      Nanoc::Int::OutdatednessReasons::ContentModified
         | 
| 79 | 
            -
                    end
         | 
| 80 | 
            -
                  end
         | 
| 81 | 
            -
                end
         | 
| 82 | 
            -
             | 
| 83 | 
            -
                class AttributesModified < OutdatednessRule
         | 
| 84 | 
            -
                  extend Nanoc::Int::Memoization
         | 
| 85 | 
            -
             | 
| 86 | 
            -
                  include Nanoc::Int::ContractsSupport
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                  def reason
         | 
| 89 | 
            -
                    Nanoc::Int::OutdatednessReasons::AttributesModified
         | 
| 90 | 
            -
                  end
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                  contract C::Or[Nanoc::Int::ItemRep, Nanoc::Int::Item, Nanoc::Int::Layout], C::Named['Nanoc::Int::OutdatednessChecker'] => C::Maybe[Nanoc::Int::OutdatednessReasons::Generic]
         | 
| 93 | 
            -
                  def apply(obj, outdatedness_checker)
         | 
| 94 | 
            -
                    case obj
         | 
| 95 | 
            -
                    when Nanoc::Int::ItemRep
         | 
| 96 | 
            -
                      apply(obj.item, outdatedness_checker)
         | 
| 97 | 
            -
                    when Nanoc::Int::Item, Nanoc::Int::Layout
         | 
| 98 | 
            -
                      ch_old = outdatedness_checker.checksum_store.attributes_checksum_for(obj)
         | 
| 99 | 
            -
                      ch_new = Nanoc::Int::Checksummer.calc_for_attributes_of(obj)
         | 
| 100 | 
            -
                      if ch_old != ch_new
         | 
| 101 | 
            -
                        Nanoc::Int::OutdatednessReasons::AttributesModified
         | 
| 102 | 
            -
                      end
         | 
| 103 | 
            -
                    else
         | 
| 104 | 
            -
                      raise ArgumentError
         | 
| 105 | 
            -
                    end
         | 
| 106 | 
            -
                  end
         | 
| 107 | 
            -
                  memoize :apply
         | 
| 108 | 
            -
                end
         | 
| 109 | 
            -
             | 
| 110 | 
            -
                class RulesModified < OutdatednessRule
         | 
| 111 | 
            -
                  def reason
         | 
| 112 | 
            -
                    Nanoc::Int::OutdatednessReasons::RulesModified
         | 
| 113 | 
            -
                  end
         | 
| 114 | 
            -
             | 
| 115 | 
            -
                  def apply(obj, outdatedness_checker)
         | 
| 116 | 
            -
                    mem_old = outdatedness_checker.rule_memory_store[obj]
         | 
| 117 | 
            -
                    mem_new = outdatedness_checker.action_provider.memory_for(obj).serialize
         | 
| 118 | 
            -
                    unless mem_old.eql?(mem_new)
         | 
| 119 | 
            -
                      Nanoc::Int::OutdatednessReasons::RulesModified
         | 
| 120 | 
            -
                    end
         | 
| 121 | 
            -
                  end
         | 
| 122 | 
            -
                end
         | 
| 123 | 
            -
             | 
| 124 | 
            -
                class PathsModified < OutdatednessRule
         | 
| 125 | 
            -
                  def reason
         | 
| 126 | 
            -
                    Nanoc::Int::OutdatednessReasons::PathsModified
         | 
| 127 | 
            -
                  end
         | 
| 128 | 
            -
             | 
| 129 | 
            -
                  def apply(obj, outdatedness_checker)
         | 
| 130 | 
            -
                    # FIXME: Prefer to not work on serialised version
         | 
| 131 | 
            -
             | 
| 132 | 
            -
                    mem_old = outdatedness_checker.rule_memory_store[obj]
         | 
| 133 | 
            -
                    mem_new = outdatedness_checker.action_provider.memory_for(obj).serialize
         | 
| 134 | 
            -
                    return true if mem_old.nil?
         | 
| 135 | 
            -
             | 
| 136 | 
            -
                    paths_old = mem_old.select { |pa| pa[0] == :snapshot }
         | 
| 137 | 
            -
                    paths_new = mem_new.select { |pa| pa[0] == :snapshot }
         | 
| 138 | 
            -
             | 
| 139 | 
            -
                    if paths_old != paths_new
         | 
| 140 | 
            -
                      Nanoc::Int::OutdatednessReasons::PathsModified
         | 
| 141 | 
            -
                    end
         | 
| 142 | 
            -
                  end
         | 
| 143 | 
            -
                end
         | 
| 144 | 
            -
             | 
| 145 | 
            -
                class UsesAlwaysOutdatedFilter < OutdatednessRule
         | 
| 146 | 
            -
                  def reason
         | 
| 147 | 
            -
                    Nanoc::Int::OutdatednessReasons::UsesAlwaysOutdatedFilter
         | 
| 148 | 
            -
                  end
         | 
| 149 | 
            -
             | 
| 150 | 
            -
                  def apply(obj, outdatedness_checker)
         | 
| 151 | 
            -
                    mem = outdatedness_checker.action_provider.memory_for(obj)
         | 
| 152 | 
            -
                    if any_always_outdated?(mem)
         | 
| 153 | 
            -
                      Nanoc::Int::OutdatednessReasons::UsesAlwaysOutdatedFilter
         | 
| 154 | 
            -
                    end
         | 
| 155 | 
            -
                  end
         | 
| 156 | 
            -
             | 
| 157 | 
            -
                  def any_always_outdated?(mem)
         | 
| 158 | 
            -
                    mem
         | 
| 159 | 
            -
                      .select { |a| a.is_a?(Nanoc::Int::ProcessingActions::Filter) }
         | 
| 160 | 
            -
                      .map { |a| Nanoc::Filter.named(a.filter_name) }
         | 
| 161 | 
            -
                      .compact
         | 
| 162 | 
            -
                      .any?(&:always_outdated?)
         | 
| 163 | 
            -
                  end
         | 
| 164 | 
            -
                end
         | 
| 165 4 | 
             
              end
         | 
| 166 5 | 
             
            end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            require_relative 'outdatedness_rules/attributes_modified'
         | 
| 8 | 
            +
            require_relative 'outdatedness_rules/code_snippets_modified'
         | 
| 9 | 
            +
            require_relative 'outdatedness_rules/configuration_modified'
         | 
| 10 | 
            +
            require_relative 'outdatedness_rules/content_modified'
         | 
| 11 | 
            +
            require_relative 'outdatedness_rules/not_written'
         | 
| 12 | 
            +
            require_relative 'outdatedness_rules/paths_modified'
         | 
| 13 | 
            +
            require_relative 'outdatedness_rules/rules_modified'
         | 
| 14 | 
            +
            require_relative 'outdatedness_rules/uses_always_outdated_filter'
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            module Nanoc::Int::OutdatednessRules
         | 
| 2 | 
            +
              class AttributesModified < Nanoc::Int::OutdatednessRule
         | 
| 3 | 
            +
                extend Nanoc::Int::Memoization
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                include Nanoc::Int::ContractsSupport
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                affects_props :attributes, :compiled_content
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                contract C::Or[Nanoc::Int::ItemRep, Nanoc::Int::Item, Nanoc::Int::Layout], C::Named['Nanoc::Int::OutdatednessChecker'] => C::Maybe[Nanoc::Int::OutdatednessReasons::Generic]
         | 
| 10 | 
            +
                def apply(obj, outdatedness_checker)
         | 
| 11 | 
            +
                  case obj
         | 
| 12 | 
            +
                  when Nanoc::Int::ItemRep
         | 
| 13 | 
            +
                    apply(obj.item, outdatedness_checker)
         | 
| 14 | 
            +
                  when Nanoc::Int::Item, Nanoc::Int::Layout
         | 
| 15 | 
            +
                    old_checksums = outdatedness_checker.checksum_store.attributes_checksum_for(obj)
         | 
| 16 | 
            +
                    unless old_checksums
         | 
| 17 | 
            +
                      return Nanoc::Int::OutdatednessReasons::AttributesModified.new(true)
         | 
| 18 | 
            +
                    end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    new_checksums = Nanoc::Int::Checksummer.calc_for_each_attribute_of(obj)
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    attributes = Set.new(old_checksums.keys) + Set.new(new_checksums.keys)
         | 
| 23 | 
            +
                    changed_attributes = attributes.reject { |a| old_checksums[a] == new_checksums[a] }
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    if changed_attributes.any?
         | 
| 26 | 
            +
                      Nanoc::Int::OutdatednessReasons::AttributesModified.new(changed_attributes)
         | 
| 27 | 
            +
                    end
         | 
| 28 | 
            +
                  else
         | 
| 29 | 
            +
                    raise ArgumentError
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
                memoize :apply
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            module Nanoc::Int::OutdatednessRules
         | 
| 2 | 
            +
              class CodeSnippetsModified < Nanoc::Int::OutdatednessRule
         | 
| 3 | 
            +
                extend Nanoc::Int::Memoization
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                include Nanoc::Int::ContractsSupport
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                affects_props :raw_content, :attributes, :compiled_content, :path
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def apply(_obj, outdatedness_checker)
         | 
| 10 | 
            +
                  if any_snippets_modified?(outdatedness_checker)
         | 
| 11 | 
            +
                    Nanoc::Int::OutdatednessReasons::CodeSnippetsModified
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                private
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def any_snippets_modified?(outdatedness_checker)
         | 
| 18 | 
            +
                  outdatedness_checker.site.code_snippets.any? do |cs|
         | 
| 19 | 
            +
                    ch_old = outdatedness_checker.checksum_store[cs]
         | 
| 20 | 
            +
                    ch_new = Nanoc::Int::Checksummer.calc(cs)
         | 
| 21 | 
            +
                    ch_old != ch_new
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
                memoize :any_snippets_modified?
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            module Nanoc::Int::OutdatednessRules
         | 
| 2 | 
            +
              class ConfigurationModified < Nanoc::Int::OutdatednessRule
         | 
| 3 | 
            +
                extend Nanoc::Int::Memoization
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                affects_props :raw_content, :attributes, :compiled_content, :path
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def apply(_obj, outdatedness_checker)
         | 
| 8 | 
            +
                  if config_modified?(outdatedness_checker)
         | 
| 9 | 
            +
                    Nanoc::Int::OutdatednessReasons::ConfigurationModified
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                private
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def config_modified?(outdatedness_checker)
         | 
| 16 | 
            +
                  obj = outdatedness_checker.site.config
         | 
| 17 | 
            +
                  ch_old = outdatedness_checker.checksum_store[obj]
         | 
| 18 | 
            +
                  ch_new = Nanoc::Int::Checksummer.calc(obj)
         | 
| 19 | 
            +
                  ch_old != ch_new
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
                memoize :config_modified?
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            module Nanoc::Int::OutdatednessRules
         | 
| 2 | 
            +
              class ContentModified < Nanoc::Int::OutdatednessRule
         | 
| 3 | 
            +
                affects_props :raw_content, :compiled_content
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def apply(obj, outdatedness_checker)
         | 
| 6 | 
            +
                  obj = obj.item if obj.is_a?(Nanoc::Int::ItemRep)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  ch_old = outdatedness_checker.checksum_store.content_checksum_for(obj)
         | 
| 9 | 
            +
                  ch_new = Nanoc::Int::Checksummer.calc_for_content_of(obj)
         | 
| 10 | 
            +
                  if ch_old != ch_new
         | 
| 11 | 
            +
                    Nanoc::Int::OutdatednessReasons::ContentModified
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            module Nanoc::Int::OutdatednessRules
         | 
| 2 | 
            +
              class NotWritten < Nanoc::Int::OutdatednessRule
         | 
| 3 | 
            +
                affects_props :raw_content, :attributes, :compiled_content, :path
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def apply(obj, _outdatedness_checker)
         | 
| 6 | 
            +
                  if obj.raw_paths.values.flatten.compact.any? { |fn| !File.file?(fn) }
         | 
| 7 | 
            +
                    Nanoc::Int::OutdatednessReasons::NotWritten
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            module Nanoc::Int::OutdatednessRules
         | 
| 2 | 
            +
              class PathsModified < Nanoc::Int::OutdatednessRule
         | 
| 3 | 
            +
                affects_props :path
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def apply(obj, outdatedness_checker)
         | 
| 6 | 
            +
                  # FIXME: Prefer to not work on serialised version
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  mem_old = outdatedness_checker.action_sequence_store[obj]
         | 
| 9 | 
            +
                  mem_new = outdatedness_checker.action_sequence_for(obj).serialize
         | 
| 10 | 
            +
                  return true if mem_old.nil?
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  paths_old = mem_old.select { |pa| pa[0] == :snapshot }
         | 
| 13 | 
            +
                  paths_new = mem_new.select { |pa| pa[0] == :snapshot }
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  if paths_old != paths_new
         | 
| 16 | 
            +
                    Nanoc::Int::OutdatednessReasons::PathsModified
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         |