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