nanoc-core 4.12.9 → 4.12.11
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 -4
- data/lib/nanoc/core/action_sequence_builder.rb +8 -10
- data/lib/nanoc/core/basic_item_view.rb +1 -1
- data/lib/nanoc/core/basic_outdatedness_checker.rb +135 -0
- data/lib/nanoc/core/checksum_collection.rb +3 -1
- data/lib/nanoc/core/checksum_store.rb +11 -1
- data/lib/nanoc/core/compilation_stages/determine_outdatedness.rb +6 -1
- data/lib/nanoc/core/compilation_stages/load_stores.rb +5 -12
- data/lib/nanoc/core/configuration.rb +15 -0
- data/lib/nanoc/core/dependency_props.rb +2 -2
- data/lib/nanoc/core/dependency_store.rb +15 -13
- data/lib/nanoc/core/document.rb +5 -1
- data/lib/nanoc/core/executor.rb +2 -1
- data/lib/nanoc/core/identifiable_collection.rb +16 -33
- data/lib/nanoc/core/identifiable_collection_view.rb +54 -10
- data/lib/nanoc/core/item.rb +1 -1
- data/lib/nanoc/core/item_collection.rb +0 -6
- data/lib/nanoc/core/item_rep.rb +18 -0
- data/lib/nanoc/core/item_rep_builder.rb +4 -4
- data/lib/nanoc/core/item_rep_selector.rb +69 -17
- data/lib/nanoc/core/layout.rb +1 -1
- data/lib/nanoc/core/layout_collection.rb +0 -6
- data/lib/nanoc/core/mutable_document_view_mixin.rb +16 -7
- data/lib/nanoc/core/outdatedness_checker.rb +57 -123
- data/lib/nanoc/core/outdatedness_rule.rb +31 -3
- data/lib/nanoc/core/outdatedness_rules/attributes_modified.rb +6 -6
- data/lib/nanoc/core/outdatedness_rules/code_snippets_modified.rb +6 -6
- data/lib/nanoc/core/outdatedness_rules/content_modified.rb +3 -3
- data/lib/nanoc/core/outdatedness_rules/item_added.rb +3 -3
- data/lib/nanoc/core/outdatedness_rules/layout_added.rb +3 -3
- data/lib/nanoc/core/outdatedness_rules/not_written.rb +9 -9
- data/lib/nanoc/core/outdatedness_rules/rules_modified.rb +12 -10
- data/lib/nanoc/core/outdatedness_rules/uses_always_outdated_filter.rb +2 -2
- data/lib/nanoc/core/outdatedness_status.rb +6 -1
- data/lib/nanoc/core/store.rb +56 -23
- data/lib/nanoc/core/version.rb +1 -1
- data/lib/nanoc/core.rb +8 -0
- metadata +4 -3
@@ -8,23 +8,62 @@ module Nanoc
|
|
8
8
|
@reps = reps
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
# An iterator (FIFO) over an array, with ability to ignore certain
|
12
|
+
# elements.
|
13
|
+
class ItemRepIgnorableIterator
|
14
|
+
def initialize(array)
|
15
|
+
@array = array.dup
|
16
|
+
end
|
17
|
+
|
18
|
+
def next_ignoring(ignored)
|
19
|
+
elem = @array.shift
|
20
|
+
elem = @array.shift while ignored.include?(elem)
|
21
|
+
elem
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# A priority queue that tracks dependencies and can detect circular
|
26
|
+
# dependencies.
|
27
|
+
class ItemRepPriorityQueue
|
12
28
|
def initialize(reps)
|
13
|
-
|
29
|
+
# Prio A: most important; prio C: least important.
|
30
|
+
@prio_a = []
|
31
|
+
@prio_b = ItemRepIgnorableIterator.new(reps)
|
32
|
+
@prio_c = []
|
33
|
+
|
34
|
+
# Stack of things that depend on each other. This is used for
|
35
|
+
# detecting and reporting circular dependencies.
|
14
36
|
@stack = []
|
37
|
+
|
38
|
+
# List of reps that we’ve already seen. Reps from `reps` will end up
|
39
|
+
# in here. Reps can end up in here even *before* they come from
|
40
|
+
# `reps`, when they are part of a dependency.
|
41
|
+
@seen = Set.new
|
15
42
|
end
|
16
43
|
|
17
44
|
def next
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@
|
22
|
-
|
23
|
-
@stack.push(rep)
|
24
|
-
end
|
25
|
-
else
|
26
|
-
nil
|
45
|
+
# Read prio A
|
46
|
+
@this = @prio_a.pop
|
47
|
+
if @this
|
48
|
+
@stack.push(@this)
|
49
|
+
return @this
|
27
50
|
end
|
51
|
+
|
52
|
+
# Read prio B
|
53
|
+
@this = @prio_b.next_ignoring(@seen)
|
54
|
+
if @this
|
55
|
+
@stack.push(@this)
|
56
|
+
return @this
|
57
|
+
end
|
58
|
+
|
59
|
+
# Read prio C
|
60
|
+
@this = @prio_c.pop
|
61
|
+
if @this
|
62
|
+
@stack.push(@this)
|
63
|
+
return @this
|
64
|
+
end
|
65
|
+
|
66
|
+
nil
|
28
67
|
end
|
29
68
|
|
30
69
|
def mark_ok
|
@@ -36,26 +75,39 @@ module Nanoc
|
|
36
75
|
raise Nanoc::Core::Errors::DependencyCycle.new(@stack + [dep])
|
37
76
|
end
|
38
77
|
|
39
|
-
|
40
|
-
|
78
|
+
# `@this` depends on `dep`, so `dep` has to be compiled first. Thus,
|
79
|
+
# move `@this` into priority C, and `dep` into priority A.
|
80
|
+
|
81
|
+
# Put `@this` (item rep that needs `dep` to be compiled first) into
|
82
|
+
# priority C (lowest prio).
|
83
|
+
@prio_c.push(@this)
|
84
|
+
|
85
|
+
# Put `dep` (item rep that needs to be compiled first, before
|
86
|
+
# `@this`) into priority A (highest prio).
|
87
|
+
@prio_a.push(dep)
|
88
|
+
|
89
|
+
# Remember that we’ve prioritised `dep`. This particular element will
|
90
|
+
# come from @prio_b at some point in the future, so we’ll have to skip
|
91
|
+
# it then.
|
92
|
+
@seen << dep
|
41
93
|
end
|
42
94
|
end
|
43
95
|
|
44
96
|
def each
|
45
|
-
|
97
|
+
pq = ItemRepPriorityQueue.new(@reps)
|
46
98
|
|
47
99
|
loop do
|
48
|
-
rep =
|
100
|
+
rep = pq.next
|
49
101
|
break if rep.nil?
|
50
102
|
|
51
103
|
begin
|
52
104
|
yield(rep)
|
53
|
-
|
105
|
+
pq.mark_ok
|
54
106
|
rescue => e
|
55
107
|
actual_error = e.is_a?(Nanoc::Core::Errors::CompilationError) ? e.unwrap : e
|
56
108
|
|
57
109
|
if actual_error.is_a?(Nanoc::Core::Errors::UnmetDependency)
|
58
|
-
|
110
|
+
pq.mark_failed(actual_error.rep)
|
59
111
|
else
|
60
112
|
raise(e)
|
61
113
|
end
|
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
|
@@ -6,92 +6,6 @@ module Nanoc
|
|
6
6
|
#
|
7
7
|
# @api private
|
8
8
|
class OutdatednessChecker
|
9
|
-
class Basic
|
10
|
-
include Nanoc::Core::ContractsSupport
|
11
|
-
|
12
|
-
Rules = Nanoc::Core::OutdatednessRules
|
13
|
-
|
14
|
-
RULES_FOR_ITEM_REP =
|
15
|
-
[
|
16
|
-
Rules::ItemAdded,
|
17
|
-
Rules::RulesModified,
|
18
|
-
Rules::ContentModified,
|
19
|
-
Rules::AttributesModified,
|
20
|
-
Rules::NotWritten,
|
21
|
-
Rules::CodeSnippetsModified,
|
22
|
-
Rules::UsesAlwaysOutdatedFilter,
|
23
|
-
].freeze
|
24
|
-
|
25
|
-
RULES_FOR_LAYOUT =
|
26
|
-
[
|
27
|
-
Rules::LayoutAdded,
|
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
|
-
C_OBJ_MAYBE_REP = C::Or[Nanoc::Core::Item, Nanoc::Core::ItemRep, Nanoc::Core::Configuration, Nanoc::Core::Layout, Nanoc::Core::ItemCollection, Nanoc::Core::LayoutCollection]
|
40
|
-
|
41
|
-
contract C::KeywordArgs[outdatedness_checker: OutdatednessChecker, reps: Nanoc::Core::ItemRepRepo] => C::Any
|
42
|
-
def initialize(outdatedness_checker:, reps:)
|
43
|
-
@outdatedness_checker = outdatedness_checker
|
44
|
-
@reps = reps
|
45
|
-
|
46
|
-
# Memoize
|
47
|
-
@_outdatedness_status_for = {}
|
48
|
-
end
|
49
|
-
|
50
|
-
contract C_OBJ_MAYBE_REP => C::Maybe[Nanoc::Core::OutdatednessStatus]
|
51
|
-
def outdatedness_status_for(obj)
|
52
|
-
@_outdatedness_status_for[obj] ||=
|
53
|
-
case obj
|
54
|
-
when Nanoc::Core::ItemRep
|
55
|
-
apply_rules(RULES_FOR_ITEM_REP, obj)
|
56
|
-
when Nanoc::Core::Item
|
57
|
-
apply_rules_multi(RULES_FOR_ITEM_REP, @reps[obj])
|
58
|
-
when Nanoc::Core::Layout
|
59
|
-
apply_rules(RULES_FOR_LAYOUT, obj)
|
60
|
-
when Nanoc::Core::Configuration
|
61
|
-
apply_rules(RULES_FOR_CONFIG, obj)
|
62
|
-
when Nanoc::Core::ItemCollection, Nanoc::Core::LayoutCollection
|
63
|
-
# Collections are never outdated. Objects inside them might be,
|
64
|
-
# however.
|
65
|
-
apply_rules([], obj)
|
66
|
-
else
|
67
|
-
raise Nanoc::Core::Errors::InternalInconsistency, "do not know how to check outdatedness of #{obj.inspect}"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
private
|
72
|
-
|
73
|
-
contract C::ArrayOf[Class], C_OBJ_MAYBE_REP, Nanoc::Core::OutdatednessStatus => C::Maybe[Nanoc::Core::OutdatednessStatus]
|
74
|
-
def apply_rules(rules, obj, status = Nanoc::Core::OutdatednessStatus.new)
|
75
|
-
rules.inject(status) do |acc, rule|
|
76
|
-
if acc.useful_to_apply?(rule)
|
77
|
-
reason = rule.instance.call(obj, @outdatedness_checker)
|
78
|
-
if reason
|
79
|
-
acc.update(reason)
|
80
|
-
else
|
81
|
-
acc
|
82
|
-
end
|
83
|
-
else
|
84
|
-
acc
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
contract C::ArrayOf[Class], C::ArrayOf[C_OBJ_MAYBE_REP] => C::Maybe[Nanoc::Core::OutdatednessStatus]
|
90
|
-
def apply_rules_multi(rules, objs)
|
91
|
-
objs.inject(Nanoc::Core::OutdatednessStatus.new) { |acc, elem| apply_rules(rules, elem, acc) }
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
9
|
include Nanoc::Core::ContractsSupport
|
96
10
|
|
97
11
|
attr_reader :checksum_store
|
@@ -107,7 +21,15 @@ module Nanoc
|
|
107
21
|
C_ITEM_OR_REP = C::Or[Nanoc::Core::Item, Nanoc::Core::ItemRep]
|
108
22
|
C_ACTION_SEQUENCES = C::HashOf[C_OBJ => Nanoc::Core::ActionSequence]
|
109
23
|
|
110
|
-
contract C::KeywordArgs[
|
24
|
+
contract C::KeywordArgs[
|
25
|
+
site: Nanoc::Core::Site,
|
26
|
+
checksum_store: Nanoc::Core::ChecksumStore,
|
27
|
+
checksums: Nanoc::Core::ChecksumCollection,
|
28
|
+
dependency_store: Nanoc::Core::DependencyStore,
|
29
|
+
action_sequence_store: Nanoc::Core::ActionSequenceStore,
|
30
|
+
action_sequences: C_ACTION_SEQUENCES,
|
31
|
+
reps: Nanoc::Core::ItemRepRepo
|
32
|
+
] => C::Any
|
111
33
|
def initialize(site:, checksum_store:, checksums:, dependency_store:, action_sequence_store:, action_sequences:, reps:)
|
112
34
|
@site = site
|
113
35
|
@checksum_store = checksum_store
|
@@ -120,20 +42,11 @@ module Nanoc
|
|
120
42
|
@objects_outdated_due_to_dependencies = {}
|
121
43
|
end
|
122
44
|
|
123
|
-
def action_sequence_for(rep)
|
124
|
-
@action_sequences.fetch(rep)
|
125
|
-
end
|
126
|
-
|
127
|
-
contract C_OBJ => C::Bool
|
128
|
-
def outdated?(obj)
|
129
|
-
outdatedness_reasons_for(obj).any?
|
130
|
-
end
|
131
|
-
|
132
45
|
contract C_OBJ => C::IterOf[Reasons::Generic]
|
133
46
|
def outdatedness_reasons_for(obj)
|
134
|
-
|
135
|
-
if
|
136
|
-
|
47
|
+
basic_reasons = basic_outdatedness_statuses.fetch(obj).reasons
|
48
|
+
if basic_reasons.any?
|
49
|
+
basic_reasons
|
137
50
|
elsif outdated_due_to_dependencies?(obj)
|
138
51
|
[Reasons::DependenciesOutdated]
|
139
52
|
else
|
@@ -143,9 +56,28 @@ module Nanoc
|
|
143
56
|
|
144
57
|
private
|
145
58
|
|
146
|
-
|
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)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
contract C::None => BasicOutdatednessChecker
|
147
71
|
def basic
|
148
|
-
@_basic ||=
|
72
|
+
@_basic ||= BasicOutdatednessChecker.new(
|
73
|
+
site: @site,
|
74
|
+
checksum_store: @checksum_store,
|
75
|
+
checksums: @checksums,
|
76
|
+
dependency_store: @dependency_store,
|
77
|
+
action_sequence_store: @action_sequence_store,
|
78
|
+
action_sequences: @action_sequences,
|
79
|
+
reps: @reps,
|
80
|
+
)
|
149
81
|
end
|
150
82
|
|
151
83
|
contract C_OBJ, Hamster::Set => C::Bool
|
@@ -191,12 +123,12 @@ module Nanoc
|
|
191
123
|
raw_content_prop_causes_outdatedness?(all_objects, dependency.props.raw_content) ||
|
192
124
|
attributes_prop_causes_outdatedness?(all_objects, dependency.props.attributes)
|
193
125
|
else
|
194
|
-
status =
|
126
|
+
status = basic_outdatedness_statuses.fetch(dependency.from)
|
195
127
|
|
196
128
|
active = status.props.active & dependency.props.active
|
197
129
|
active.delete(:attributes) if attributes_unaffected?(status, dependency)
|
198
130
|
|
199
|
-
active.
|
131
|
+
!active.empty?
|
200
132
|
end
|
201
133
|
end
|
202
134
|
|
@@ -217,8 +149,7 @@ module Nanoc
|
|
217
149
|
when Enumerable
|
218
150
|
# If the `raw_content` dependency prop is a collection, then this
|
219
151
|
# is a dependency on specific objects, given by the patterns.
|
220
|
-
|
221
|
-
patterns.flat_map { |pat| objects.select { |obj| pat.match?(obj.identifier) } }
|
152
|
+
raw_content_prop.flat_map { |pat| objects.find_all(pat) }
|
222
153
|
else
|
223
154
|
raise(
|
224
155
|
Nanoc::Core::Errors::InternalInconsistency,
|
@@ -236,7 +167,7 @@ module Nanoc
|
|
236
167
|
# accessed), then another dependency will exist that will cause
|
237
168
|
# outdatedness.
|
238
169
|
matching_objects.any? do |obj|
|
239
|
-
status =
|
170
|
+
status = basic_outdatedness_statuses.fetch(obj)
|
240
171
|
status.reasons.any? { |r| Nanoc::Core::OutdatednessReasons::DocumentAdded == r }
|
241
172
|
end
|
242
173
|
end
|
@@ -265,27 +196,30 @@ module Nanoc
|
|
265
196
|
objects.any? do |object|
|
266
197
|
# Find old and new attribute checksums for the object
|
267
198
|
old_object_checksums = checksum_store.attributes_checksum_for(object)
|
268
|
-
next false unless old_object_checksums
|
269
|
-
|
270
199
|
new_object_checksums = checksums.attributes_checksum_for(object)
|
271
200
|
|
272
|
-
# Ignore any attribute not mentioned in the dependency
|
273
|
-
old_object_checksums = old_object_checksums.select { |k, _v| dep_checksums.key?(k) }
|
274
|
-
new_object_checksums = new_object_checksums.select { |k, _v| dep_checksums.key?(k) }
|
275
|
-
|
276
201
|
dep_checksums.any? do |key, dep_value|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
202
|
+
if old_object_checksums
|
203
|
+
# Get old and new checksum for this particular attribute
|
204
|
+
old_value = old_object_checksums[key]
|
205
|
+
new_value = new_object_checksums[key]
|
206
|
+
|
207
|
+
# If the old and new checksums are identical, then the attribute
|
208
|
+
# is unchanged and can’t cause outdatedness.
|
209
|
+
next false unless old_value != new_value
|
210
|
+
|
211
|
+
# We already know that the old value and new value are different.
|
212
|
+
# This attribute will cause outdatedness if either of those
|
213
|
+
# checksums is identical to the one in the prop.
|
214
|
+
old_value == dep_value || new_value == dep_value
|
215
|
+
else
|
216
|
+
# We don’t have the previous checksums, which means this item is
|
217
|
+
# newly added. In this case, we can compare the value in the
|
218
|
+
# dependency with the new checksum.
|
287
219
|
|
288
|
-
|
220
|
+
new_value = new_object_checksums[key]
|
221
|
+
new_value == dep_value
|
222
|
+
end
|
289
223
|
end
|
290
224
|
end
|
291
225
|
end
|
@@ -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
|
@@ -8,22 +8,22 @@ 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::
|
12
|
-
def apply(obj,
|
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]
|
12
|
+
def apply(obj, basic_outdatedness_checker)
|
13
13
|
case obj
|
14
14
|
when Nanoc::Core::ItemRep
|
15
|
-
apply(obj.item,
|
15
|
+
apply(obj.item, basic_outdatedness_checker)
|
16
16
|
when Nanoc::Core::Item, Nanoc::Core::Layout, Nanoc::Core::Configuration
|
17
|
-
if
|
17
|
+
if basic_outdatedness_checker.checksum_store[obj] == basic_outdatedness_checker.checksums.checksum_for(obj)
|
18
18
|
return nil
|
19
19
|
end
|
20
20
|
|
21
|
-
old_checksums =
|
21
|
+
old_checksums = basic_outdatedness_checker.checksum_store.attributes_checksum_for(obj)
|
22
22
|
unless old_checksums
|
23
23
|
return Nanoc::Core::OutdatednessReasons::AttributesModified.new(true)
|
24
24
|
end
|
25
25
|
|
26
|
-
new_checksums =
|
26
|
+
new_checksums = basic_outdatedness_checker.checksums.attributes_checksum_for(obj)
|
27
27
|
|
28
28
|
attributes = Set.new(old_checksums.keys) + Set.new(new_checksums.keys)
|
29
29
|
changed_attributes = attributes.reject { |a| old_checksums[a] == new_checksums[a] }
|
@@ -10,18 +10,18 @@ module Nanoc
|
|
10
10
|
|
11
11
|
affects_props :raw_content, :attributes, :compiled_content, :path
|
12
12
|
|
13
|
-
def apply(_obj,
|
14
|
-
if any_snippets_modified?(
|
13
|
+
def apply(_obj, basic_outdatedness_checker)
|
14
|
+
if any_snippets_modified?(basic_outdatedness_checker)
|
15
15
|
Nanoc::Core::OutdatednessReasons::CodeSnippetsModified
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
20
20
|
|
21
|
-
def any_snippets_modified?(
|
22
|
-
|
23
|
-
ch_old =
|
24
|
-
ch_new =
|
21
|
+
def any_snippets_modified?(basic_outdatedness_checker)
|
22
|
+
basic_outdatedness_checker.site.code_snippets.any? do |cs|
|
23
|
+
ch_old = basic_outdatedness_checker.checksum_store[cs]
|
24
|
+
ch_new = basic_outdatedness_checker.checksums.checksum_for(cs)
|
25
25
|
ch_old != ch_new
|
26
26
|
end
|
27
27
|
end
|
@@ -6,11 +6,11 @@ module Nanoc
|
|
6
6
|
class ContentModified < Nanoc::Core::OutdatednessRule
|
7
7
|
affects_props :raw_content, :compiled_content
|
8
8
|
|
9
|
-
def apply(obj,
|
9
|
+
def apply(obj, basic_outdatedness_checker)
|
10
10
|
obj = obj.item if obj.is_a?(Nanoc::Core::ItemRep)
|
11
11
|
|
12
|
-
ch_old =
|
13
|
-
ch_new =
|
12
|
+
ch_old = basic_outdatedness_checker.checksum_store.content_checksum_for(obj)
|
13
|
+
ch_new = basic_outdatedness_checker.checksums.content_checksum_for(obj)
|
14
14
|
if ch_old != ch_new
|
15
15
|
Nanoc::Core::OutdatednessReasons::ContentModified
|
16
16
|
end
|
@@ -6,9 +6,9 @@ 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::
|
10
|
-
def apply(obj,
|
11
|
-
if
|
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
12
|
Nanoc::Core::OutdatednessReasons::DocumentAdded
|
13
13
|
end
|
14
14
|
end
|
@@ -6,9 +6,9 @@ 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::
|
10
|
-
def apply(obj,
|
11
|
-
if
|
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
12
|
Nanoc::Core::OutdatednessReasons::DocumentAdded
|
13
13
|
end
|
14
14
|
end
|
@@ -6,30 +6,30 @@ module Nanoc
|
|
6
6
|
class NotWritten < Nanoc::Core::OutdatednessRule
|
7
7
|
affects_props :raw_content, :attributes, :compiled_content, :path
|
8
8
|
|
9
|
-
def apply(obj,
|
10
|
-
if obj.raw_paths.values.flatten.compact.any? { |fn| !exist?(fn,
|
9
|
+
def apply(obj, basic_outdatedness_checker)
|
10
|
+
if obj.raw_paths.values.flatten.compact.any? { |fn| !exist?(fn, basic_outdatedness_checker) }
|
11
11
|
Nanoc::Core::OutdatednessReasons::NotWritten
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
15
|
private
|
16
16
|
|
17
|
-
def exist?(fn,
|
18
|
-
all(
|
17
|
+
def exist?(fn, basic_outdatedness_checker)
|
18
|
+
all(basic_outdatedness_checker).include?(fn)
|
19
19
|
end
|
20
20
|
|
21
|
-
def all(
|
21
|
+
def all(basic_outdatedness_checker)
|
22
22
|
# NOTE: Cached per outdatedness checker, so that unrelated invocations
|
23
23
|
# later on don’t reuse an old cache.
|
24
24
|
|
25
25
|
@all ||= {}
|
26
|
-
@all[
|
27
|
-
Dir.glob("#{site_root(
|
26
|
+
@all[basic_outdatedness_checker] ||= Set.new(
|
27
|
+
Dir.glob("#{site_root(basic_outdatedness_checker)}/**/*", File::FNM_DOTMATCH),
|
28
28
|
)
|
29
29
|
end
|
30
30
|
|
31
|
-
def site_root(
|
32
|
-
|
31
|
+
def site_root(basic_outdatedness_checker)
|
32
|
+
basic_outdatedness_checker.site.config.output_dir
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -6,15 +6,15 @@ module Nanoc
|
|
6
6
|
class RulesModified < Nanoc::Core::OutdatednessRule
|
7
7
|
affects_props :compiled_content, :path
|
8
8
|
|
9
|
-
def apply(obj,
|
9
|
+
def apply(obj, basic_outdatedness_checker)
|
10
10
|
# Check rules of obj itself
|
11
|
-
if rules_modified?(obj,
|
11
|
+
if rules_modified?(obj, basic_outdatedness_checker)
|
12
12
|
return Nanoc::Core::OutdatednessReasons::RulesModified
|
13
13
|
end
|
14
14
|
|
15
15
|
# Check rules of layouts used by obj
|
16
|
-
layouts = layouts_touched_by(obj,
|
17
|
-
if layouts.any? { |layout| rules_modified?(layout,
|
16
|
+
layouts = layouts_touched_by(obj, basic_outdatedness_checker)
|
17
|
+
if layouts.any? { |layout| rules_modified?(layout, basic_outdatedness_checker) }
|
18
18
|
return Nanoc::Core::OutdatednessReasons::RulesModified
|
19
19
|
end
|
20
20
|
|
@@ -23,20 +23,22 @@ module Nanoc
|
|
23
23
|
|
24
24
|
private
|
25
25
|
|
26
|
-
def rules_modified?(obj,
|
27
|
-
seq_old =
|
28
|
-
seq_new =
|
26
|
+
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
29
|
|
30
30
|
!seq_old.eql?(seq_new)
|
31
31
|
end
|
32
32
|
|
33
|
-
def layouts_touched_by(obj,
|
34
|
-
actions =
|
33
|
+
def layouts_touched_by(obj, basic_outdatedness_checker)
|
34
|
+
actions = basic_outdatedness_checker.action_sequence_store[obj]
|
35
35
|
layout_actions = actions.select { |a| a.first == :layout }
|
36
36
|
|
37
|
+
layouts = basic_outdatedness_checker.site.layouts
|
38
|
+
|
37
39
|
layout_actions.map do |layout_action|
|
38
40
|
layout_pattern = layout_action[1]
|
39
|
-
|
41
|
+
layouts.object_with_identifier(layout_pattern) || layouts.object_matching_glob(layout_pattern)
|
40
42
|
end.compact
|
41
43
|
end
|
42
44
|
end
|
@@ -6,8 +6,8 @@ module Nanoc
|
|
6
6
|
class UsesAlwaysOutdatedFilter < Nanoc::Core::OutdatednessRule
|
7
7
|
affects_props :raw_content, :attributes, :path
|
8
8
|
|
9
|
-
def apply(obj,
|
10
|
-
seq =
|
9
|
+
def apply(obj, basic_outdatedness_checker)
|
10
|
+
seq = basic_outdatedness_checker.action_sequence_for(obj)
|
11
11
|
if any_always_outdated?(seq)
|
12
12
|
Nanoc::Core::OutdatednessReasons::UsesAlwaysOutdatedFilter
|
13
13
|
end
|