nanoc-core 4.12.8 → 4.12.10
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/lib/nanoc/core/checksum_collection.rb +3 -1
- data/lib/nanoc/core/checksum_store.rb +11 -1
- data/lib/nanoc/core/checksummer.rb +11 -3
- data/lib/nanoc/core/contracts_support.rb +2 -2
- data/lib/nanoc/core/dependency_props.rb +65 -9
- data/lib/nanoc/core/dependency_store.rb +59 -23
- data/lib/nanoc/core/dependency_tracker.rb +3 -2
- data/lib/nanoc/core/document.rb +5 -1
- data/lib/nanoc/core/feature.rb +2 -0
- data/lib/nanoc/core/identifiable_collection_view.rb +28 -0
- data/lib/nanoc/core/item.rb +1 -1
- data/lib/nanoc/core/layout.rb +1 -1
- data/lib/nanoc/core/mutable_document_view_mixin.rb +16 -7
- data/lib/nanoc/core/outdatedness_checker.rb +99 -31
- data/lib/nanoc/core/outdatedness_reasons.rb +9 -19
- data/lib/nanoc/core/outdatedness_rule.rb +31 -3
- data/lib/nanoc/core/outdatedness_rules/item_added.rb +18 -0
- data/lib/nanoc/core/outdatedness_rules/layout_added.rb +18 -0
- data/lib/nanoc/core/outdatedness_status.rb +10 -1
- data/lib/nanoc/core/version.rb +1 -1
- metadata +5 -5
- data/lib/nanoc/core/outdatedness_rules/item_collection_extended.rb +0 -20
- data/lib/nanoc/core/outdatedness_rules/layout_collection_extended.rb +0 -20
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 3365fa09f4ff20a16df20f260562fca8c64342098ba70b4547dc38580204ea2e
         | 
| 4 | 
            +
              data.tar.gz: 132a480e5593d19bb6c1802f6f740e3ed1d081eb88f0178fbde311d9a4e52cc0
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 5c0190dbbad1225882d5b76891e80f45cf5e02238c6f6418071d9e8968e82cdd0263099eb5a71963b179238fb57a86f53ef7f7677592299c61cc6197be6b5dd9
         | 
| 7 | 
            +
              data.tar.gz: 13424fbb1cc81c95e471a8ba99f172d24b6f33b1e9220a50773ed32554f5577622db7d63825734b04254e33c624b2d382b16ced1628952f5cee7e6429d96e57a
         | 
| @@ -9,6 +9,8 @@ module Nanoc | |
| 9 9 |  | 
| 10 10 | 
             
                  def initialize(checksums)
         | 
| 11 11 | 
             
                    @checksums = checksums
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    @_attribute_checksums = {}
         | 
| 12 14 | 
             
                  end
         | 
| 13 15 |  | 
| 14 16 | 
             
                  contract c_obj => C::Maybe[String]
         | 
| @@ -23,7 +25,7 @@ module Nanoc | |
| 23 25 |  | 
| 24 26 | 
             
                  contract c_obj => C::Maybe[C::HashOf[Symbol, String]]
         | 
| 25 27 | 
             
                  def attributes_checksum_for(obj)
         | 
| 26 | 
            -
                    @checksums[[obj.reference, :each_attribute]]
         | 
| 28 | 
            +
                    @_attribute_checksums[obj] ||= @checksums[[obj.reference, :each_attribute]]
         | 
| 27 29 | 
             
                  end
         | 
| 28 30 |  | 
| 29 31 | 
             
                  def to_h
         | 
| @@ -21,6 +21,8 @@ module Nanoc | |
| 21 21 | 
             
                    @objects = objects
         | 
| 22 22 |  | 
| 23 23 | 
             
                    @checksums = {}
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    invalidate_memoization
         | 
| 24 26 | 
             
                  end
         | 
| 25 27 |  | 
| 26 28 | 
             
                  contract c_obj => C::Maybe[String]
         | 
| @@ -50,7 +52,7 @@ module Nanoc | |
| 50 52 |  | 
| 51 53 | 
             
                  contract c_obj => C::Maybe[C::HashOf[Symbol, String]]
         | 
| 52 54 | 
             
                  def attributes_checksum_for(obj)
         | 
| 53 | 
            -
                    @checksums[[obj.reference, :each_attribute]]
         | 
| 55 | 
            +
                    @_attribute_checksums[obj] ||= @checksums[[obj.reference, :each_attribute]]
         | 
| 54 56 | 
             
                  end
         | 
| 55 57 |  | 
| 56 58 | 
             
                  protected
         | 
| @@ -60,6 +62,8 @@ module Nanoc | |
| 60 62 | 
             
                  end
         | 
| 61 63 |  | 
| 62 64 | 
             
                  def data=(new_data)
         | 
| 65 | 
            +
                    invalidate_memoization
         | 
| 66 | 
            +
             | 
| 63 67 | 
             
                    references = Set.new(@objects.map(&:reference))
         | 
| 64 68 |  | 
| 65 69 | 
             
                    @checksums = {}
         | 
| @@ -69,6 +73,12 @@ module Nanoc | |
| 69 73 | 
             
                      end
         | 
| 70 74 | 
             
                    end
         | 
| 71 75 | 
             
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  private
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                  def invalidate_memoization
         | 
| 80 | 
            +
                    @_attribute_checksums = {}
         | 
| 81 | 
            +
                  end
         | 
| 72 82 | 
             
                end
         | 
| 73 83 | 
             
              end
         | 
| 74 84 | 
             
            end
         | 
| @@ -81,7 +81,8 @@ module Nanoc | |
| 81 81 | 
             
                      # NOTE: Other behaviors are registered elsewhere
         | 
| 82 82 | 
             
                      # (search for `define_behavior`).
         | 
| 83 83 |  | 
| 84 | 
            -
                      define_behavior(Array,  | 
| 84 | 
            +
                      define_behavior(Array, CollectionUpdateBehavior)
         | 
| 85 | 
            +
                      define_behavior(Set, SetUpdateBehavior)
         | 
| 85 86 | 
             
                      define_behavior(FalseClass, NoUpdateBehavior)
         | 
| 86 87 | 
             
                      define_behavior(Hash, HashUpdateBehavior)
         | 
| 87 88 | 
             
                      define_behavior(NilClass, NoUpdateBehavior)
         | 
| @@ -96,7 +97,7 @@ module Nanoc | |
| 96 97 | 
             
                      define_behavior(Nanoc::Core::Configuration, HashUpdateBehavior)
         | 
| 97 98 | 
             
                      define_behavior(Nanoc::Core::Context, ContextUpdateBehavior)
         | 
| 98 99 | 
             
                      define_behavior(Nanoc::Core::CodeSnippet, DataUpdateBehavior)
         | 
| 99 | 
            -
                      define_behavior(Nanoc::Core::IdentifiableCollection,  | 
| 100 | 
            +
                      define_behavior(Nanoc::Core::IdentifiableCollection, CollectionUpdateBehavior)
         | 
| 100 101 | 
             
                      define_behavior(Nanoc::Core::Identifier, ToSUpdateBehavior)
         | 
| 101 102 | 
             
                      define_behavior(Nanoc::Core::Item, DocumentUpdateBehavior)
         | 
| 102 103 | 
             
                      define_behavior(Nanoc::Core::ItemRep, ItemRepUpdateBehavior)
         | 
| @@ -194,7 +195,7 @@ module Nanoc | |
| 194 195 | 
             
                    end
         | 
| 195 196 | 
             
                  end
         | 
| 196 197 |  | 
| 197 | 
            -
                  class  | 
| 198 | 
            +
                  class CollectionUpdateBehavior < UpdateBehavior
         | 
| 198 199 | 
             
                    def self.update(obj, digest)
         | 
| 199 200 | 
             
                      obj.each do |el|
         | 
| 200 201 | 
             
                        yield(el)
         | 
| @@ -203,6 +204,13 @@ module Nanoc | |
| 203 204 | 
             
                    end
         | 
| 204 205 | 
             
                  end
         | 
| 205 206 |  | 
| 207 | 
            +
                  class SetUpdateBehavior < CollectionUpdateBehavior
         | 
| 208 | 
            +
                    def self.update(obj, digest)
         | 
| 209 | 
            +
                      # Similar to CollectionUpdateBehavior, but sorted for consistency.
         | 
| 210 | 
            +
                      super(obj.sort { |a, b| (a <=> b) || 0 }, digest)
         | 
| 211 | 
            +
                    end
         | 
| 212 | 
            +
                  end
         | 
| 213 | 
            +
             | 
| 206 214 | 
             
                  class HashUpdateBehavior < UpdateBehavior
         | 
| 207 215 | 
             
                    def self.update(obj, digest)
         | 
| 208 216 | 
             
                      obj.each do |key, value|
         | 
| @@ -25,6 +25,7 @@ module Nanoc | |
| 25 25 | 
             
                    Maybe       = Ignorer.instance
         | 
| 26 26 | 
             
                    None        = Ignorer.instance
         | 
| 27 27 | 
             
                    ArrayOf     = Ignorer.instance
         | 
| 28 | 
            +
                    SetOf       = Ignorer.instance
         | 
| 28 29 | 
             
                    Or          = Ignorer.instance
         | 
| 29 30 | 
             
                    Func        = Ignorer.instance
         | 
| 30 31 | 
             
                    RespondTo   = Ignorer.instance
         | 
| @@ -96,8 +97,7 @@ module Nanoc | |
| 96 97 | 
             
                        false
         | 
| 97 98 | 
             
                      end
         | 
| 98 99 |  | 
| 99 | 
            -
                     | 
| 100 | 
            -
                    @_contracts_support__should_enable = contracts_loadable && !RUBY_VERSION.start_with?('3') && !ENV.key?('DISABLE_CONTRACTS')
         | 
| 100 | 
            +
                    @_contracts_support__should_enable = contracts_loadable && !ENV.key?('DISABLE_CONTRACTS')
         | 
| 101 101 |  | 
| 102 102 | 
             
                    if @_contracts_support__should_enable
         | 
| 103 103 | 
             
                      # FIXME: ugly
         | 
| @@ -10,9 +10,39 @@ module Nanoc | |
| 10 10 | 
             
                  attr_reader :raw_content
         | 
| 11 11 |  | 
| 12 12 | 
             
                  # TODO: Split raw_content for documents and collections
         | 
| 13 | 
            -
                  C_RAW_CONTENT = | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 13 | 
            +
                  C_RAW_CONTENT =
         | 
| 14 | 
            +
                    C::Or[
         | 
| 15 | 
            +
                      C::SetOf[C::Or[String, Regexp]],
         | 
| 16 | 
            +
                      C::ArrayOf[C::Or[String, Regexp]],
         | 
| 17 | 
            +
                      C::Bool
         | 
| 18 | 
            +
                    ]
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  C_ATTR =
         | 
| 21 | 
            +
                    C::Or[
         | 
| 22 | 
            +
                      C::SetOf[
         | 
| 23 | 
            +
                        C::Or[
         | 
| 24 | 
            +
                          Symbol,          # any value
         | 
| 25 | 
            +
                          [Symbol, C::Any] # pair (specific value)
         | 
| 26 | 
            +
                        ],
         | 
| 27 | 
            +
                      ],
         | 
| 28 | 
            +
                      C::ArrayOf[
         | 
| 29 | 
            +
                        C::Or[
         | 
| 30 | 
            +
                          Symbol,          # any value
         | 
| 31 | 
            +
                          [Symbol, C::Any] # pair (specific value)
         | 
| 32 | 
            +
                        ],
         | 
| 33 | 
            +
                      ],
         | 
| 34 | 
            +
                      C::Bool
         | 
| 35 | 
            +
                    ]
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  C_ARGS =
         | 
| 38 | 
            +
                    C::KeywordArgs[
         | 
| 39 | 
            +
                      raw_content: C::Optional[C_RAW_CONTENT],
         | 
| 40 | 
            +
                      attributes: C::Optional[C_ATTR],
         | 
| 41 | 
            +
                      compiled_content: C::Optional[C::Bool],
         | 
| 42 | 
            +
                      path: C::Optional[C::Bool]
         | 
| 43 | 
            +
                    ]
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  contract C_ARGS => C::Any
         | 
| 16 46 | 
             
                  def initialize(raw_content: false, attributes: false, compiled_content: false, path: false)
         | 
| 17 47 | 
             
                    @compiled_content = compiled_content
         | 
| 18 48 | 
             
                    @path = path
         | 
| @@ -21,7 +51,7 @@ module Nanoc | |
| 21 51 | 
             
                      case attributes
         | 
| 22 52 | 
             
                      when Set
         | 
| 23 53 | 
             
                        attributes
         | 
| 24 | 
            -
                      when  | 
| 54 | 
            +
                      when Array
         | 
| 25 55 | 
             
                        Set.new(attributes)
         | 
| 26 56 | 
             
                      else
         | 
| 27 57 | 
             
                        attributes
         | 
| @@ -31,7 +61,7 @@ module Nanoc | |
| 31 61 | 
             
                      case raw_content
         | 
| 32 62 | 
             
                      when Set
         | 
| 33 63 | 
             
                        raw_content
         | 
| 34 | 
            -
                      when  | 
| 64 | 
            +
                      when Array
         | 
| 35 65 | 
             
                        Set.new(raw_content)
         | 
| 36 66 | 
             
                      else
         | 
| 37 67 | 
             
                        raw_content
         | 
| @@ -46,6 +76,23 @@ module Nanoc | |
| 46 76 | 
             
                      s << (attributes? ? 'a' : '_')
         | 
| 47 77 | 
             
                      s << (compiled_content? ? 'c' : '_')
         | 
| 48 78 | 
             
                      s << (path? ? 'p' : '_')
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                      if @raw_content.is_a?(Set)
         | 
| 81 | 
            +
                        @raw_content.each do |elem|
         | 
| 82 | 
            +
                          s << '; raw_content('
         | 
| 83 | 
            +
                          s << elem.inspect
         | 
| 84 | 
            +
                          s << ')'
         | 
| 85 | 
            +
                        end
         | 
| 86 | 
            +
                      end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                      if @attributes.is_a?(Set)
         | 
| 89 | 
            +
                        @attributes.each do |elem|
         | 
| 90 | 
            +
                          s << '; attr('
         | 
| 91 | 
            +
                          s << elem.inspect
         | 
| 92 | 
            +
                          s << ')'
         | 
| 93 | 
            +
                        end
         | 
| 94 | 
            +
                      end
         | 
| 95 | 
            +
             | 
| 49 96 | 
             
                      s << ')'
         | 
| 50 97 | 
             
                    end
         | 
| 51 98 | 
             
                  end
         | 
| @@ -63,8 +110,8 @@ module Nanoc | |
| 63 110 | 
             
                  contract C::None => C::Bool
         | 
| 64 111 | 
             
                  def raw_content?
         | 
| 65 112 | 
             
                    case @raw_content
         | 
| 66 | 
            -
                    when  | 
| 67 | 
            -
                       | 
| 113 | 
            +
                    when Set
         | 
| 114 | 
            +
                      !@raw_content.empty?
         | 
| 68 115 | 
             
                    else
         | 
| 69 116 | 
             
                      @raw_content
         | 
| 70 117 | 
             
                    end
         | 
| @@ -73,8 +120,8 @@ module Nanoc | |
| 73 120 | 
             
                  contract C::None => C::Bool
         | 
| 74 121 | 
             
                  def attributes?
         | 
| 75 122 | 
             
                    case @attributes
         | 
| 76 | 
            -
                    when  | 
| 77 | 
            -
                       | 
| 123 | 
            +
                    when Set
         | 
| 124 | 
            +
                      !@attributes.empty?
         | 
| 78 125 | 
             
                    else
         | 
| 79 126 | 
             
                      @attributes
         | 
| 80 127 | 
             
                    end
         | 
| @@ -136,6 +183,15 @@ module Nanoc | |
| 136 183 | 
             
                    end
         | 
| 137 184 | 
             
                  end
         | 
| 138 185 |  | 
| 186 | 
            +
                  def attribute_keys
         | 
| 187 | 
            +
                    case @attributes
         | 
| 188 | 
            +
                    when Enumerable
         | 
| 189 | 
            +
                      @attributes.map { |a| a.is_a?(Array) ? a.first : a }
         | 
| 190 | 
            +
                    else
         | 
| 191 | 
            +
                      []
         | 
| 192 | 
            +
                    end
         | 
| 193 | 
            +
                  end
         | 
| 194 | 
            +
             | 
| 139 195 | 
             
                  contract C::None => Hash
         | 
| 140 196 | 
             
                  def to_h
         | 
| 141 197 | 
             
                    {
         | 
| @@ -6,11 +6,36 @@ module Nanoc | |
| 6 6 | 
             
                class DependencyStore < ::Nanoc::Core::Store
         | 
| 7 7 | 
             
                  include Nanoc::Core::ContractsSupport
         | 
| 8 8 |  | 
| 9 | 
            -
                   | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 9 | 
            +
                  C_RAW_CONTENT =
         | 
| 10 | 
            +
                    C::Or[
         | 
| 11 | 
            +
                      C::ArrayOf[C::Or[String, Regexp]],
         | 
| 12 | 
            +
                      C::Bool
         | 
| 13 | 
            +
                    ]
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  C_ATTR =
         | 
| 16 | 
            +
                    C::Or[
         | 
| 17 | 
            +
                      C::ArrayOf[Symbol],
         | 
| 18 | 
            +
                      C::HashOf[Symbol => C::Any],
         | 
| 19 | 
            +
                      C::Bool
         | 
| 20 | 
            +
                    ]
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  C_KEYWORD_PROPS =
         | 
| 23 | 
            +
                    C::KeywordArgs[
         | 
| 24 | 
            +
                      raw_content: C::Optional[C_RAW_CONTENT],
         | 
| 25 | 
            +
                      attributes: C::Optional[C_ATTR],
         | 
| 26 | 
            +
                      compiled_content: C::Optional[C::Bool],
         | 
| 27 | 
            +
                      path: C::Optional[C::Bool]
         | 
| 28 | 
            +
                    ]
         | 
| 29 | 
            +
             | 
| 12 30 | 
             
                  C_OBJ_SRC = Nanoc::Core::Item
         | 
| 13 | 
            -
             | 
| 31 | 
            +
             | 
| 32 | 
            +
                  C_OBJ_DST =
         | 
| 33 | 
            +
                    C::Or[
         | 
| 34 | 
            +
                      Nanoc::Core::Item,
         | 
| 35 | 
            +
                      Nanoc::Core::Layout,
         | 
| 36 | 
            +
                      Nanoc::Core::Configuration,
         | 
| 37 | 
            +
                      Nanoc::Core::IdentifiableCollection
         | 
| 38 | 
            +
                    ]
         | 
| 14 39 |  | 
| 15 40 | 
             
                  attr_reader :items
         | 
| 16 41 | 
             
                  attr_reader :layouts
         | 
| @@ -46,12 +71,7 @@ module Nanoc | |
| 46 71 | 
             
                      Nanoc::Core::Dependency.new(
         | 
| 47 72 | 
             
                        other_object,
         | 
| 48 73 | 
             
                        object,
         | 
| 49 | 
            -
                         | 
| 50 | 
            -
                          raw_content: props.fetch(:raw_content, false),
         | 
| 51 | 
            -
                          attributes: props.fetch(:attributes, false),
         | 
| 52 | 
            -
                          compiled_content: props.fetch(:compiled_content, false),
         | 
| 53 | 
            -
                          path: props.fetch(:path, false),
         | 
| 54 | 
            -
                        ),
         | 
| 74 | 
            +
                        props,
         | 
| 55 75 | 
             
                      )
         | 
| 56 76 | 
             
                    end
         | 
| 57 77 | 
             
                  end
         | 
| @@ -116,11 +136,16 @@ module Nanoc | |
| 116 136 | 
             
                    src_ref = obj2ref(src)
         | 
| 117 137 | 
             
                    dst_ref = obj2ref(dst)
         | 
| 118 138 |  | 
| 119 | 
            -
                     | 
| 139 | 
            +
                    # Convert attributes into key-value pairs, if necessary
         | 
| 140 | 
            +
                    if attributes.is_a?(Hash)
         | 
| 141 | 
            +
                      attributes = attributes.to_a
         | 
| 142 | 
            +
                    end
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                    existing_props = @graph.props_for(dst_ref, src_ref)
         | 
| 120 145 | 
             
                    new_props = Nanoc::Core::DependencyProps.new(raw_content: raw_content, attributes: attributes, compiled_content: compiled_content, path: path)
         | 
| 121 | 
            -
                    props = existing_props.merge(new_props)
         | 
| 146 | 
            +
                    props = existing_props ? existing_props.merge(new_props) : new_props
         | 
| 122 147 |  | 
| 123 | 
            -
                    @graph.add_edge(dst_ref, src_ref, props: props | 
| 148 | 
            +
                    @graph.add_edge(dst_ref, src_ref, props: props)
         | 
| 124 149 | 
             
                  end
         | 
| 125 150 |  | 
| 126 151 | 
             
                  def add_vertex_for(obj)
         | 
| @@ -163,18 +188,26 @@ module Nanoc | |
| 163 188 | 
             
                  end
         | 
| 164 189 |  | 
| 165 190 | 
             
                  def props_for(from, to)
         | 
| 166 | 
            -
                    props = @graph.props_for(obj2ref(from), obj2ref(to)) | 
| 167 | 
            -
             | 
| 168 | 
            -
             | 
| 169 | 
            -
             | 
| 170 | 
            -
                     | 
| 171 | 
            -
             | 
| 172 | 
            -
                     | 
| 191 | 
            +
                    props = @graph.props_for(obj2ref(from), obj2ref(to))
         | 
| 192 | 
            +
                    return props if props
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                    # This is for backwards compatibility, in case there are no dependency
         | 
| 195 | 
            +
                    # props available yet. Pretend everything is set to `true`; it’ll be
         | 
| 196 | 
            +
                    # recompiled and correct props will be available in the next run.
         | 
| 197 | 
            +
                    #
         | 
| 198 | 
            +
                    # NOTE: This isn’t covered by tests, yet. (Not trivial to test because
         | 
| 199 | 
            +
                    # it’s not a condition that can arise in the current Nanoc version.)
         | 
| 200 | 
            +
                    Nanoc::Core::DependencyProps.new(
         | 
| 201 | 
            +
                      raw_content: true,
         | 
| 202 | 
            +
                      attributes: true,
         | 
| 203 | 
            +
                      compiled_content: true,
         | 
| 204 | 
            +
                      path: true,
         | 
| 205 | 
            +
                    )
         | 
| 173 206 | 
             
                  end
         | 
| 174 207 |  | 
| 175 208 | 
             
                  def data
         | 
| 176 209 | 
             
                    {
         | 
| 177 | 
            -
                      edges: @graph.edges,
         | 
| 210 | 
            +
                      edges: @graph.edges.map { |arr| [arr[0], arr[1], arr[2].to_h] },
         | 
| 178 211 | 
             
                      vertices: @graph.vertices,
         | 
| 179 212 | 
             
                    }
         | 
| 180 213 | 
             
                  end
         | 
| @@ -193,8 +226,11 @@ module Nanoc | |
| 193 226 | 
             
                    # Load edges
         | 
| 194 227 | 
             
                    new_data[:edges].each do |edge|
         | 
| 195 228 | 
             
                      from_index, to_index, props = *edge
         | 
| 196 | 
            -
             | 
| 197 | 
            -
                       | 
| 229 | 
            +
             | 
| 230 | 
            +
                      from  = from_index && previous_refs[from_index]
         | 
| 231 | 
            +
                      to    = to_index && previous_refs[to_index]
         | 
| 232 | 
            +
                      props = Nanoc::Core::DependencyProps.new(**props)
         | 
| 233 | 
            +
             | 
| 198 234 | 
             
                      @graph.add_edge(from, to, props: props)
         | 
| 199 235 | 
             
                    end
         | 
| 200 236 |  | 
| @@ -16,13 +16,14 @@ module Nanoc | |
| 16 16 |  | 
| 17 17 | 
             
                  C_RAW_CONTENT =
         | 
| 18 18 | 
             
                    C::Or[
         | 
| 19 | 
            -
                      C:: | 
| 19 | 
            +
                      C::ArrayOf[C::Or[String, Regexp]],
         | 
| 20 20 | 
             
                      C::Bool
         | 
| 21 21 | 
             
                    ]
         | 
| 22 22 |  | 
| 23 23 | 
             
                  C_ATTR =
         | 
| 24 24 | 
             
                    C::Or[
         | 
| 25 | 
            -
                      C:: | 
| 25 | 
            +
                      C::ArrayOf[Symbol],
         | 
| 26 | 
            +
                      C::HashOf[Symbol => C::Any],
         | 
| 26 27 | 
             
                      C::Bool
         | 
| 27 28 | 
             
                    ]
         | 
| 28 29 |  | 
    
        data/lib/nanoc/core/document.rb
    CHANGED
    
    | @@ -49,6 +49,10 @@ module Nanoc | |
| 49 49 | 
             
                    @checksum_data = checksum_data
         | 
| 50 50 | 
             
                    @content_checksum_data = content_checksum_data
         | 
| 51 51 | 
             
                    @attributes_checksum_data = attributes_checksum_data
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    # Precalculate for performance
         | 
| 54 | 
            +
                    @hash = [self.class, identifier].hash
         | 
| 55 | 
            +
                    reference
         | 
| 52 56 | 
             
                  end
         | 
| 53 57 |  | 
| 54 58 | 
             
                  # @return [Hash]
         | 
| @@ -107,7 +111,7 @@ module Nanoc | |
| 107 111 |  | 
| 108 112 | 
             
                  contract C::None => C::Num
         | 
| 109 113 | 
             
                  def hash
         | 
| 110 | 
            -
                     | 
| 114 | 
            +
                    @hash
         | 
| 111 115 | 
             
                  end
         | 
| 112 116 |  | 
| 113 117 | 
             
                  contract C::Any => C::Bool
         | 
    
        data/lib/nanoc/core/feature.rb
    CHANGED
    
    
| @@ -69,6 +69,34 @@ module Nanoc | |
| 69 69 | 
             
                    @objects.find_all(arg).map { |i| view_class.new(i, @context) }
         | 
| 70 70 | 
             
                  end
         | 
| 71 71 |  | 
| 72 | 
            +
                  # Finds all objects that have the given attribute key/value pair.
         | 
| 73 | 
            +
                  #
         | 
| 74 | 
            +
                  # @example
         | 
| 75 | 
            +
                  #
         | 
| 76 | 
            +
                  #     @items.where(kind: 'article')
         | 
| 77 | 
            +
                  #     @items.where(kind: 'article', year: 2020)
         | 
| 78 | 
            +
                  #
         | 
| 79 | 
            +
                  # @return [Enumerable]
         | 
| 80 | 
            +
                  def where(**hash)
         | 
| 81 | 
            +
                    unless Nanoc::Core::Feature.enabled?(Nanoc::Core::Feature::WHERE)
         | 
| 82 | 
            +
                      raise(
         | 
| 83 | 
            +
                        Nanoc::Core::TrivialError,
         | 
| 84 | 
            +
                        '#where is experimental, and not yet available unless the corresponding feature flag is turned on. Set the `NANOC_FEATURES` environment variable to `where` to enable its usage. (Alternatively, set the environment variable to `all` to turn on all feature flags.)',
         | 
| 85 | 
            +
                      )
         | 
| 86 | 
            +
                    end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                    @context.dependency_tracker.bounce(_unwrap, attributes: hash)
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                    # IDEA: Nanoc could remember (from the previous compilation) how many
         | 
| 91 | 
            +
                    # times #where is called with a given attribute key, and memoize the
         | 
| 92 | 
            +
                    # key-to-identifiers list.
         | 
| 93 | 
            +
                    found_objects = @objects.select do |i|
         | 
| 94 | 
            +
                      hash.all? { |k, v| i.attributes[k] == v }
         | 
| 95 | 
            +
                    end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                    found_objects.map { |i| view_class.new(i, @context) }
         | 
| 98 | 
            +
                  end
         | 
| 99 | 
            +
             | 
| 72 100 | 
             
                  # @overload [](string)
         | 
| 73 101 | 
             
                  #
         | 
| 74 102 | 
             
                  #   Finds the object whose identifier matches the given string.
         | 
    
        data/lib/nanoc/core/item.rb
    CHANGED
    
    
    
        data/lib/nanoc/core/layout.rb
    CHANGED
    
    
| @@ -26,13 +26,7 @@ module Nanoc | |
| 26 26 | 
             
                  #
         | 
| 27 27 | 
             
                  # @see Hash#[]=
         | 
| 28 28 | 
             
                  def []=(key, value)
         | 
| 29 | 
            -
                     | 
| 30 | 
            -
                      Nanoc::Core::Item,
         | 
| 31 | 
            -
                      Nanoc::Core::Layout,
         | 
| 32 | 
            -
                      Nanoc::Core::CompilationItemView,
         | 
| 33 | 
            -
                      Nanoc::Core::LayoutView,
         | 
| 34 | 
            -
                    ])
         | 
| 35 | 
            -
                    if disallowed_value_classes.include?(value.class)
         | 
| 29 | 
            +
                    if disallowed_value_class?(value.class)
         | 
| 36 30 | 
             
                      raise DisallowedAttributeValueError.new(value)
         | 
| 37 31 | 
             
                    end
         | 
| 38 32 |  | 
| @@ -55,6 +49,21 @@ module Nanoc | |
| 55 49 | 
             
                    hash.each { |k, v| _unwrap.set_attribute(k, v) }
         | 
| 56 50 | 
             
                    self
         | 
| 57 51 | 
             
                  end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  private
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  def disallowed_value_class?(klass)
         | 
| 56 | 
            +
                    # NOTE: We’re explicitly disabling Style/MultipleComparison, because
         | 
| 57 | 
            +
                    # the suggested alternative (Array#include?) carries a measurable
         | 
| 58 | 
            +
                    # performance penatly.
         | 
| 59 | 
            +
                    #
         | 
| 60 | 
            +
                    # rubocop:disable Style/MultipleComparison
         | 
| 61 | 
            +
                    klass == Nanoc::Core::Item ||
         | 
| 62 | 
            +
                      klass == Nanoc::Core::Layout ||
         | 
| 63 | 
            +
                      klass == Nanoc::Core::CompilationItemView ||
         | 
| 64 | 
            +
                      klass == Nanoc::Core::LayoutView
         | 
| 65 | 
            +
                    # rubocop:enable Style/MultipleComparison
         | 
| 66 | 
            +
                  end
         | 
| 58 67 | 
             
                end
         | 
| 59 68 | 
             
              end
         | 
| 60 69 | 
             
            end
         | 
| @@ -13,6 +13,7 @@ module Nanoc | |
| 13 13 |  | 
| 14 14 | 
             
                    RULES_FOR_ITEM_REP =
         | 
| 15 15 | 
             
                      [
         | 
| 16 | 
            +
                        Rules::ItemAdded,
         | 
| 16 17 | 
             
                        Rules::RulesModified,
         | 
| 17 18 | 
             
                        Rules::ContentModified,
         | 
| 18 19 | 
             
                        Rules::AttributesModified,
         | 
| @@ -23,6 +24,7 @@ module Nanoc | |
| 23 24 |  | 
| 24 25 | 
             
                    RULES_FOR_LAYOUT =
         | 
| 25 26 | 
             
                      [
         | 
| 27 | 
            +
                        Rules::LayoutAdded,
         | 
| 26 28 | 
             
                        Rules::RulesModified,
         | 
| 27 29 | 
             
                        Rules::ContentModified,
         | 
| 28 30 | 
             
                        Rules::AttributesModified,
         | 
| @@ -34,16 +36,6 @@ module Nanoc | |
| 34 36 | 
             
                        Rules::AttributesModified,
         | 
| 35 37 | 
             
                      ].freeze
         | 
| 36 38 |  | 
| 37 | 
            -
                    RULES_FOR_ITEM_COLLECTION =
         | 
| 38 | 
            -
                      [
         | 
| 39 | 
            -
                        Rules::ItemCollectionExtended,
         | 
| 40 | 
            -
                      ].freeze
         | 
| 41 | 
            -
             | 
| 42 | 
            -
                    RULES_FOR_LAYOUT_COLLECTION =
         | 
| 43 | 
            -
                      [
         | 
| 44 | 
            -
                        Rules::LayoutCollectionExtended,
         | 
| 45 | 
            -
                      ].freeze
         | 
| 46 | 
            -
             | 
| 47 39 | 
             
                    C_OBJ_MAYBE_REP = C::Or[Nanoc::Core::Item, Nanoc::Core::ItemRep, Nanoc::Core::Configuration, Nanoc::Core::Layout, Nanoc::Core::ItemCollection, Nanoc::Core::LayoutCollection]
         | 
| 48 40 |  | 
| 49 41 | 
             
                    contract C::KeywordArgs[outdatedness_checker: OutdatednessChecker, reps: Nanoc::Core::ItemRepRepo] => C::Any
         | 
| @@ -67,10 +59,10 @@ module Nanoc | |
| 67 59 | 
             
                          apply_rules(RULES_FOR_LAYOUT, obj)
         | 
| 68 60 | 
             
                        when Nanoc::Core::Configuration
         | 
| 69 61 | 
             
                          apply_rules(RULES_FOR_CONFIG, obj)
         | 
| 70 | 
            -
                        when Nanoc::Core::ItemCollection
         | 
| 71 | 
            -
                           | 
| 72 | 
            -
             | 
| 73 | 
            -
                          apply_rules( | 
| 62 | 
            +
                        when Nanoc::Core::ItemCollection, Nanoc::Core::LayoutCollection
         | 
| 63 | 
            +
                          # Collections are never outdated. Objects inside them might be,
         | 
| 64 | 
            +
                          # however.
         | 
| 65 | 
            +
                          apply_rules([], obj)
         | 
| 74 66 | 
             
                        else
         | 
| 75 67 | 
             
                          raise Nanoc::Core::Errors::InternalInconsistency, "do not know how to check outdatedness of #{obj.inspect}"
         | 
| 76 68 | 
             
                        end
         | 
| @@ -190,31 +182,107 @@ module Nanoc | |
| 190 182 |  | 
| 191 183 | 
             
                  contract Nanoc::Core::Dependency => C::Bool
         | 
| 192 184 | 
             
                  def dependency_causes_outdatedness?(dependency)
         | 
| 193 | 
            -
                     | 
| 194 | 
            -
             | 
| 195 | 
            -
             | 
| 185 | 
            +
                    case dependency.from
         | 
| 186 | 
            +
                    when nil
         | 
| 187 | 
            +
                      true
         | 
| 188 | 
            +
                    when Nanoc::Core::ItemCollection, Nanoc::Core::LayoutCollection
         | 
| 189 | 
            +
                      all_objects = dependency.from
         | 
| 190 | 
            +
             | 
| 191 | 
            +
                      raw_content_prop_causes_outdatedness?(all_objects, dependency.props.raw_content) ||
         | 
| 192 | 
            +
                        attributes_prop_causes_outdatedness?(all_objects, dependency.props.attributes)
         | 
| 193 | 
            +
                    else
         | 
| 194 | 
            +
                      status = basic.outdatedness_status_for(dependency.from)
         | 
| 196 195 |  | 
| 197 | 
            -
             | 
| 198 | 
            -
             | 
| 199 | 
            -
                    active.delete(:raw_content) if raw_content_unaffected?(status, dependency)
         | 
| 196 | 
            +
                      active = status.props.active & dependency.props.active
         | 
| 197 | 
            +
                      active.delete(:attributes) if attributes_unaffected?(status, dependency)
         | 
| 200 198 |  | 
| 201 | 
            -
             | 
| 199 | 
            +
                      !active.empty?
         | 
| 200 | 
            +
                    end
         | 
| 202 201 | 
             
                  end
         | 
| 203 202 |  | 
| 204 203 | 
             
                  def attributes_unaffected?(status, dependency)
         | 
| 205 204 | 
             
                    reason = status.reasons.find { |r| r.is_a?(Nanoc::Core::OutdatednessReasons::AttributesModified) }
         | 
| 206 | 
            -
                    reason && dependency.props. | 
| 205 | 
            +
                    reason && dependency.props.attribute_keys.any? && (dependency.props.attribute_keys & reason.attributes).empty?
         | 
| 207 206 | 
             
                  end
         | 
| 208 207 |  | 
| 209 | 
            -
                  def  | 
| 210 | 
            -
                     | 
| 211 | 
            -
             | 
| 212 | 
            -
             | 
| 213 | 
            -
             | 
| 214 | 
            -
                       | 
| 215 | 
            -
             | 
| 216 | 
            -
             | 
| 217 | 
            -
             | 
| 208 | 
            +
                  def raw_content_prop_causes_outdatedness?(objects, raw_content_prop)
         | 
| 209 | 
            +
                    return false unless raw_content_prop
         | 
| 210 | 
            +
             | 
| 211 | 
            +
                    matching_objects =
         | 
| 212 | 
            +
                      case raw_content_prop
         | 
| 213 | 
            +
                      when true
         | 
| 214 | 
            +
                        # If the `raw_content` dependency prop is `true`, then this is a
         | 
| 215 | 
            +
                        # dependency on all *objects* (items or layouts).
         | 
| 216 | 
            +
                        objects
         | 
| 217 | 
            +
                      when Enumerable
         | 
| 218 | 
            +
                        # If the `raw_content` dependency prop is a collection, then this
         | 
| 219 | 
            +
                        # is a dependency on specific objects, given by the patterns.
         | 
| 220 | 
            +
                        patterns = raw_content_prop.map { |r| Nanoc::Core::Pattern.from(r) }
         | 
| 221 | 
            +
                        patterns.flat_map { |pat| objects.select { |obj| pat.match?(obj.identifier) } }
         | 
| 222 | 
            +
                      else
         | 
| 223 | 
            +
                        raise(
         | 
| 224 | 
            +
                          Nanoc::Core::Errors::InternalInconsistency,
         | 
| 225 | 
            +
                          "Unexpected type of raw_content: #{raw_content_prop.inspect}",
         | 
| 226 | 
            +
                        )
         | 
| 227 | 
            +
                      end
         | 
| 228 | 
            +
             | 
| 229 | 
            +
                    # For all objects matching the `raw_content` dependency prop:
         | 
| 230 | 
            +
                    # If the object is outdated because it is newly added,
         | 
| 231 | 
            +
                    # then this dependency causes outdatedness.
         | 
| 232 | 
            +
                    #
         | 
| 233 | 
            +
                    # Note that these objects might be modified but *not* newly added,
         | 
| 234 | 
            +
                    # in which case this dependency will *not* cause outdatedness.
         | 
| 235 | 
            +
                    # However, when the object is used later (e.g. attributes are
         | 
| 236 | 
            +
                    # accessed), then another dependency will exist that will cause
         | 
| 237 | 
            +
                    # outdatedness.
         | 
| 238 | 
            +
                    matching_objects.any? do |obj|
         | 
| 239 | 
            +
                      status = basic.outdatedness_status_for(obj)
         | 
| 240 | 
            +
                      status.reasons.any? { |r| Nanoc::Core::OutdatednessReasons::DocumentAdded == r }
         | 
| 241 | 
            +
                    end
         | 
| 242 | 
            +
                  end
         | 
| 243 | 
            +
             | 
| 244 | 
            +
                  def attributes_prop_causes_outdatedness?(objects, attributes_prop)
         | 
| 245 | 
            +
                    return false unless attributes_prop
         | 
| 246 | 
            +
             | 
| 247 | 
            +
                    unless attributes_prop.is_a?(Set)
         | 
| 248 | 
            +
                      raise(
         | 
| 249 | 
            +
                        Nanoc::Core::Errors::InternalInconsistency,
         | 
| 250 | 
            +
                        'expected attributes_prop to be a Set',
         | 
| 251 | 
            +
                      )
         | 
| 252 | 
            +
                    end
         | 
| 253 | 
            +
             | 
| 254 | 
            +
                    pairs = attributes_prop.select { |a| a.is_a?(Array) }.to_h
         | 
| 255 | 
            +
             | 
| 256 | 
            +
                    unless pairs.any?
         | 
| 257 | 
            +
                      raise(
         | 
| 258 | 
            +
                        Nanoc::Core::Errors::InternalInconsistency,
         | 
| 259 | 
            +
                        'expected attributes_prop not to be empty',
         | 
| 260 | 
            +
                      )
         | 
| 261 | 
            +
                    end
         | 
| 262 | 
            +
             | 
| 263 | 
            +
                    dep_checksums = pairs.transform_values { |value| Nanoc::Core::Checksummer.calc(value) }
         | 
| 264 | 
            +
             | 
| 265 | 
            +
                    objects.any? do |object|
         | 
| 266 | 
            +
                      # Find old and new attribute checksums for the object
         | 
| 267 | 
            +
                      old_object_checksums = checksum_store.attributes_checksum_for(object)
         | 
| 268 | 
            +
                      next false unless old_object_checksums
         | 
| 269 | 
            +
             | 
| 270 | 
            +
                      new_object_checksums = checksums.attributes_checksum_for(object)
         | 
| 271 | 
            +
             | 
| 272 | 
            +
                      dep_checksums.any? do |key, dep_value|
         | 
| 273 | 
            +
                        # Get old and new checksum for this particular attribute
         | 
| 274 | 
            +
                        old_value = old_object_checksums[key]
         | 
| 275 | 
            +
                        new_value = new_object_checksums[key]
         | 
| 276 | 
            +
             | 
| 277 | 
            +
                        # If the old and new checksums are identical, then the attribute is
         | 
| 278 | 
            +
                        # unchanged and can’t cause outdatedness.
         | 
| 279 | 
            +
                        next false unless old_value != new_value
         | 
| 280 | 
            +
             | 
| 281 | 
            +
                        # We already know that the old value and new value are different.
         | 
| 282 | 
            +
                        # This attribute will cause outdatedness if either of those
         | 
| 283 | 
            +
                        # checksums is identical to the one in the prop.
         | 
| 284 | 
            +
                        old_value == dep_value || new_value == dep_value
         | 
| 285 | 
            +
                      end
         | 
| 218 286 | 
             
                    end
         | 
| 219 287 | 
             
                  end
         | 
| 220 288 | 
             
                end
         | 
| @@ -18,6 +18,10 @@ module Nanoc | |
| 18 18 | 
             
                    # @param [String] message The descriptive message for this outdatedness
         | 
| 19 19 | 
             
                    #   reason
         | 
| 20 20 | 
             
                    def initialize(message, props = Nanoc::Core::DependencyProps.new)
         | 
| 21 | 
            +
                      # TODO: Replace `DependencyProps` with its own `OutdatednessProps`
         | 
| 22 | 
            +
                      # type. For `OutdatednessProps`, the only values are true/false;
         | 
| 23 | 
            +
                      # giving a collection for `raw_content` makes no sense (anymore).
         | 
| 24 | 
            +
             | 
| 21 25 | 
             
                      @message = message
         | 
| 22 26 | 
             
                      @props = props
         | 
| 23 27 | 
             
                    end
         | 
| @@ -42,30 +46,16 @@ module Nanoc | |
| 42 46 | 
             
                    Nanoc::Core::DependencyProps.new(compiled_content: true, path: true),
         | 
| 43 47 | 
             
                  )
         | 
| 44 48 |  | 
| 49 | 
            +
                  DocumentAdded = Generic.new(
         | 
| 50 | 
            +
                    'The item or layout is newly added to the site.',
         | 
| 51 | 
            +
                    Nanoc::Core::DependencyProps.new, # NOTE: empty props, because they’re not relevant
         | 
| 52 | 
            +
                  )
         | 
| 53 | 
            +
             | 
| 45 54 | 
             
                  ContentModified = Generic.new(
         | 
| 46 55 | 
             
                    'The content of this item has been modified since the last time the site was compiled.',
         | 
| 47 56 | 
             
                    Nanoc::Core::DependencyProps.new(raw_content: true, compiled_content: true),
         | 
| 48 57 | 
             
                  )
         | 
| 49 58 |  | 
| 50 | 
            -
                  class DocumentCollectionExtended < Generic
         | 
| 51 | 
            -
                    attr_reader :objects
         | 
| 52 | 
            -
             | 
| 53 | 
            -
                    def initialize(objects)
         | 
| 54 | 
            -
                      super(
         | 
| 55 | 
            -
                        'New items/layouts have been added to the site.',
         | 
| 56 | 
            -
                        Nanoc::Core::DependencyProps.new(raw_content: true),
         | 
| 57 | 
            -
                      )
         | 
| 58 | 
            -
             | 
| 59 | 
            -
                      @objects = objects
         | 
| 60 | 
            -
                    end
         | 
| 61 | 
            -
                  end
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                  class ItemCollectionExtended < DocumentCollectionExtended
         | 
| 64 | 
            -
                  end
         | 
| 65 | 
            -
             | 
| 66 | 
            -
                  class LayoutCollectionExtended < DocumentCollectionExtended
         | 
| 67 | 
            -
                  end
         | 
| 68 | 
            -
             | 
| 69 59 | 
             
                  class AttributesModified < Generic
         | 
| 70 60 | 
             
                    attr_reader :attributes
         | 
| 71 61 |  | 
| @@ -23,11 +23,39 @@ module Nanoc | |
| 23 23 | 
             
                  end
         | 
| 24 24 |  | 
| 25 25 | 
             
                  def self.affects_props(*names)
         | 
| 26 | 
            -
                    @ | 
| 26 | 
            +
                    @affects_raw_content = false
         | 
| 27 | 
            +
                    @affects_attributes = false
         | 
| 28 | 
            +
                    @affects_compiled_content = false
         | 
| 29 | 
            +
                    @affects_path = false
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    names.each do |name|
         | 
| 32 | 
            +
                      case name
         | 
| 33 | 
            +
                      when :raw_content
         | 
| 34 | 
            +
                        @affects_raw_content = true
         | 
| 35 | 
            +
                      when :attributes
         | 
| 36 | 
            +
                        @affects_attributes = true
         | 
| 37 | 
            +
                      when :compiled_content
         | 
| 38 | 
            +
                        @affects_compiled_content = true
         | 
| 39 | 
            +
                      when :path
         | 
| 40 | 
            +
                        @affects_path = true
         | 
| 41 | 
            +
                      end
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  def self.affects_raw_content?
         | 
| 46 | 
            +
                    @affects_raw_content
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  def self.affects_attributes?
         | 
| 50 | 
            +
                    @affects_attributes
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  def self.affects_compiled_content?
         | 
| 54 | 
            +
                    @affects_compiled_content
         | 
| 27 55 | 
             
                  end
         | 
| 28 56 |  | 
| 29 | 
            -
                  def self. | 
| 30 | 
            -
                    @ | 
| 57 | 
            +
                  def self.affects_path?
         | 
| 58 | 
            +
                    @affects_path
         | 
| 31 59 | 
             
                  end
         | 
| 32 60 | 
             
                end
         | 
| 33 61 | 
             
              end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Nanoc
         | 
| 4 | 
            +
              module Core
         | 
| 5 | 
            +
                module OutdatednessRules
         | 
| 6 | 
            +
                  class ItemAdded < Nanoc::Core::OutdatednessRule
         | 
| 7 | 
            +
                    affects_props :raw_content
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    contract Nanoc::Core::ItemRep, C::Named['Nanoc::Core::OutdatednessChecker'] => C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
         | 
| 10 | 
            +
                    def apply(obj, outdatedness_checker)
         | 
| 11 | 
            +
                      if outdatedness_checker.dependency_store.new_items.include?(obj.item)
         | 
| 12 | 
            +
                        Nanoc::Core::OutdatednessReasons::DocumentAdded
         | 
| 13 | 
            +
                      end
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Nanoc
         | 
| 4 | 
            +
              module Core
         | 
| 5 | 
            +
                module OutdatednessRules
         | 
| 6 | 
            +
                  class LayoutAdded < Nanoc::Core::OutdatednessRule
         | 
| 7 | 
            +
                    affects_props :raw_content
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    contract Nanoc::Core::Layout, C::Named['Nanoc::Core::OutdatednessChecker'] => C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
         | 
| 10 | 
            +
                    def apply(obj, outdatedness_checker)
         | 
| 11 | 
            +
                      if outdatedness_checker.dependency_store.new_layouts.include?(obj)
         | 
| 12 | 
            +
                        Nanoc::Core::OutdatednessReasons::DocumentAdded
         | 
| 13 | 
            +
                      end
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -13,7 +13,12 @@ module Nanoc | |
| 13 13 | 
             
                  end
         | 
| 14 14 |  | 
| 15 15 | 
             
                  def useful_to_apply?(rule)
         | 
| 16 | 
            -
                     | 
| 16 | 
            +
                    return true if rule.affects_raw_content? && !@props.raw_content?
         | 
| 17 | 
            +
                    return true if rule.affects_attributes? && !@props.attributes?
         | 
| 18 | 
            +
                    return true if rule.affects_compiled_content? && !@props.compiled_content?
         | 
| 19 | 
            +
                    return true if rule.affects_path? && !@props.path?
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    false
         | 
| 17 22 | 
             
                  end
         | 
| 18 23 |  | 
| 19 24 | 
             
                  def update(reason)
         | 
| @@ -22,6 +27,10 @@ module Nanoc | |
| 22 27 | 
             
                      props: @props.merge(reason.props),
         | 
| 23 28 | 
             
                    )
         | 
| 24 29 | 
             
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  def inspect
         | 
| 32 | 
            +
                    "<#{self.class} reasons=#{@reasons.inspect} props=#{@props.inspect}>"
         | 
| 33 | 
            +
                  end
         | 
| 25 34 | 
             
                end
         | 
| 26 35 | 
             
              end
         | 
| 27 36 | 
             
            end
         | 
    
        data/lib/nanoc/core/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: nanoc-core
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 4.12. | 
| 4 | 
            +
              version: 4.12.10
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Denis Defreyne
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2022-10- | 
| 11 | 
            +
            date: 2022-10-18 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: concurrent-ruby
         | 
| @@ -261,8 +261,8 @@ files: | |
| 261 261 | 
             
            - lib/nanoc/core/outdatedness_rules/attributes_modified.rb
         | 
| 262 262 | 
             
            - lib/nanoc/core/outdatedness_rules/code_snippets_modified.rb
         | 
| 263 263 | 
             
            - lib/nanoc/core/outdatedness_rules/content_modified.rb
         | 
| 264 | 
            -
            - lib/nanoc/core/outdatedness_rules/ | 
| 265 | 
            -
            - lib/nanoc/core/outdatedness_rules/ | 
| 264 | 
            +
            - lib/nanoc/core/outdatedness_rules/item_added.rb
         | 
| 265 | 
            +
            - lib/nanoc/core/outdatedness_rules/layout_added.rb
         | 
| 266 266 | 
             
            - lib/nanoc/core/outdatedness_rules/not_written.rb
         | 
| 267 267 | 
             
            - lib/nanoc/core/outdatedness_rules/rules_modified.rb
         | 
| 268 268 | 
             
            - lib/nanoc/core/outdatedness_rules/uses_always_outdated_filter.rb
         | 
| @@ -315,7 +315,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 315 315 | 
             
                - !ruby/object:Gem::Version
         | 
| 316 316 | 
             
                  version: '0'
         | 
| 317 317 | 
             
            requirements: []
         | 
| 318 | 
            -
            rubygems_version: 3.3. | 
| 318 | 
            +
            rubygems_version: 3.3.24
         | 
| 319 319 | 
             
            signing_key:
         | 
| 320 320 | 
             
            specification_version: 4
         | 
| 321 321 | 
             
            summary: Core of Nanoc
         | 
| @@ -1,20 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Nanoc
         | 
| 4 | 
            -
              module Core
         | 
| 5 | 
            -
                module OutdatednessRules
         | 
| 6 | 
            -
                  class ItemCollectionExtended < Nanoc::Core::OutdatednessRule
         | 
| 7 | 
            -
                    affects_props :raw_content
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                    contract Nanoc::Core::ItemCollection, C::Named['Nanoc::Core::OutdatednessChecker'] => C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
         | 
| 10 | 
            -
                    def apply(_obj, outdatedness_checker)
         | 
| 11 | 
            -
                      new_items = outdatedness_checker.dependency_store.new_items
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                      if new_items.any?
         | 
| 14 | 
            -
                        Nanoc::Core::OutdatednessReasons::ItemCollectionExtended.new(new_items)
         | 
| 15 | 
            -
                      end
         | 
| 16 | 
            -
                    end
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
              end
         | 
| 20 | 
            -
            end
         | 
| @@ -1,20 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Nanoc
         | 
| 4 | 
            -
              module Core
         | 
| 5 | 
            -
                module OutdatednessRules
         | 
| 6 | 
            -
                  class LayoutCollectionExtended < Nanoc::Core::OutdatednessRule
         | 
| 7 | 
            -
                    affects_props :raw_content
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                    contract Nanoc::Core::LayoutCollection, C::Named['Nanoc::Core::OutdatednessChecker'] => C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
         | 
| 10 | 
            -
                    def apply(_obj, outdatedness_checker)
         | 
| 11 | 
            -
                      new_layouts = outdatedness_checker.dependency_store.new_layouts
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                      if new_layouts.any?
         | 
| 14 | 
            -
                        Nanoc::Core::OutdatednessReasons::LayoutCollectionExtended.new(new_layouts)
         | 
| 15 | 
            -
                      end
         | 
| 16 | 
            -
                    end
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
              end
         | 
| 20 | 
            -
            end
         |