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.
- checksums.yaml +4 -4
- data/lib/nanoc/core/action_sequence.rb +1 -1
- data/lib/nanoc/core/action_sequence_builder.rb +12 -4
- data/lib/nanoc/core/action_sequence_store.rb +8 -5
- data/lib/nanoc/core/assertions.rb +12 -2
- data/lib/nanoc/core/basic_outdatedness_checker.rb +26 -10
- data/lib/nanoc/core/binary_compiled_content_cache.rb +24 -10
- data/lib/nanoc/core/checksum_collection.rb +7 -2
- data/lib/nanoc/core/checksum_store.rb +26 -9
- data/lib/nanoc/core/checksummer.rb +63 -32
- data/lib/nanoc/core/code_snippet.rb +1 -1
- data/lib/nanoc/core/compilation_stages/build_reps.rb +7 -2
- data/lib/nanoc/core/compilation_stages/calculate_checksums.rb +2 -0
- data/lib/nanoc/core/compilation_stages/cleanup.rb +8 -2
- data/lib/nanoc/core/compilation_stages/compile_reps.rb +78 -36
- data/lib/nanoc/core/compilation_stages/determine_outdatedness.rb +2 -0
- data/lib/nanoc/core/compilation_stages/forget_outdated_dependencies.rb +5 -1
- data/lib/nanoc/core/compilation_stages/load_stores.rb +6 -1
- data/lib/nanoc/core/compilation_stages/postprocess.rb +2 -0
- data/lib/nanoc/core/compilation_stages/preprocess.rb +12 -3
- data/lib/nanoc/core/compilation_stages/prune.rb +6 -1
- data/lib/nanoc/core/compilation_stages/store_post_compilation_state.rb +2 -0
- data/lib/nanoc/core/compilation_stages/store_pre_compilation_state.rb +6 -1
- data/lib/nanoc/core/compiled_content_cache.rb +7 -2
- data/lib/nanoc/core/compiled_content_repo.rb +13 -5
- data/lib/nanoc/core/compiler.rb +12 -3
- data/lib/nanoc/core/compiler_loader.rb +13 -4
- data/lib/nanoc/core/config_loader.rb +14 -4
- data/lib/nanoc/core/configuration.rb +36 -15
- data/lib/nanoc/core/content.rb +5 -1
- data/lib/nanoc/core/context.rb +4 -5
- data/lib/nanoc/core/contracts_support.rb +26 -8
- data/lib/nanoc/core/core_ext/hash.rb +12 -2
- data/lib/nanoc/core/data_source.rb +22 -6
- data/lib/nanoc/core/dependency.rb +8 -2
- data/lib/nanoc/core/dependency_props.rb +27 -8
- data/lib/nanoc/core/dependency_store.rb +55 -22
- data/lib/nanoc/core/dependency_tracker.rb +20 -4
- data/lib/nanoc/core/directed_graph.rb +27 -64
- data/lib/nanoc/core/document.rb +4 -1
- data/lib/nanoc/core/errors.rb +45 -12
- data/lib/nanoc/core/executor.rb +26 -9
- data/lib/nanoc/core/feature.rb +2 -1
- data/lib/nanoc/core/filter.rb +27 -11
- data/lib/nanoc/core/identifiable_collection.rb +2 -1
- data/lib/nanoc/core/identifier.rb +23 -8
- data/lib/nanoc/core/in_memory_data_source.rb +3 -1
- data/lib/nanoc/core/item.rb +1 -1
- data/lib/nanoc/core/item_collection.rb +2 -2
- data/lib/nanoc/core/item_rep.rb +1 -1
- data/lib/nanoc/core/item_rep_builder.rb +14 -5
- data/lib/nanoc/core/item_rep_router.rb +27 -13
- data/lib/nanoc/core/item_rep_writer.rb +28 -5
- data/lib/nanoc/core/layout.rb +1 -1
- data/lib/nanoc/core/layout_collection.rb +2 -2
- data/lib/nanoc/core/mutable_document_view_mixin.rb +3 -6
- data/lib/nanoc/core/outdatedness_checker.rb +170 -95
- data/lib/nanoc/core/outdatedness_reasons.rb +45 -16
- data/lib/nanoc/core/outdatedness_rules/attributes_modified.rb +24 -10
- data/lib/nanoc/core/outdatedness_rules/item_added.rb +9 -4
- data/lib/nanoc/core/outdatedness_rules/layout_added.rb +9 -4
- data/lib/nanoc/core/outdatedness_rules/not_written.rb +7 -2
- data/lib/nanoc/core/outdatedness_rules/rules_modified.rb +14 -6
- data/lib/nanoc/core/outdatedness_rules/uses_always_outdated_filter.rb +1 -1
- data/lib/nanoc/core/outdatedness_store.rb +7 -1
- data/lib/nanoc/core/pattern.rb +4 -1
- data/lib/nanoc/core/prefixed_data_source.rb +6 -2
- data/lib/nanoc/core/processing_actions/filter.rb +2 -0
- data/lib/nanoc/core/processing_actions/layout.rb +2 -0
- data/lib/nanoc/core/processing_actions/snapshot.rb +12 -3
- data/lib/nanoc/core/pruner.rb +11 -3
- data/lib/nanoc/core/regexp_pattern.rb +1 -1
- data/lib/nanoc/core/site.rb +10 -4
- data/lib/nanoc/core/site_loader.rb +25 -17
- data/lib/nanoc/core/store.rb +33 -6
- data/lib/nanoc/core/string_pattern.rb +1 -1
- data/lib/nanoc/core/textual_compiled_content_cache.rb +60 -5
- data/lib/nanoc/core/textual_content.rb +4 -1
- data/lib/nanoc/core/version.rb +1 -1
- data/lib/nanoc/core/view_context_for_compilation.rb +6 -2
- data/lib/nanoc/core/views/basic_item_rep_collection_view.rb +11 -4
- data/lib/nanoc/core/views/basic_item_rep_view.rb +9 -2
- data/lib/nanoc/core/views/basic_item_view.rb +17 -9
- data/lib/nanoc/core/views/compilation_item_rep_view.rb +12 -4
- data/lib/nanoc/core/views/compilation_item_view.rb +3 -1
- data/lib/nanoc/core/views/identifiable_collection_view.rb +17 -5
- data/lib/nanoc/core/views/mutable_item_collection_view.rb +5 -2
- data/lib/nanoc/core/views/mutable_layout_collection_view.rb +5 -2
- data/lib/nanoc/core/views/post_compile_item_view.rb +3 -1
- data/lib/nanoc/core.rb +4 -4
- metadata +3 -9
- data/lib/nanoc/core/compilation_phases/abstract.rb +0 -48
- data/lib/nanoc/core/compilation_phases/cache.rb +0 -28
- data/lib/nanoc/core/compilation_phases/mark_done.rb +0 -23
- data/lib/nanoc/core/compilation_phases/notify.rb +0 -22
- data/lib/nanoc/core/compilation_phases/recalculate.rb +0 -59
- 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
|
-
|
|
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
|
-
|
|
12
|
-
end
|
|
11
|
+
super("The #{value.class} cannot be stored inside an attribute. Store its identifier instead.")
|
|
13
12
|
|
|
14
|
-
|
|
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[
|
|
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(
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
109
|
-
|
|
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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
129
|
-
|
|
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
|
-
|
|
132
|
-
|
|
133
|
-
|
|
223
|
+
case raw_content_prop
|
|
224
|
+
when true
|
|
225
|
+
true
|
|
134
226
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
end
|
|
227
|
+
when Enumerable
|
|
228
|
+
patterns = raw_content_prop
|
|
229
|
+
identifiers = document_added_reason.identifiers
|
|
139
230
|
|
|
140
|
-
|
|
141
|
-
|
|
231
|
+
patterns.any? do |pat|
|
|
232
|
+
coerced_pattern = Nanoc::Core::Pattern.from(pat)
|
|
142
233
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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.
|
|
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
|
|
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
|
|
32
|
-
|
|
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
|
|
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
|
|
41
|
-
|
|
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
|
|
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
|
|
50
|
-
|
|
51
|
-
|
|
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
|
|
56
|
-
|
|
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
|
|
65
|
-
|
|
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
|
|
74
|
-
|
|
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[
|
|
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,
|
|
16
|
-
when Nanoc::Core::Item,
|
|
17
|
-
|
|
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 =
|
|
31
|
+
old_checksums = boc.checksum_store.attributes_checksum_for(obj)
|
|
22
32
|
unless old_checksums
|
|
23
|
-
return Nanoc::Core::OutdatednessReasons::AttributesModified
|
|
33
|
+
return Nanoc::Core::OutdatednessReasons::AttributesModified
|
|
34
|
+
.new(true)
|
|
24
35
|
end
|
|
25
36
|
|
|
26
|
-
new_checksums =
|
|
37
|
+
new_checksums = boc.checksums.attributes_checksum_for(obj)
|
|
27
38
|
|
|
28
|
-
attributes =
|
|
29
|
-
|
|
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
|
|
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::
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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::
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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?
|
|
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(
|
|
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,
|
|
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,
|
|
17
|
-
if layouts.any? { |
|
|
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 =
|
|
28
|
-
|
|
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) ||
|
|
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
|
-
.
|
|
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(
|
|
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
|
data/lib/nanoc/core/pattern.rb
CHANGED
|
@@ -17,7 +17,10 @@ module Nanoc
|
|
|
17
17
|
when Symbol
|
|
18
18
|
Nanoc::Core::StringPattern.new(obj.to_s)
|
|
19
19
|
else
|
|
20
|
-
raise
|
|
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
|
|