nanoc-core 4.14.6 → 4.14.8

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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/lib/nanoc/core/action_sequence.rb +1 -1
  3. data/lib/nanoc/core/action_sequence_builder.rb +12 -4
  4. data/lib/nanoc/core/action_sequence_store.rb +8 -5
  5. data/lib/nanoc/core/assertions.rb +12 -2
  6. data/lib/nanoc/core/basic_outdatedness_checker.rb +26 -10
  7. data/lib/nanoc/core/binary_compiled_content_cache.rb +24 -10
  8. data/lib/nanoc/core/checksum_collection.rb +7 -2
  9. data/lib/nanoc/core/checksum_store.rb +26 -9
  10. data/lib/nanoc/core/checksummer.rb +63 -32
  11. data/lib/nanoc/core/code_snippet.rb +1 -1
  12. data/lib/nanoc/core/compilation_stages/build_reps.rb +7 -2
  13. data/lib/nanoc/core/compilation_stages/calculate_checksums.rb +2 -0
  14. data/lib/nanoc/core/compilation_stages/cleanup.rb +8 -2
  15. data/lib/nanoc/core/compilation_stages/compile_reps.rb +78 -36
  16. data/lib/nanoc/core/compilation_stages/determine_outdatedness.rb +2 -0
  17. data/lib/nanoc/core/compilation_stages/forget_outdated_dependencies.rb +5 -1
  18. data/lib/nanoc/core/compilation_stages/load_stores.rb +6 -1
  19. data/lib/nanoc/core/compilation_stages/postprocess.rb +2 -0
  20. data/lib/nanoc/core/compilation_stages/preprocess.rb +12 -3
  21. data/lib/nanoc/core/compilation_stages/prune.rb +6 -1
  22. data/lib/nanoc/core/compilation_stages/store_post_compilation_state.rb +2 -0
  23. data/lib/nanoc/core/compilation_stages/store_pre_compilation_state.rb +6 -1
  24. data/lib/nanoc/core/compiled_content_cache.rb +7 -2
  25. data/lib/nanoc/core/compiled_content_repo.rb +13 -5
  26. data/lib/nanoc/core/compiler.rb +12 -3
  27. data/lib/nanoc/core/compiler_loader.rb +13 -4
  28. data/lib/nanoc/core/config_loader.rb +14 -4
  29. data/lib/nanoc/core/configuration.rb +36 -15
  30. data/lib/nanoc/core/content.rb +5 -1
  31. data/lib/nanoc/core/context.rb +4 -5
  32. data/lib/nanoc/core/contracts_support.rb +26 -8
  33. data/lib/nanoc/core/core_ext/hash.rb +12 -2
  34. data/lib/nanoc/core/data_source.rb +22 -6
  35. data/lib/nanoc/core/dependency.rb +8 -2
  36. data/lib/nanoc/core/dependency_props.rb +27 -8
  37. data/lib/nanoc/core/dependency_store.rb +55 -22
  38. data/lib/nanoc/core/dependency_tracker.rb +20 -4
  39. data/lib/nanoc/core/directed_graph.rb +27 -64
  40. data/lib/nanoc/core/document.rb +4 -1
  41. data/lib/nanoc/core/errors.rb +45 -12
  42. data/lib/nanoc/core/executor.rb +26 -9
  43. data/lib/nanoc/core/feature.rb +2 -1
  44. data/lib/nanoc/core/filter.rb +27 -11
  45. data/lib/nanoc/core/identifiable_collection.rb +2 -1
  46. data/lib/nanoc/core/identifier.rb +23 -8
  47. data/lib/nanoc/core/in_memory_data_source.rb +3 -1
  48. data/lib/nanoc/core/item.rb +1 -1
  49. data/lib/nanoc/core/item_collection.rb +2 -2
  50. data/lib/nanoc/core/item_rep.rb +1 -1
  51. data/lib/nanoc/core/item_rep_builder.rb +14 -5
  52. data/lib/nanoc/core/item_rep_router.rb +27 -13
  53. data/lib/nanoc/core/item_rep_writer.rb +28 -5
  54. data/lib/nanoc/core/layout.rb +1 -1
  55. data/lib/nanoc/core/layout_collection.rb +2 -2
  56. data/lib/nanoc/core/mutable_document_view_mixin.rb +3 -6
  57. data/lib/nanoc/core/outdatedness_checker.rb +170 -95
  58. data/lib/nanoc/core/outdatedness_reasons.rb +45 -16
  59. data/lib/nanoc/core/outdatedness_rules/attributes_modified.rb +24 -10
  60. data/lib/nanoc/core/outdatedness_rules/item_added.rb +9 -4
  61. data/lib/nanoc/core/outdatedness_rules/layout_added.rb +9 -4
  62. data/lib/nanoc/core/outdatedness_rules/not_written.rb +7 -2
  63. data/lib/nanoc/core/outdatedness_rules/rules_modified.rb +14 -6
  64. data/lib/nanoc/core/outdatedness_rules/uses_always_outdated_filter.rb +1 -1
  65. data/lib/nanoc/core/outdatedness_store.rb +7 -1
  66. data/lib/nanoc/core/pattern.rb +4 -1
  67. data/lib/nanoc/core/prefixed_data_source.rb +6 -2
  68. data/lib/nanoc/core/processing_actions/filter.rb +2 -0
  69. data/lib/nanoc/core/processing_actions/layout.rb +2 -0
  70. data/lib/nanoc/core/processing_actions/snapshot.rb +12 -3
  71. data/lib/nanoc/core/pruner.rb +11 -3
  72. data/lib/nanoc/core/regexp_pattern.rb +1 -1
  73. data/lib/nanoc/core/site.rb +10 -4
  74. data/lib/nanoc/core/site_loader.rb +25 -17
  75. data/lib/nanoc/core/store.rb +33 -6
  76. data/lib/nanoc/core/string_pattern.rb +1 -1
  77. data/lib/nanoc/core/textual_compiled_content_cache.rb +60 -5
  78. data/lib/nanoc/core/textual_content.rb +4 -1
  79. data/lib/nanoc/core/version.rb +1 -1
  80. data/lib/nanoc/core/view_context_for_compilation.rb +6 -2
  81. data/lib/nanoc/core/views/basic_item_rep_collection_view.rb +11 -4
  82. data/lib/nanoc/core/views/basic_item_rep_view.rb +9 -2
  83. data/lib/nanoc/core/views/basic_item_view.rb +17 -9
  84. data/lib/nanoc/core/views/compilation_item_rep_view.rb +12 -4
  85. data/lib/nanoc/core/views/compilation_item_view.rb +3 -1
  86. data/lib/nanoc/core/views/identifiable_collection_view.rb +17 -5
  87. data/lib/nanoc/core/views/mutable_item_collection_view.rb +5 -2
  88. data/lib/nanoc/core/views/mutable_layout_collection_view.rb +5 -2
  89. data/lib/nanoc/core/views/post_compile_item_view.rb +3 -1
  90. data/lib/nanoc/core.rb +4 -4
  91. metadata +3 -9
  92. data/lib/nanoc/core/compilation_phases/abstract.rb +0 -48
  93. data/lib/nanoc/core/compilation_phases/cache.rb +0 -28
  94. data/lib/nanoc/core/compilation_phases/mark_done.rb +0 -23
  95. data/lib/nanoc/core/compilation_phases/notify.rb +0 -22
  96. data/lib/nanoc/core/compilation_phases/recalculate.rb +0 -59
  97. data/lib/nanoc/core/compilation_phases/write.rb +0 -31
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Nanoc
4
4
  module Core
5
- class LayoutCollection < IdentifiableCollection
5
+ class LayoutCollection < Nanoc::Core::IdentifiableCollection
6
6
  prepend MemoWise
7
7
 
8
8
  def initialize(config, objects = [])
@@ -10,7 +10,7 @@ module Nanoc
10
10
  end
11
11
 
12
12
  def reference
13
- 'layouts'
13
+ :layouts
14
14
  end
15
15
  end
16
16
  end
@@ -8,11 +8,9 @@ module Nanoc
8
8
  attr_reader :value
9
9
 
10
10
  def initialize(value)
11
- @value = value
12
- end
11
+ super("The #{value.class} cannot be stored inside an attribute. Store its identifier instead.")
13
12
 
14
- def message
15
- "The #{value.class} cannot be stored inside an attribute. Store its identifier instead."
13
+ @value = value
16
14
  end
17
15
  end
18
16
 
@@ -57,12 +55,11 @@ module Nanoc
57
55
  # the suggested alternative (Array#include?) carries a measurable
58
56
  # performance penatly.
59
57
  #
60
- # rubocop:disable Style/MultipleComparison
58
+ # rubocop:disable-next Style/MultipleComparison
61
59
  klass == Nanoc::Core::Item ||
62
60
  klass == Nanoc::Core::Layout ||
63
61
  klass == Nanoc::Core::CompilationItemView ||
64
62
  klass == Nanoc::Core::LayoutView
65
- # rubocop:enable Style/MultipleComparison
66
63
  end
67
64
  end
68
65
  end
@@ -17,7 +17,13 @@ module Nanoc
17
17
 
18
18
  Reasons = Nanoc::Core::OutdatednessReasons
19
19
 
20
- C_OBJ = C::Or[Nanoc::Core::Item, Nanoc::Core::ItemRep, Nanoc::Core::Configuration, Nanoc::Core::Layout, Nanoc::Core::ItemCollection]
20
+ C_OBJ = C::Or[
21
+ Nanoc::Core::Item,
22
+ Nanoc::Core::ItemRep,
23
+ Nanoc::Core::Configuration,
24
+ Nanoc::Core::Layout,
25
+ Nanoc::Core::ItemCollection,
26
+ ]
21
27
  C_ITEM_OR_REP = C::Or[Nanoc::Core::Item, Nanoc::Core::ItemRep]
22
28
  C_ACTION_SEQUENCES = C::HashOf[C_OBJ => Nanoc::Core::ActionSequence]
23
29
 
@@ -30,7 +36,10 @@ module Nanoc
30
36
  action_sequences: C_ACTION_SEQUENCES,
31
37
  reps: Nanoc::Core::ItemRepRepo,
32
38
  ] => C::Any
33
- def initialize(site:, checksum_store:, checksums:, dependency_store:, action_sequence_store:, action_sequences:, reps:)
39
+ def initialize(
40
+ site:, checksum_store:, checksums:, dependency_store:,
41
+ action_sequence_store:, action_sequences:, reps:
42
+ )
34
43
  @site = site
35
44
  @checksum_store = checksum_store
36
45
  @checksums = checksums
@@ -40,31 +49,139 @@ module Nanoc
40
49
  @reps = reps
41
50
 
42
51
  @objects_outdated_due_to_dependencies = {}
52
+ @ran = false
43
53
  end
44
54
 
45
55
  contract C_OBJ => C::IterOf[Reasons::Generic]
46
56
  def outdatedness_reasons_for(obj)
47
- basic_reasons = basic_outdatedness_statuses.fetch(obj).reasons
48
- if !basic_reasons.empty?
49
- basic_reasons
50
- elsif outdated_due_to_dependencies?(obj)
51
- [Reasons::DependenciesOutdated]
52
- else
53
- []
57
+ precalculate
58
+
59
+ basic_reasons = @basic_outdatedness_statuses.fetch(obj).reasons
60
+ unless basic_reasons.empty?
61
+ return basic_reasons
54
62
  end
63
+
64
+ obj = obj.item if obj.is_a?(Nanoc::Core::ItemRep)
65
+ if @objs_outdated_due_to_dependencies.include?(obj)
66
+ return [Reasons::DependenciesOutdated]
67
+ end
68
+
69
+ []
55
70
  end
56
71
 
57
72
  private
58
73
 
59
- def basic_outdatedness_statuses
60
- @_basic_outdatedness_statuses ||= {}.tap do |tmp|
61
- collections = [[@site.config], @site.layouts, @site.items, @reps]
62
- collections.each do |collection|
63
- collection.each do |obj|
64
- tmp[obj] = basic.outdatedness_status_for(obj)
74
+ def precalculate
75
+ return if @precalculated
76
+
77
+ @basic_outdatedness_statuses, basic_outdated_objs =
78
+ calc_basic_outdatedness_statuses
79
+
80
+ @objs_outdated_due_to_dependencies =
81
+ propagate_outdatedness(
82
+ @basic_outdatedness_statuses,
83
+ basic_outdated_objs,
84
+ )
85
+
86
+ @precalculated = true
87
+ end
88
+
89
+ def propagate_outdatedness(
90
+ basic_outdatedness_statuses,
91
+ basic_outdated_objs
92
+ )
93
+ objs_outdated_due_to_dependencies = Set.new
94
+
95
+ seen = Set.new
96
+ pending = [nil, @site.items, @site.layouts] + basic_outdated_objs.to_a
97
+ until pending.empty?
98
+ obj = pending.shift
99
+ obj = obj.item if obj.is_a?(Nanoc::Core::ItemRep)
100
+ next if seen.include?(obj)
101
+
102
+ seen << obj
103
+
104
+ deps = dependency_store.dependencies_outdated_because_of(obj)
105
+ deps.each do |dep|
106
+ # NOTE: dep.from == obj
107
+
108
+ status = basic_outdatedness_statuses[dep.to]
109
+ next if status && status.reasons.size.positive?
110
+ next if objs_outdated_due_to_dependencies.include?(dep.to)
111
+
112
+ case dep.from # from = what causes outdatedness
113
+
114
+ when nil
115
+ # Dependency from a removed object
116
+ objs_outdated_due_to_dependencies << dep.to
117
+ pending << dep.to
118
+
119
+ when Nanoc::Core::ItemCollection,
120
+ Nanoc::Core::LayoutCollection
121
+ coll = dep.from # or simply `obj`
122
+ props = dep.props
123
+
124
+ if raw_content_prop_causes_outdatedness?(
125
+ coll, props.raw_content, basic_outdatedness_statuses
126
+ ) || attributes_prop_causes_outdatedness?(
127
+ coll, props.attributes
128
+ )
129
+ objs_outdated_due_to_dependencies << dep.to
130
+ pending << dep.to
131
+ end
132
+
133
+ when Nanoc::Core::Item,
134
+ Nanoc::Core::Layout,
135
+ Nanoc::Core::Configuration
136
+ status = basic_outdatedness_statuses[dep.from]
137
+
138
+ active = status.props.active & dep.props.active
139
+ if attributes_unaffected?(status, dep)
140
+ active &= ~DependencyProps::BIT_PATTERN_ATTRIBUTES
141
+ end
142
+
143
+ if active != 0x00 || (
144
+ dep.props.compiled_content? &&
145
+ objs_outdated_due_to_dependencies.include?(dep.from)
146
+ )
147
+ objs_outdated_due_to_dependencies << dep.to
148
+ pending << dep.to
149
+ end
150
+
151
+ else
152
+ raise Nanoc::Core::Errors::InternalInconsistency,
153
+ "unexpected object type: #{dep.from.inspect}"
154
+ end
155
+ end
156
+ end
157
+
158
+ objs_outdated_due_to_dependencies
159
+ end
160
+
161
+ def calc_basic_outdatedness_statuses
162
+ basic_outdatedness_statuses = {}
163
+ basic_outdated_objs = Set.new
164
+
165
+ collections = [
166
+ [@site.config, @site.layouts, @site.items],
167
+ @site.layouts,
168
+ @site.items,
169
+ @reps,
170
+ ]
171
+
172
+ collections.each do |collection|
173
+ collection.each do |obj|
174
+ status = basic.outdatedness_status_for(obj)
175
+
176
+ basic_outdatedness_statuses[obj] = status
177
+
178
+ unless status.reasons.empty?
179
+ basic_outdated_objs << obj
65
180
  end
66
181
  end
67
182
  end
183
+
184
+ [basic_outdatedness_statuses, basic_outdated_objs.freeze]
68
185
  end
69
186
 
70
187
  contract C::None => BasicOutdatednessChecker
@@ -80,95 +197,51 @@ module Nanoc
80
197
  )
81
198
  end
82
199
 
83
- contract C_OBJ, Immutable::Set => C::Bool
84
- def outdated_due_to_dependencies?(obj, processed = Immutable::Set.new)
85
- # Convert from rep to item if necessary
86
- obj = obj.item if obj.is_a?(Nanoc::Core::ItemRep)
87
-
88
- # Only items can have dependencies
89
- return false unless obj.is_a?(Nanoc::Core::Item)
90
-
91
- # Get from cache
92
- if @objects_outdated_due_to_dependencies.key?(obj)
93
- return @objects_outdated_due_to_dependencies[obj]
94
- end
95
-
96
- # Check processed
97
- # Don’t return true; the false will be or’ed into a true if there
98
- # really is a dependency that is causing outdatedness.
99
- return false if processed.include?(obj)
100
-
101
- # Calculate
102
- is_outdated = dependency_store.dependencies_causing_outdatedness_of(obj).any? do |dep|
103
- dependency_causes_outdatedness?(dep) ||
104
- (dep.props.compiled_content? &&
105
- outdated_due_to_dependencies?(dep.from, processed.merge([obj])))
200
+ def attributes_unaffected?(status, dependency)
201
+ reason = status.reasons.find do |r|
202
+ r.is_a?(Nanoc::Core::OutdatednessReasons::AttributesModified)
106
203
  end
107
204
 
108
- # Cache
109
- @objects_outdated_due_to_dependencies[obj] = is_outdated
110
-
111
- # Done
112
- is_outdated
205
+ reason &&
206
+ !dependency.props.attribute_keys.empty? &&
207
+ !dependency.props.attribute_keys.intersect?(reason.attributes)
113
208
  end
114
209
 
115
- contract Nanoc::Core::Dependency => C::Bool
116
- def dependency_causes_outdatedness?(dependency)
117
- case dependency.from
118
- when nil
119
- true
120
- when Nanoc::Core::ItemCollection, Nanoc::Core::LayoutCollection
121
- all_objects = dependency.from
122
-
123
- raw_content_prop_causes_outdatedness?(all_objects, dependency.props.raw_content) ||
124
- attributes_prop_causes_outdatedness?(all_objects, dependency.props.attributes)
125
- else
126
- status = basic_outdatedness_statuses.fetch(dependency.from)
210
+ def raw_content_prop_causes_outdatedness?(
211
+ collection, raw_content_prop, basic_outdatedness_statuses
212
+ )
213
+ return false unless raw_content_prop
127
214
 
128
- active = status.props.active & dependency.props.active
129
- active.delete(:attributes) if attributes_unaffected?(status, dependency)
215
+ document_added_reason =
216
+ basic_outdatedness_statuses
217
+ .fetch(collection)
218
+ .reasons
219
+ .grep(Nanoc::Core::OutdatednessReasons::DocumentAdded)
220
+ .first
221
+ return false unless document_added_reason
130
222
 
131
- !active.empty?
132
- end
133
- end
223
+ case raw_content_prop
224
+ when true
225
+ true
134
226
 
135
- def attributes_unaffected?(status, dependency)
136
- reason = status.reasons.find { |r| r.is_a?(Nanoc::Core::OutdatednessReasons::AttributesModified) }
137
- reason && !dependency.props.attribute_keys.empty? && !dependency.props.attribute_keys.intersect?(reason.attributes)
138
- end
227
+ when Enumerable
228
+ patterns = raw_content_prop
229
+ identifiers = document_added_reason.identifiers
139
230
 
140
- def raw_content_prop_causes_outdatedness?(objects, raw_content_prop)
141
- return false unless raw_content_prop
231
+ patterns.any? do |pat|
232
+ coerced_pattern = Nanoc::Core::Pattern.from(pat)
142
233
 
143
- matching_objects =
144
- case raw_content_prop
145
- when true
146
- # If the `raw_content` dependency prop is `true`, then this is a
147
- # dependency on all *objects* (items or layouts).
148
- objects
149
- when Enumerable
150
- # If the `raw_content` dependency prop is a collection, then this
151
- # is a dependency on specific objects, given by the patterns.
152
- raw_content_prop.flat_map { |pat| objects.find_all(pat) }
153
- else
154
- raise(
155
- Nanoc::Core::Errors::InternalInconsistency,
156
- "Unexpected type of raw_content: #{raw_content_prop.inspect}",
157
- )
234
+ identifiers.any? do |identifier|
235
+ coerced_pattern.match?(identifier)
236
+ end
158
237
  end
159
238
 
160
- # For all objects matching the `raw_content` dependency prop:
161
- # If the object is outdated because it is newly added,
162
- # then this dependency causes outdatedness.
163
- #
164
- # Note that these objects might be modified but *not* newly added,
165
- # in which case this dependency will *not* cause outdatedness.
166
- # However, when the object is used later (e.g. attributes are
167
- # accessed), then another dependency will exist that will cause
168
- # outdatedness.
169
- matching_objects.any? do |obj|
170
- status = basic_outdatedness_statuses.fetch(obj)
171
- status.reasons.any? { |r| r == Nanoc::Core::OutdatednessReasons::DocumentAdded }
239
+ else
240
+ raise(
241
+ Nanoc::Core::Errors::InternalInconsistency,
242
+ "Unexpected type of raw_content: #{raw_content_prop.inspect}",
243
+ )
244
+
172
245
  end
173
246
  end
174
247
 
@@ -182,7 +255,7 @@ module Nanoc
182
255
  )
183
256
  end
184
257
 
185
- pairs = attributes_prop.select { |a| a.is_a?(Array) }.to_h
258
+ pairs = attributes_prop.grep(Array).to_h
186
259
 
187
260
  if pairs.empty?
188
261
  raise(
@@ -191,7 +264,9 @@ module Nanoc
191
264
  )
192
265
  end
193
266
 
194
- dep_checksums = pairs.transform_values { |value| Nanoc::Core::Checksummer.calc(value) }
267
+ dep_checksums = pairs.transform_values do |value|
268
+ Nanoc::Core::Checksummer.calc(value)
269
+ end
195
270
 
196
271
  objects.any? do |object|
197
272
  # Find old and new attribute checksums for the object
@@ -28,32 +28,55 @@ module Nanoc
28
28
  end
29
29
 
30
30
  CodeSnippetsModified = Generic.new(
31
- 'The code snippets have been modified since the last time the site was compiled.',
32
- Nanoc::Core::DependencyProps.new(raw_content: true, attributes: true, compiled_content: true, path: true),
31
+ 'The code snippets have been modified since the last time the site ' \
32
+ 'was compiled.',
33
+ Nanoc::Core::DependencyProps.new(
34
+ raw_content: true, attributes: true,
35
+ compiled_content: true, path: true
36
+ ),
33
37
  )
34
38
 
35
39
  DependenciesOutdated = Generic.new(
36
- 'This item uses content or attributes that have changed since the last time the site was compiled.',
40
+ 'This item uses content or attributes that have changed since the ' \
41
+ 'last time the site was compiled.',
37
42
  )
38
43
 
39
44
  NotWritten = Generic.new(
40
- 'This item representation has not yet been written to the output directory (but it does have a path).',
41
- Nanoc::Core::DependencyProps.new(raw_content: true, attributes: true, compiled_content: true, path: true),
45
+ 'This item representation has not yet been written to the output ' \
46
+ 'directory (but it does have a path).',
47
+ Nanoc::Core::DependencyProps.new(
48
+ raw_content: true, attributes: true,
49
+ compiled_content: true, path: true
50
+ ),
42
51
  )
43
52
 
44
53
  RulesModified = Generic.new(
45
- 'The rules file has been modified since the last time the site was compiled.',
54
+ 'The rules file has been modified since the last time the site was ' \
55
+ 'compiled.',
46
56
  Nanoc::Core::DependencyProps.new(compiled_content: true, path: true),
47
57
  )
48
58
 
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
- )
59
+ class DocumentAdded < Generic
60
+ attr_reader :identifiers
61
+
62
+ def initialize(identifiers:)
63
+ super(
64
+ 'Items or layouts were newly added to the site.',
65
+ Nanoc::Core::DependencyProps.new(
66
+ raw_content: true, compiled_content: true,
67
+ ),
68
+ )
69
+
70
+ @identifiers = identifiers
71
+ end
72
+ end
53
73
 
54
74
  ContentModified = Generic.new(
55
- 'The content of this item has been modified since the last time the site was compiled.',
56
- Nanoc::Core::DependencyProps.new(raw_content: true, compiled_content: true),
75
+ 'The content of this item has been modified since the last time ' \
76
+ 'the site was compiled.',
77
+ Nanoc::Core::DependencyProps.new(
78
+ raw_content: true, compiled_content: true,
79
+ ),
57
80
  )
58
81
 
59
82
  class AttributesModified < Generic
@@ -61,8 +84,11 @@ module Nanoc
61
84
 
62
85
  def initialize(attributes)
63
86
  super(
64
- 'The attributes of this item have been modified since the last time the site was compiled.',
65
- Nanoc::Core::DependencyProps.new(attributes: true, compiled_content: true),
87
+ 'The attributes of this item have been modified since the last ' \
88
+ 'time the site was compiled.',
89
+ Nanoc::Core::DependencyProps.new(
90
+ attributes: true, compiled_content: true,
91
+ ),
66
92
  )
67
93
 
68
94
  @attributes = attributes
@@ -70,8 +96,11 @@ module Nanoc
70
96
  end
71
97
 
72
98
  UsesAlwaysOutdatedFilter = Generic.new(
73
- 'This item rep uses one or more filters that cannot track dependencies, and will thus always be considered as outdated.',
74
- Nanoc::Core::DependencyProps.new(raw_content: true, attributes: true, compiled_content: true),
99
+ 'This item rep uses one or more filters that cannot track ' \
100
+ 'dependencies, and will thus always be considered as outdated.',
101
+ Nanoc::Core::DependencyProps.new(
102
+ raw_content: true, attributes: true, compiled_content: true,
103
+ ),
75
104
  )
76
105
  end
77
106
  end
@@ -8,28 +8,42 @@ module Nanoc
8
8
 
9
9
  affects_props :attributes, :compiled_content
10
10
 
11
- contract C::Or[Nanoc::Core::ItemRep, Nanoc::Core::Item, Nanoc::Core::Configuration, Nanoc::Core::Layout], C::Named['Nanoc::Core::BasicOutdatednessChecker'] => C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
11
+ contract C::Or[
12
+ Nanoc::Core::ItemRep,
13
+ Nanoc::Core::Item,
14
+ Nanoc::Core::Configuration,
15
+ Nanoc::Core::Layout,
16
+ ], C::Named['Nanoc::Core::BasicOutdatednessChecker'] =>
17
+ C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
12
18
  def apply(obj, basic_outdatedness_checker)
19
+ boc = basic_outdatedness_checker
20
+
13
21
  case obj
14
22
  when Nanoc::Core::ItemRep
15
- apply(obj.item, basic_outdatedness_checker)
16
- when Nanoc::Core::Item, Nanoc::Core::Layout, Nanoc::Core::Configuration
17
- if basic_outdatedness_checker.checksum_store[obj] == basic_outdatedness_checker.checksums.checksum_for(obj)
23
+ apply(obj.item, boc)
24
+ when Nanoc::Core::Item,
25
+ Nanoc::Core::Layout,
26
+ Nanoc::Core::Configuration
27
+ if boc.checksum_store[obj] == boc.checksums.checksum_for(obj)
18
28
  return nil
19
29
  end
20
30
 
21
- old_checksums = basic_outdatedness_checker.checksum_store.attributes_checksum_for(obj)
31
+ old_checksums = boc.checksum_store.attributes_checksum_for(obj)
22
32
  unless old_checksums
23
- return Nanoc::Core::OutdatednessReasons::AttributesModified.new(true)
33
+ return Nanoc::Core::OutdatednessReasons::AttributesModified
34
+ .new(true)
24
35
  end
25
36
 
26
- new_checksums = basic_outdatedness_checker.checksums.attributes_checksum_for(obj)
37
+ new_checksums = boc.checksums.attributes_checksum_for(obj)
27
38
 
28
- attributes = Set.new(old_checksums.keys) + Set.new(new_checksums.keys)
29
- changed_attributes = attributes.reject { |a| old_checksums[a] == new_checksums[a] }
39
+ attributes =
40
+ Set.new(old_checksums.keys) + Set.new(new_checksums.keys)
41
+ changed_attributes =
42
+ attributes.reject { |a| old_checksums[a] == new_checksums[a] }
30
43
 
31
44
  unless changed_attributes.empty?
32
- Nanoc::Core::OutdatednessReasons::AttributesModified.new(changed_attributes)
45
+ Nanoc::Core::OutdatednessReasons::AttributesModified
46
+ .new(changed_attributes)
33
47
  end
34
48
  else
35
49
  raise ArgumentError
@@ -6,10 +6,15 @@ module Nanoc
6
6
  class ItemAdded < Nanoc::Core::OutdatednessRule
7
7
  affects_props :raw_content
8
8
 
9
- contract Nanoc::Core::ItemRep, C::Named['Nanoc::Core::BasicOutdatednessChecker'] => C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
10
- def apply(obj, basic_outdatedness_checker)
11
- if basic_outdatedness_checker.dependency_store.new_items.include?(obj.item)
12
- Nanoc::Core::OutdatednessReasons::DocumentAdded
9
+ contract Nanoc::Core::ItemCollection,
10
+ C::Named['Nanoc::Core::BasicOutdatednessChecker'] =>
11
+ C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
12
+ def apply(_obj, basic_outdatedness_checker)
13
+ new_items = basic_outdatedness_checker.dependency_store.new_items
14
+ if new_items.size.positive?
15
+ Nanoc::Core::OutdatednessReasons::DocumentAdded.new(
16
+ identifiers: new_items.map(&:identifier),
17
+ )
13
18
  end
14
19
  end
15
20
  end
@@ -6,10 +6,15 @@ module Nanoc
6
6
  class LayoutAdded < Nanoc::Core::OutdatednessRule
7
7
  affects_props :raw_content
8
8
 
9
- contract Nanoc::Core::Layout, C::Named['Nanoc::Core::BasicOutdatednessChecker'] => C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
10
- def apply(obj, basic_outdatedness_checker)
11
- if basic_outdatedness_checker.dependency_store.new_layouts.include?(obj)
12
- Nanoc::Core::OutdatednessReasons::DocumentAdded
9
+ contract Nanoc::Core::LayoutCollection,
10
+ C::Named['Nanoc::Core::BasicOutdatednessChecker'] =>
11
+ C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
12
+ def apply(_obj, basic_outdatedness_checker)
13
+ new_layouts = basic_outdatedness_checker.dependency_store.new_layouts
14
+ if new_layouts.size.positive?
15
+ Nanoc::Core::OutdatednessReasons::DocumentAdded.new(
16
+ identifiers: new_layouts.map(&:identifier),
17
+ )
13
18
  end
14
19
  end
15
20
  end
@@ -7,7 +7,9 @@ module Nanoc
7
7
  affects_props :raw_content, :attributes, :compiled_content, :path
8
8
 
9
9
  def apply(obj, basic_outdatedness_checker)
10
- if obj.raw_paths.values.flatten.compact.any? { |fn| !exist?(fn, basic_outdatedness_checker) }
10
+ if obj.raw_paths.values.flatten.compact.any? do |fn|
11
+ !exist?(fn, basic_outdatedness_checker)
12
+ end
11
13
  Nanoc::Core::OutdatednessReasons::NotWritten
12
14
  end
13
15
  end
@@ -24,7 +26,10 @@ module Nanoc
24
26
 
25
27
  @all ||= {}
26
28
  @all[basic_outdatedness_checker] ||= Set.new(
27
- Dir.glob("#{site_root(basic_outdatedness_checker)}/**/*", File::FNM_DOTMATCH),
29
+ Dir.glob(
30
+ "#{site_root(basic_outdatedness_checker)}/**/*",
31
+ File::FNM_DOTMATCH,
32
+ ),
28
33
  )
29
34
  end
30
35
 
@@ -7,14 +7,16 @@ module Nanoc
7
7
  affects_props :compiled_content, :path
8
8
 
9
9
  def apply(obj, basic_outdatedness_checker)
10
+ boc = basic_outdatedness_checker
11
+
10
12
  # Check rules of obj itself
11
- if rules_modified?(obj, basic_outdatedness_checker)
13
+ if rules_modified?(obj, boc)
12
14
  return Nanoc::Core::OutdatednessReasons::RulesModified
13
15
  end
14
16
 
15
17
  # Check rules of layouts used by obj
16
- layouts = layouts_touched_by(obj, basic_outdatedness_checker)
17
- if layouts.any? { |layout| rules_modified?(layout, basic_outdatedness_checker) }
18
+ layouts = layouts_touched_by(obj, boc)
19
+ if layouts.any? { |l| rules_modified?(l, boc) }
18
20
  return Nanoc::Core::OutdatednessReasons::RulesModified
19
21
  end
20
22
 
@@ -24,8 +26,13 @@ module Nanoc
24
26
  private
25
27
 
26
28
  def rules_modified?(obj, basic_outdatedness_checker)
27
- seq_old = basic_outdatedness_checker.action_sequence_store[obj]
28
- seq_new = basic_outdatedness_checker.action_sequence_for(obj).serialize
29
+ seq_old =
30
+ basic_outdatedness_checker
31
+ .action_sequence_store[obj]
32
+ seq_new =
33
+ basic_outdatedness_checker
34
+ .action_sequence_for(obj)
35
+ .serialize
29
36
 
30
37
  !seq_old.eql?(seq_new)
31
38
  end
@@ -38,7 +45,8 @@ module Nanoc
38
45
 
39
46
  layout_actions.map do |layout_action|
40
47
  layout_pattern = layout_action[1]
41
- layouts.object_with_identifier(layout_pattern) || layouts.object_matching_glob(layout_pattern)
48
+ layouts.object_with_identifier(layout_pattern) ||
49
+ layouts.object_matching_glob(layout_pattern)
42
50
  end.compact
43
51
  end
44
52
  end
@@ -15,7 +15,7 @@ module Nanoc
15
15
 
16
16
  def any_always_outdated?(seq)
17
17
  seq
18
- .select { |a| a.is_a?(Nanoc::Core::ProcessingActions::Filter) }
18
+ .grep(Nanoc::Core::ProcessingActions::Filter)
19
19
  .map { |a| Nanoc::Core::Filter.named(a.filter_name) }
20
20
  .compact
21
21
  .any?(&:always_outdated?)
@@ -8,7 +8,13 @@ module Nanoc
8
8
 
9
9
  contract C::KeywordArgs[config: Nanoc::Core::Configuration] => C::Any
10
10
  def initialize(config:)
11
- super(Nanoc::Core::Store.tmp_path_for(config:, store_name: 'outdatedness'), 2)
11
+ super(
12
+ self.class.tmp_path_for(
13
+ config:,
14
+ store_name: 'outdatedness',
15
+ ),
16
+ 2,
17
+ )
12
18
 
13
19
  @outdated_refs = Set.new
14
20
  end
@@ -17,7 +17,10 @@ module Nanoc
17
17
  when Symbol
18
18
  Nanoc::Core::StringPattern.new(obj.to_s)
19
19
  else
20
- raise ArgumentError, "Do not know how to convert `#{obj.inspect}` into a Nanoc::Pattern"
20
+ raise(
21
+ ArgumentError,
22
+ "Do not know how to convert `#{obj.inspect}` into a Nanoc::Pattern",
23
+ )
21
24
  end
22
25
  end
23
26