nanoc-core 4.11.12 → 4.11.17

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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/lib/nanoc/core.rb +37 -0
  3. data/lib/nanoc/core/basic_item_rep_collection_view.rb +88 -0
  4. data/lib/nanoc/core/basic_item_rep_view.rb +83 -0
  5. data/lib/nanoc/core/basic_item_view.rb +54 -0
  6. data/lib/nanoc/core/changes_stream.rb +55 -0
  7. data/lib/nanoc/core/checksum_store.rb +1 -1
  8. data/lib/nanoc/core/checksummer.rb +4 -2
  9. data/lib/nanoc/core/compilation_item_rep_collection_view.rb +12 -0
  10. data/lib/nanoc/core/compilation_item_rep_view.rb +57 -0
  11. data/lib/nanoc/core/compilation_item_view.rb +47 -0
  12. data/lib/nanoc/core/compilation_phases/abstract.rb +48 -0
  13. data/lib/nanoc/core/compilation_phases/cache.rb +43 -0
  14. data/lib/nanoc/core/compilation_phases/mark_done.rb +23 -0
  15. data/lib/nanoc/core/compilation_phases/notify.rb +19 -0
  16. data/lib/nanoc/core/compilation_phases/recalculate.rb +49 -0
  17. data/lib/nanoc/core/compilation_phases/resume.rb +52 -0
  18. data/lib/nanoc/core/compilation_phases/write.rb +84 -0
  19. data/lib/nanoc/core/compilation_stages/build_reps.rb +36 -0
  20. data/lib/nanoc/core/compilation_stages/calculate_checksums.rb +42 -0
  21. data/lib/nanoc/core/compilation_stages/cleanup.rb +43 -0
  22. data/lib/nanoc/core/compilation_stages/compile_reps.rb +96 -0
  23. data/lib/nanoc/core/compilation_stages/determine_outdatedness.rb +49 -0
  24. data/lib/nanoc/core/compilation_stages/forget_outdated_dependencies.rb +20 -0
  25. data/lib/nanoc/core/compilation_stages/load_stores.rb +35 -0
  26. data/lib/nanoc/core/compilation_stages/postprocess.rb +21 -0
  27. data/lib/nanoc/core/compilation_stages/preprocess.rb +32 -0
  28. data/lib/nanoc/core/compilation_stages/prune.rb +30 -0
  29. data/lib/nanoc/core/compilation_stages/store_post_compilation_state.rb +20 -0
  30. data/lib/nanoc/core/compilation_stages/store_pre_compilation_state.rb +32 -0
  31. data/lib/nanoc/core/compiled_content_cache.rb +2 -2
  32. data/lib/nanoc/core/compiler.rb +214 -0
  33. data/lib/nanoc/core/compiler_loader.rb +48 -0
  34. data/lib/nanoc/core/config_loader.rb +95 -0
  35. data/lib/nanoc/core/config_view.rb +67 -0
  36. data/lib/nanoc/core/configuration.rb +2 -4
  37. data/lib/nanoc/core/contracts_support.rb +20 -0
  38. data/lib/nanoc/core/dependency_store.rb +3 -3
  39. data/lib/nanoc/core/document_view_mixin.rb +87 -0
  40. data/lib/nanoc/core/errors.rb +108 -0
  41. data/lib/nanoc/core/executor.rb +134 -0
  42. data/lib/nanoc/core/feature.rb +92 -0
  43. data/lib/nanoc/core/filter.rb +269 -0
  44. data/lib/nanoc/core/identifiable_collection_view.rb +111 -0
  45. data/lib/nanoc/core/item_collection_with_reps_view.rb +12 -0
  46. data/lib/nanoc/core/item_collection_without_reps_view.rb +12 -0
  47. data/lib/nanoc/core/item_rep_builder.rb +54 -0
  48. data/lib/nanoc/core/item_rep_selector.rb +67 -0
  49. data/lib/nanoc/core/item_rep_writer.rb +85 -0
  50. data/lib/nanoc/core/layout_collection_view.rb +12 -0
  51. data/lib/nanoc/core/layout_view.rb +9 -0
  52. data/lib/nanoc/core/mutable_config_view.rb +16 -0
  53. data/lib/nanoc/core/mutable_document_view_mixin.rb +60 -0
  54. data/lib/nanoc/core/mutable_identifiable_collection_view.rb +19 -0
  55. data/lib/nanoc/core/mutable_item_collection_view.rb +34 -0
  56. data/lib/nanoc/core/mutable_item_view.rb +9 -0
  57. data/lib/nanoc/core/mutable_layout_collection_view.rb +26 -0
  58. data/lib/nanoc/core/mutable_layout_view.rb +9 -0
  59. data/lib/nanoc/core/outdatedness_checker.rb +222 -0
  60. data/lib/nanoc/core/outdatedness_rules/attributes_modified.rb +41 -0
  61. data/lib/nanoc/core/outdatedness_rules/code_snippets_modified.rb +31 -0
  62. data/lib/nanoc/core/outdatedness_rules/content_modified.rb +21 -0
  63. data/lib/nanoc/core/outdatedness_rules/item_collection_extended.rb +20 -0
  64. data/lib/nanoc/core/outdatedness_rules/layout_collection_extended.rb +20 -0
  65. data/lib/nanoc/core/outdatedness_rules/not_written.rb +17 -0
  66. data/lib/nanoc/core/outdatedness_rules/rules_modified.rb +45 -0
  67. data/lib/nanoc/core/outdatedness_rules/uses_always_outdated_filter.rb +26 -0
  68. data/lib/nanoc/core/post_compile_item_collection_view.rb +12 -0
  69. data/lib/nanoc/core/post_compile_item_rep_collection_view.rb +12 -0
  70. data/lib/nanoc/core/post_compile_item_rep_view.rb +33 -0
  71. data/lib/nanoc/core/post_compile_item_view.rb +20 -0
  72. data/lib/nanoc/core/pruner.rb +123 -0
  73. data/lib/nanoc/core/site_loader.rb +102 -0
  74. data/lib/nanoc/core/trivial_error.rb +10 -0
  75. data/lib/nanoc/core/version.rb +1 -1
  76. data/lib/nanoc/core/view.rb +43 -0
  77. data/lib/nanoc/core/view_context_for_compilation.rb +6 -6
  78. metadata +97 -3
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ class MutableIdentifiableCollectionView < Nanoc::Core::IdentifiableCollectionView
6
+ # Deletes every object for which the block evaluates to true.
7
+ #
8
+ # @yieldparam [#identifier] object
9
+ #
10
+ # @yieldreturn [Boolean]
11
+ #
12
+ # @return [self]
13
+ def delete_if(&_block)
14
+ @objects = @objects.reject { |o| yield(view_class.new(o, @context)) }
15
+ self
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ class MutableItemCollectionView < Nanoc::Core::MutableIdentifiableCollectionView
6
+ # @api private
7
+ def view_class
8
+ Nanoc::Core::MutableItemView
9
+ end
10
+
11
+ # Creates a new item and adds it to the site’s collection of items.
12
+ #
13
+ # @param [String] content The uncompiled item content (if it is a textual
14
+ # item) or the path to the filename containing the content (if it is a
15
+ # binary item).
16
+ #
17
+ # @param [Hash] attributes A hash containing this item's attributes.
18
+ #
19
+ # @param [Nanoc::Core::Identifier, String] identifier This item's identifier.
20
+ #
21
+ # @param [Boolean] binary Whether or not this item is binary
22
+ #
23
+ # @param [String] filename Absolute path to the file
24
+ # containing this content (if any)
25
+ #
26
+ # @return [self]
27
+ def create(content, attributes, identifier, binary: false, filename: nil)
28
+ content = Nanoc::Core::Content.create(content, binary: binary, filename: filename)
29
+ @objects = @objects.add(Nanoc::Core::Item.new(content, attributes, identifier))
30
+ self
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ class MutableItemView < Nanoc::Core::BasicItemView
6
+ include Nanoc::Core::MutableDocumentViewMixin
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ class MutableLayoutCollectionView < Nanoc::Core::MutableIdentifiableCollectionView
6
+ # @api private
7
+ def view_class
8
+ Nanoc::Core::MutableLayoutView
9
+ end
10
+
11
+ # Creates a new layout and adds it to the site’s collection of layouts.
12
+ #
13
+ # @param [String] content The layout content.
14
+ #
15
+ # @param [Hash] attributes A hash containing this layout's attributes.
16
+ #
17
+ # @param [Nanoc::Core::Identifier, String] identifier This layout's identifier.
18
+ #
19
+ # @return [self]
20
+ def create(content, attributes, identifier)
21
+ @objects = @objects.add(Nanoc::Core::Layout.new(content, attributes, identifier))
22
+ self
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ class MutableLayoutView < Nanoc::Core::LayoutView
6
+ include Nanoc::Core::MutableDocumentViewMixin
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,222 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ # Responsible for determining whether an item or a layout is outdated.
6
+ #
7
+ # @api private
8
+ class OutdatednessChecker
9
+ class Basic
10
+ DDMemoize.activate(self)
11
+
12
+ include Nanoc::Core::ContractsSupport
13
+
14
+ Rules = Nanoc::Core::OutdatednessRules
15
+
16
+ RULES_FOR_ITEM_REP =
17
+ [
18
+ Rules::RulesModified,
19
+ Rules::ContentModified,
20
+ Rules::AttributesModified,
21
+ Rules::NotWritten,
22
+ Rules::CodeSnippetsModified,
23
+ Rules::UsesAlwaysOutdatedFilter,
24
+ ].freeze
25
+
26
+ RULES_FOR_LAYOUT =
27
+ [
28
+ Rules::RulesModified,
29
+ Rules::ContentModified,
30
+ Rules::AttributesModified,
31
+ Rules::UsesAlwaysOutdatedFilter,
32
+ ].freeze
33
+
34
+ RULES_FOR_CONFIG =
35
+ [
36
+ Rules::AttributesModified,
37
+ ].freeze
38
+
39
+ RULES_FOR_ITEM_COLLECTION =
40
+ [
41
+ Rules::ItemCollectionExtended,
42
+ ].freeze
43
+
44
+ RULES_FOR_LAYOUT_COLLECTION =
45
+ [
46
+ Rules::LayoutCollectionExtended,
47
+ ].freeze
48
+
49
+ C_OBJ_MAYBE_REP = C::Or[Nanoc::Core::Item, Nanoc::Core::ItemRep, Nanoc::Core::Configuration, Nanoc::Core::Layout, Nanoc::Core::ItemCollection, Nanoc::Core::LayoutCollection]
50
+
51
+ contract C::KeywordArgs[outdatedness_checker: OutdatednessChecker, reps: Nanoc::Core::ItemRepRepo] => C::Any
52
+ def initialize(outdatedness_checker:, reps:)
53
+ @outdatedness_checker = outdatedness_checker
54
+ @reps = reps
55
+ end
56
+
57
+ contract C_OBJ_MAYBE_REP => C::Maybe[Nanoc::Core::OutdatednessStatus]
58
+ memoized def outdatedness_status_for(obj)
59
+ case obj
60
+ when Nanoc::Core::ItemRep
61
+ apply_rules(RULES_FOR_ITEM_REP, obj)
62
+ when Nanoc::Core::Item
63
+ apply_rules_multi(RULES_FOR_ITEM_REP, @reps[obj])
64
+ when Nanoc::Core::Layout
65
+ apply_rules(RULES_FOR_LAYOUT, obj)
66
+ when Nanoc::Core::Configuration
67
+ apply_rules(RULES_FOR_CONFIG, obj)
68
+ when Nanoc::Core::ItemCollection
69
+ apply_rules(RULES_FOR_ITEM_COLLECTION, obj)
70
+ when Nanoc::Core::LayoutCollection
71
+ apply_rules(RULES_FOR_LAYOUT_COLLECTION, obj)
72
+ else
73
+ raise Nanoc::Core::Errors::InternalInconsistency, "do not know how to check outdatedness of #{obj.inspect}"
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ contract C::ArrayOf[Class], C_OBJ_MAYBE_REP, Nanoc::Core::OutdatednessStatus => C::Maybe[Nanoc::Core::OutdatednessStatus]
80
+ def apply_rules(rules, obj, status = Nanoc::Core::OutdatednessStatus.new)
81
+ rules.inject(status) do |acc, rule|
82
+ if !acc.useful_to_apply?(rule)
83
+ acc
84
+ else
85
+ reason = rule.instance.call(obj, @outdatedness_checker)
86
+ if reason
87
+ acc.update(reason)
88
+ else
89
+ acc
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ contract C::ArrayOf[Class], C::ArrayOf[C_OBJ_MAYBE_REP] => C::Maybe[Nanoc::Core::OutdatednessStatus]
96
+ def apply_rules_multi(rules, objs)
97
+ objs.inject(Nanoc::Core::OutdatednessStatus.new) { |acc, elem| apply_rules(rules, elem, acc) }
98
+ end
99
+ end
100
+
101
+ DDMemoize.activate(self)
102
+
103
+ include Nanoc::Core::ContractsSupport
104
+
105
+ attr_reader :checksum_store
106
+ attr_reader :checksums
107
+ attr_reader :dependency_store
108
+ attr_reader :action_sequence_store
109
+ attr_reader :action_sequences
110
+ attr_reader :site
111
+
112
+ Reasons = Nanoc::Core::OutdatednessReasons
113
+
114
+ C_OBJ = C::Or[Nanoc::Core::Item, Nanoc::Core::ItemRep, Nanoc::Core::Configuration, Nanoc::Core::Layout, Nanoc::Core::ItemCollection]
115
+ C_ITEM_OR_REP = C::Or[Nanoc::Core::Item, Nanoc::Core::ItemRep]
116
+ C_ACTION_SEQUENCES = C::HashOf[C_OBJ => Nanoc::Core::ActionSequence]
117
+
118
+ contract C::KeywordArgs[site: Nanoc::Core::Site, checksum_store: Nanoc::Core::ChecksumStore, checksums: Nanoc::Core::ChecksumCollection, dependency_store: Nanoc::Core::DependencyStore, action_sequence_store: Nanoc::Core::ActionSequenceStore, action_sequences: C_ACTION_SEQUENCES, reps: Nanoc::Core::ItemRepRepo] => C::Any
119
+ def initialize(site:, checksum_store:, checksums:, dependency_store:, action_sequence_store:, action_sequences:, reps:)
120
+ @site = site
121
+ @checksum_store = checksum_store
122
+ @checksums = checksums
123
+ @dependency_store = dependency_store
124
+ @action_sequence_store = action_sequence_store
125
+ @action_sequences = action_sequences
126
+ @reps = reps
127
+
128
+ @objects_outdated_due_to_dependencies = {}
129
+ end
130
+
131
+ def action_sequence_for(rep)
132
+ @action_sequences.fetch(rep)
133
+ end
134
+
135
+ contract C_OBJ => C::Bool
136
+ def outdated?(obj)
137
+ outdatedness_reasons_for(obj).any?
138
+ end
139
+
140
+ contract C_OBJ => C::IterOf[Reasons::Generic]
141
+ def outdatedness_reasons_for(obj)
142
+ reasons = basic.outdatedness_status_for(obj).reasons
143
+ if reasons.any?
144
+ reasons
145
+ elsif outdated_due_to_dependencies?(obj)
146
+ [Reasons::DependenciesOutdated]
147
+ else
148
+ []
149
+ end
150
+ end
151
+
152
+ private
153
+
154
+ contract C::None => Basic
155
+ def basic
156
+ @_basic ||= Basic.new(outdatedness_checker: self, reps: @reps)
157
+ end
158
+
159
+ contract C_OBJ, Hamster::Set => C::Bool
160
+ def outdated_due_to_dependencies?(obj, processed = Hamster::Set.new)
161
+ # Convert from rep to item if necessary
162
+ obj = obj.item if obj.is_a?(Nanoc::Core::ItemRep)
163
+
164
+ # Only items can have dependencies
165
+ return false unless obj.is_a?(Nanoc::Core::Item)
166
+
167
+ # Get from cache
168
+ if @objects_outdated_due_to_dependencies.key?(obj)
169
+ return @objects_outdated_due_to_dependencies[obj]
170
+ end
171
+
172
+ # Check processed
173
+ # Don’t return true; the false will be or’ed into a true if there
174
+ # really is a dependency that is causing outdatedness.
175
+ return false if processed.include?(obj)
176
+
177
+ # Calculate
178
+ is_outdated = dependency_store.dependencies_causing_outdatedness_of(obj).any? do |dep|
179
+ dependency_causes_outdatedness?(dep) ||
180
+ (dep.props.compiled_content? &&
181
+ outdated_due_to_dependencies?(dep.from, processed.merge([obj])))
182
+ end
183
+
184
+ # Cache
185
+ @objects_outdated_due_to_dependencies[obj] = is_outdated
186
+
187
+ # Done
188
+ is_outdated
189
+ end
190
+
191
+ contract Nanoc::Core::Dependency => C::Bool
192
+ def dependency_causes_outdatedness?(dependency)
193
+ return true if dependency.from.nil?
194
+
195
+ status = basic.outdatedness_status_for(dependency.from)
196
+
197
+ active = status.props.active & dependency.props.active
198
+ active.delete(:attributes) if attributes_unaffected?(status, dependency)
199
+ active.delete(:raw_content) if raw_content_unaffected?(status, dependency)
200
+
201
+ active.any?
202
+ end
203
+
204
+ def attributes_unaffected?(status, dependency)
205
+ reason = status.reasons.find { |r| r.is_a?(Nanoc::Core::OutdatednessReasons::AttributesModified) }
206
+ reason && dependency.props.attributes.is_a?(Enumerable) && (dependency.props.attributes & reason.attributes).empty?
207
+ end
208
+
209
+ def raw_content_unaffected?(status, dependency)
210
+ reason = status.reasons.find { |r| r.is_a?(Nanoc::Core::OutdatednessReasons::DocumentCollectionExtended) }
211
+ if reason.nil?
212
+ false
213
+ elsif !dependency.props.raw_content.is_a?(Enumerable)
214
+ false
215
+ else
216
+ patterns = dependency.props.raw_content.map { |r| Nanoc::Core::Pattern.from(r) }
217
+ patterns.none? { |pat| reason.objects.any? { |obj| pat.match?(obj.identifier) } }
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ module OutdatednessRules
6
+ class AttributesModified < Nanoc::Core::OutdatednessRule
7
+ include Nanoc::Core::ContractsSupport
8
+
9
+ affects_props :attributes, :compiled_content
10
+
11
+ contract C::Or[Nanoc::Core::ItemRep, Nanoc::Core::Item, Nanoc::Core::Configuration, Nanoc::Core::Layout], C::Named['Nanoc::Core::OutdatednessChecker'] => C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
12
+ def apply(obj, outdatedness_checker)
13
+ case obj
14
+ when Nanoc::Core::ItemRep
15
+ apply(obj.item, outdatedness_checker)
16
+ when Nanoc::Core::Item, Nanoc::Core::Layout, Nanoc::Core::Configuration
17
+ if outdatedness_checker.checksum_store[obj] == outdatedness_checker.checksums.checksum_for(obj)
18
+ return nil
19
+ end
20
+
21
+ old_checksums = outdatedness_checker.checksum_store.attributes_checksum_for(obj)
22
+ unless old_checksums
23
+ return Nanoc::Core::OutdatednessReasons::AttributesModified.new(true)
24
+ end
25
+
26
+ new_checksums = outdatedness_checker.checksums.attributes_checksum_for(obj)
27
+
28
+ attributes = Set.new(old_checksums.keys) + Set.new(new_checksums.keys)
29
+ changed_attributes = attributes.reject { |a| old_checksums[a] == new_checksums[a] }
30
+
31
+ if changed_attributes.any?
32
+ Nanoc::Core::OutdatednessReasons::AttributesModified.new(changed_attributes)
33
+ end
34
+ else
35
+ raise ArgumentError
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ module OutdatednessRules
6
+ class CodeSnippetsModified < Nanoc::Core::OutdatednessRule
7
+ DDMemoize.activate(self)
8
+
9
+ include Nanoc::Core::ContractsSupport
10
+
11
+ affects_props :raw_content, :attributes, :compiled_content, :path
12
+
13
+ def apply(_obj, outdatedness_checker)
14
+ if any_snippets_modified?(outdatedness_checker)
15
+ Nanoc::Core::OutdatednessReasons::CodeSnippetsModified
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ memoized 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 = outdatedness_checker.checksums.checksum_for(cs)
25
+ ch_old != ch_new
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ module OutdatednessRules
6
+ class ContentModified < Nanoc::Core::OutdatednessRule
7
+ affects_props :raw_content, :compiled_content
8
+
9
+ def apply(obj, outdatedness_checker)
10
+ obj = obj.item if obj.is_a?(Nanoc::Core::ItemRep)
11
+
12
+ ch_old = outdatedness_checker.checksum_store.content_checksum_for(obj)
13
+ ch_new = outdatedness_checker.checksums.content_checksum_for(obj)
14
+ if ch_old != ch_new
15
+ Nanoc::Core::OutdatednessReasons::ContentModified
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
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
@@ -0,0 +1,20 @@
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