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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7fc026255728ddb8de8c0756afdfbdc7548e47938d9c4fb464023c0811ae4e2
|
4
|
+
data.tar.gz: a8531e9c3920f81c9caa88996b1f195eedec21ef392cda04cd2fcf76c0f83106
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f819fe95a0d25831e51ba4ce360ca76921c01517402bf67d3407d369b1fc8c7f05a7262fe0df1dbfd03e3c3f12d72281d818db19746f294f135e8b017a21a07d
|
7
|
+
data.tar.gz: c0de0aef8f83c0a7723d755bf804a25f3ca574e308b54b36cac6e0a91ac5b0b2c4658635cd899d18fdc830d51250a151cbb23d69dfdd4b4abd1cde5b12c96a2c
|
@@ -7,11 +7,9 @@ module Nanoc
|
|
7
7
|
include Enumerable
|
8
8
|
prepend MemoWise
|
9
9
|
|
10
|
-
attr_reader :item_rep
|
11
10
|
attr_reader :actions
|
12
11
|
|
13
|
-
def initialize(
|
14
|
-
@item_rep = item_rep
|
12
|
+
def initialize(actions: [])
|
15
13
|
@actions = actions
|
16
14
|
end
|
17
15
|
|
@@ -54,7 +52,6 @@ module Nanoc
|
|
54
52
|
# contract C::Func[Nanoc::Core::ProcessingAction => C::Any] => self
|
55
53
|
def map(&block)
|
56
54
|
self.class.new(
|
57
|
-
@item_rep,
|
58
55
|
actions: @actions.map(&block),
|
59
56
|
)
|
60
57
|
end
|
@@ -15,14 +15,13 @@ module Nanoc
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def self.build
|
19
|
-
builder = new
|
18
|
+
def self.build
|
19
|
+
builder = new
|
20
20
|
yield(builder)
|
21
21
|
builder.action_sequence
|
22
22
|
end
|
23
23
|
|
24
|
-
def initialize
|
25
|
-
@item_rep = item_rep
|
24
|
+
def initialize
|
26
25
|
@actions = []
|
27
26
|
end
|
28
27
|
|
@@ -38,24 +37,23 @@ module Nanoc
|
|
38
37
|
self
|
39
38
|
end
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
will_add_snapshot(snapshot_name)
|
40
|
+
def add_snapshot(snapshot_name, path, rep)
|
41
|
+
will_add_snapshot(snapshot_name, rep)
|
44
42
|
@actions << Nanoc::Core::ProcessingActions::Snapshot.new([snapshot_name], path ? [path] : [])
|
45
43
|
self
|
46
44
|
end
|
47
45
|
|
48
46
|
contract C::None => Nanoc::Core::ActionSequence
|
49
47
|
def action_sequence
|
50
|
-
Nanoc::Core::ActionSequence.new(
|
48
|
+
Nanoc::Core::ActionSequence.new(actions: @actions)
|
51
49
|
end
|
52
50
|
|
53
51
|
private
|
54
52
|
|
55
|
-
def will_add_snapshot(name)
|
53
|
+
def will_add_snapshot(name, rep)
|
56
54
|
@_snapshot_names ||= Set.new
|
57
55
|
if @_snapshot_names.include?(name)
|
58
|
-
raise CannotCreateMultipleSnapshotsWithSameNameError.new(
|
56
|
+
raise CannotCreateMultipleSnapshotsWithSameNameError.new(rep, name)
|
59
57
|
else
|
60
58
|
@_snapshot_names << name
|
61
59
|
end
|
@@ -34,7 +34,7 @@ module Nanoc
|
|
34
34
|
parent_identifier = '/' + _unwrap.identifier.components[0..-2].join('/') + '/'
|
35
35
|
parent_identifier = '/' if parent_identifier == '//'
|
36
36
|
|
37
|
-
parent = @context.items
|
37
|
+
parent = @context.items.object_with_identifier(parent_identifier)
|
38
38
|
|
39
39
|
parent && self.class.new(parent, @context)
|
40
40
|
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Core
|
5
|
+
class BasicOutdatednessChecker
|
6
|
+
include Nanoc::Core::ContractsSupport
|
7
|
+
|
8
|
+
attr_reader :site
|
9
|
+
attr_reader :checksum_store
|
10
|
+
attr_reader :checksums
|
11
|
+
attr_reader :dependency_store
|
12
|
+
attr_reader :action_sequence_store
|
13
|
+
attr_reader :action_sequences
|
14
|
+
|
15
|
+
Rules = Nanoc::Core::OutdatednessRules
|
16
|
+
|
17
|
+
RULES_FOR_ITEM_REP =
|
18
|
+
[
|
19
|
+
Rules::ItemAdded,
|
20
|
+
Rules::RulesModified,
|
21
|
+
Rules::ContentModified,
|
22
|
+
Rules::AttributesModified,
|
23
|
+
Rules::NotWritten,
|
24
|
+
Rules::CodeSnippetsModified,
|
25
|
+
Rules::UsesAlwaysOutdatedFilter,
|
26
|
+
].freeze
|
27
|
+
|
28
|
+
RULES_FOR_LAYOUT =
|
29
|
+
[
|
30
|
+
Rules::LayoutAdded,
|
31
|
+
Rules::RulesModified,
|
32
|
+
Rules::ContentModified,
|
33
|
+
Rules::AttributesModified,
|
34
|
+
Rules::UsesAlwaysOutdatedFilter,
|
35
|
+
].freeze
|
36
|
+
|
37
|
+
RULES_FOR_CONFIG =
|
38
|
+
[
|
39
|
+
Rules::AttributesModified,
|
40
|
+
].freeze
|
41
|
+
|
42
|
+
C_OBJ = C::Or[
|
43
|
+
Nanoc::Core::Item,
|
44
|
+
Nanoc::Core::ItemRep,
|
45
|
+
Nanoc::Core::Configuration,
|
46
|
+
Nanoc::Core::Layout,
|
47
|
+
Nanoc::Core::ItemCollection,
|
48
|
+
]
|
49
|
+
|
50
|
+
C_OBJ_MAYBE_REP = C::Or[
|
51
|
+
Nanoc::Core::Item,
|
52
|
+
Nanoc::Core::ItemRep,
|
53
|
+
Nanoc::Core::Configuration,
|
54
|
+
Nanoc::Core::Layout,
|
55
|
+
Nanoc::Core::ItemCollection,
|
56
|
+
Nanoc::Core::LayoutCollection,
|
57
|
+
]
|
58
|
+
|
59
|
+
C_ACTION_SEQUENCES = C::HashOf[C_OBJ => Nanoc::Core::ActionSequence]
|
60
|
+
|
61
|
+
contract C::KeywordArgs[
|
62
|
+
site: Nanoc::Core::Site,
|
63
|
+
checksum_store: Nanoc::Core::ChecksumStore,
|
64
|
+
checksums: Nanoc::Core::ChecksumCollection,
|
65
|
+
dependency_store: Nanoc::Core::DependencyStore,
|
66
|
+
action_sequence_store: Nanoc::Core::ActionSequenceStore,
|
67
|
+
action_sequences: C_ACTION_SEQUENCES,
|
68
|
+
reps: Nanoc::Core::ItemRepRepo,
|
69
|
+
] => C::Any
|
70
|
+
def initialize(site:, checksum_store:, checksums:, dependency_store:, action_sequence_store:, action_sequences:, reps:)
|
71
|
+
@reps = reps
|
72
|
+
@site = site
|
73
|
+
@checksum_store = checksum_store
|
74
|
+
@checksums = checksums
|
75
|
+
@dependency_store = dependency_store
|
76
|
+
@action_sequence_store = action_sequence_store
|
77
|
+
@action_sequences = action_sequences
|
78
|
+
|
79
|
+
# Memoize
|
80
|
+
@_outdatedness_status_for = {}
|
81
|
+
end
|
82
|
+
|
83
|
+
contract C_OBJ_MAYBE_REP => C::Maybe[Nanoc::Core::OutdatednessStatus]
|
84
|
+
def outdatedness_status_for(obj)
|
85
|
+
# TODO: remove memoization (no longer needed)
|
86
|
+
@_outdatedness_status_for[obj] ||=
|
87
|
+
case obj
|
88
|
+
when Nanoc::Core::ItemRep
|
89
|
+
apply_rules(RULES_FOR_ITEM_REP, obj)
|
90
|
+
when Nanoc::Core::Item
|
91
|
+
apply_rules_multi(RULES_FOR_ITEM_REP, @reps[obj])
|
92
|
+
when Nanoc::Core::Layout
|
93
|
+
apply_rules(RULES_FOR_LAYOUT, obj)
|
94
|
+
when Nanoc::Core::Configuration
|
95
|
+
apply_rules(RULES_FOR_CONFIG, obj)
|
96
|
+
when Nanoc::Core::ItemCollection, Nanoc::Core::LayoutCollection
|
97
|
+
# Collections are never outdated. Objects inside them might be,
|
98
|
+
# however.
|
99
|
+
apply_rules([], obj)
|
100
|
+
else
|
101
|
+
raise Nanoc::Core::Errors::InternalInconsistency, "do not know how to check outdatedness of #{obj.inspect}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def action_sequence_for(rep)
|
106
|
+
@action_sequences.fetch(rep)
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
contract C::ArrayOf[Class], C_OBJ_MAYBE_REP, Nanoc::Core::OutdatednessStatus => C::Maybe[Nanoc::Core::OutdatednessStatus]
|
112
|
+
def apply_rules(rules, obj, status = Nanoc::Core::OutdatednessStatus.new)
|
113
|
+
rules.inject(status) do |acc, rule|
|
114
|
+
if acc.useful_to_apply?(rule)
|
115
|
+
reason = rule.instance.call(obj, self)
|
116
|
+
if reason
|
117
|
+
acc.update(reason)
|
118
|
+
else
|
119
|
+
acc
|
120
|
+
end
|
121
|
+
else
|
122
|
+
acc
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
contract C::ArrayOf[Class], C::ArrayOf[C_OBJ_MAYBE_REP] => C::Maybe[Nanoc::Core::OutdatednessStatus]
|
128
|
+
def apply_rules_multi(rules, objs)
|
129
|
+
objs.inject(Nanoc::Core::OutdatednessStatus.new) do |acc, elem|
|
130
|
+
apply_rules(rules, elem, acc)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -9,6 +9,8 @@ module Nanoc
|
|
9
9
|
|
10
10
|
def initialize(checksums)
|
11
11
|
@checksums = checksums
|
12
|
+
|
13
|
+
@_attribute_checksums = {}
|
12
14
|
end
|
13
15
|
|
14
16
|
contract c_obj => C::Maybe[String]
|
@@ -23,7 +25,7 @@ module Nanoc
|
|
23
25
|
|
24
26
|
contract c_obj => C::Maybe[C::HashOf[Symbol, String]]
|
25
27
|
def attributes_checksum_for(obj)
|
26
|
-
@checksums[[obj.reference, :each_attribute]]
|
28
|
+
@_attribute_checksums[obj] ||= @checksums[[obj.reference, :each_attribute]]
|
27
29
|
end
|
28
30
|
|
29
31
|
def to_h
|
@@ -21,6 +21,8 @@ module Nanoc
|
|
21
21
|
@objects = objects
|
22
22
|
|
23
23
|
@checksums = {}
|
24
|
+
|
25
|
+
invalidate_memoization
|
24
26
|
end
|
25
27
|
|
26
28
|
contract c_obj => C::Maybe[String]
|
@@ -50,7 +52,7 @@ module Nanoc
|
|
50
52
|
|
51
53
|
contract c_obj => C::Maybe[C::HashOf[Symbol, String]]
|
52
54
|
def attributes_checksum_for(obj)
|
53
|
-
@checksums[[obj.reference, :each_attribute]]
|
55
|
+
@_attribute_checksums[obj] ||= @checksums[[obj.reference, :each_attribute]]
|
54
56
|
end
|
55
57
|
|
56
58
|
protected
|
@@ -60,6 +62,8 @@ module Nanoc
|
|
60
62
|
end
|
61
63
|
|
62
64
|
def data=(new_data)
|
65
|
+
invalidate_memoization
|
66
|
+
|
63
67
|
references = Set.new(@objects.map(&:reference))
|
64
68
|
|
65
69
|
@checksums = {}
|
@@ -69,6 +73,12 @@ module Nanoc
|
|
69
73
|
end
|
70
74
|
end
|
71
75
|
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def invalidate_memoization
|
80
|
+
@_attribute_checksums = {}
|
81
|
+
end
|
72
82
|
end
|
73
83
|
end
|
74
84
|
end
|
@@ -41,7 +41,12 @@ module Nanoc
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def outdated?(rep)
|
44
|
-
@outdatedness_store.include?(rep)
|
44
|
+
if @outdatedness_store.include?(rep)
|
45
|
+
# We determined previously that this rep is outdated.
|
46
|
+
true
|
47
|
+
else
|
48
|
+
!@outdatedness_checker.outdatedness_reasons_for(rep).empty?
|
49
|
+
end
|
45
50
|
end
|
46
51
|
end
|
47
52
|
end
|
@@ -16,18 +16,11 @@ module Nanoc
|
|
16
16
|
|
17
17
|
contract C::None => C::Any
|
18
18
|
def run
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
contract Nanoc::Core::Store => C::Any
|
27
|
-
def load_store(store)
|
28
|
-
Nanoc::Core::Instrumentor.call(:store_loaded, store.class) do
|
29
|
-
store.load
|
30
|
-
end
|
19
|
+
@checksum_store.load
|
20
|
+
@compiled_content_cache.load
|
21
|
+
@dependency_store.load
|
22
|
+
@action_sequence_store.load
|
23
|
+
@outdatedness_store.load
|
31
24
|
end
|
32
25
|
end
|
33
26
|
end
|
@@ -176,6 +176,21 @@ module Nanoc
|
|
176
176
|
"<#{self.class}>"
|
177
177
|
end
|
178
178
|
|
179
|
+
contract C::None => C::Num
|
180
|
+
def hash
|
181
|
+
[@dir, @env_name].hash
|
182
|
+
end
|
183
|
+
|
184
|
+
contract C::Any => C::Bool
|
185
|
+
def ==(other)
|
186
|
+
eql?(other)
|
187
|
+
end
|
188
|
+
|
189
|
+
contract C::Any => C::Bool
|
190
|
+
def eql?(other)
|
191
|
+
other.is_a?(self.class) && @dir == other.dir && @env_name == other.env_name
|
192
|
+
end
|
193
|
+
|
179
194
|
private
|
180
195
|
|
181
196
|
def make_absolute(path)
|
@@ -111,7 +111,7 @@ module Nanoc
|
|
111
111
|
def raw_content?
|
112
112
|
case @raw_content
|
113
113
|
when Set
|
114
|
-
|
114
|
+
!@raw_content.empty?
|
115
115
|
else
|
116
116
|
@raw_content
|
117
117
|
end
|
@@ -121,7 +121,7 @@ module Nanoc
|
|
121
121
|
def attributes?
|
122
122
|
case @attributes
|
123
123
|
when Set
|
124
|
-
|
124
|
+
!@attributes.empty?
|
125
125
|
else
|
126
126
|
@attributes
|
127
127
|
end
|
@@ -71,12 +71,7 @@ module Nanoc
|
|
71
71
|
Nanoc::Core::Dependency.new(
|
72
72
|
other_object,
|
73
73
|
object,
|
74
|
-
|
75
|
-
raw_content: props.fetch(:raw_content, false),
|
76
|
-
attributes: props.fetch(:attributes, false),
|
77
|
-
compiled_content: props.fetch(:compiled_content, false),
|
78
|
-
path: props.fetch(:path, false),
|
79
|
-
),
|
74
|
+
props,
|
80
75
|
)
|
81
76
|
end
|
82
77
|
end
|
@@ -192,15 +187,22 @@ module Nanoc
|
|
192
187
|
refs.map { |r| ref2obj(r) }
|
193
188
|
end
|
194
189
|
|
195
|
-
# TODO: Return not a Hash, but a DependencyProps instead
|
196
190
|
def props_for(from, to)
|
197
191
|
props = @graph.props_for(obj2ref(from), obj2ref(to))
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
192
|
+
return props if props
|
193
|
+
|
194
|
+
# This is for backwards compatibility, in case there are no dependency
|
195
|
+
# props available yet. Pretend everything is set to `true`; it’ll be
|
196
|
+
# recompiled and correct props will be available in the next run.
|
197
|
+
#
|
198
|
+
# NOTE: This isn’t covered by tests, yet. (Not trivial to test because
|
199
|
+
# it’s not a condition that can arise in the current Nanoc version.)
|
200
|
+
Nanoc::Core::DependencyProps.new(
|
201
|
+
raw_content: true,
|
202
|
+
attributes: true,
|
203
|
+
compiled_content: true,
|
204
|
+
path: true,
|
205
|
+
)
|
204
206
|
end
|
205
207
|
|
206
208
|
def data
|
data/lib/nanoc/core/document.rb
CHANGED
@@ -49,6 +49,10 @@ module Nanoc
|
|
49
49
|
@checksum_data = checksum_data
|
50
50
|
@content_checksum_data = content_checksum_data
|
51
51
|
@attributes_checksum_data = attributes_checksum_data
|
52
|
+
|
53
|
+
# Precalculate for performance
|
54
|
+
@hash = [self.class, identifier].hash
|
55
|
+
reference
|
52
56
|
end
|
53
57
|
|
54
58
|
# @return [Hash]
|
@@ -107,7 +111,7 @@ module Nanoc
|
|
107
111
|
|
108
112
|
contract C::None => C::Num
|
109
113
|
def hash
|
110
|
-
|
114
|
+
@hash
|
111
115
|
end
|
112
116
|
|
113
117
|
contract C::Any => C::Bool
|
data/lib/nanoc/core/executor.rb
CHANGED
@@ -90,10 +90,11 @@ module Nanoc
|
|
90
90
|
|
91
91
|
def find_layout(arg)
|
92
92
|
req_id = arg.__nanoc_cleaned_identifier
|
93
|
-
layout = layouts
|
93
|
+
layout = layouts.object_with_identifier(req_id)
|
94
94
|
return layout if layout
|
95
95
|
|
96
96
|
if use_globs?
|
97
|
+
# TODO: use object_matching_glob instead
|
97
98
|
pat = Nanoc::Core::Pattern.from(arg)
|
98
99
|
layout = layouts.find { |l| pat.match?(l.identifier) }
|
99
100
|
return layout if layout
|
@@ -37,15 +37,6 @@ module Nanoc
|
|
37
37
|
super
|
38
38
|
end
|
39
39
|
|
40
|
-
# contract C::Any => C::Maybe[C::RespondTo[:identifier]]
|
41
|
-
def [](arg)
|
42
|
-
if frozen?
|
43
|
-
get_memoized(arg)
|
44
|
-
else
|
45
|
-
get_unmemoized(arg)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
40
|
# contract C::Any => C::IterOf[C::RespondTo[:identifier]]
|
50
41
|
def find_all(arg)
|
51
42
|
if frozen?
|
@@ -75,7 +66,6 @@ module Nanoc
|
|
75
66
|
self.class.new(@config, @objects.reject(&block))
|
76
67
|
end
|
77
68
|
|
78
|
-
# contract C::Any => C::Maybe[C::RespondTo[:identifier]]
|
79
69
|
def object_with_identifier(identifier)
|
80
70
|
if frozen?
|
81
71
|
@mapping[identifier.to_s]
|
@@ -84,26 +74,26 @@ module Nanoc
|
|
84
74
|
end
|
85
75
|
end
|
86
76
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
def get_unmemoized(arg)
|
91
|
-
case arg
|
92
|
-
when Nanoc::Core::Identifier
|
93
|
-
object_with_identifier(arg)
|
94
|
-
when String
|
95
|
-
object_with_identifier(arg) || object_matching_glob(arg)
|
96
|
-
when Regexp
|
97
|
-
find { |i| i.identifier.to_s =~ arg }
|
77
|
+
def object_matching_glob(glob)
|
78
|
+
if frozen?
|
79
|
+
object_matching_glob_memoized(glob)
|
98
80
|
else
|
99
|
-
|
81
|
+
object_matching_glob_unmemoized(glob)
|
100
82
|
end
|
101
83
|
end
|
102
84
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
85
|
+
protected
|
86
|
+
|
87
|
+
def object_matching_glob_memoized(glob)
|
88
|
+
object_matching_glob_unmemoized(glob)
|
89
|
+
end
|
90
|
+
memo_wise :object_matching_glob_memoized
|
91
|
+
|
92
|
+
def object_matching_glob_unmemoized(glob)
|
93
|
+
if use_globs?
|
94
|
+
pat = Pattern.from(glob)
|
95
|
+
find { |i| pat.match?(i.identifier) }
|
96
|
+
end
|
107
97
|
end
|
108
98
|
|
109
99
|
# contract C::Any => C::IterOf[C::RespondTo[:identifier]]
|
@@ -118,13 +108,6 @@ module Nanoc
|
|
118
108
|
end
|
119
109
|
memo_wise :find_all_memoized
|
120
110
|
|
121
|
-
def object_matching_glob(glob)
|
122
|
-
if use_globs?
|
123
|
-
pat = Pattern.from(glob)
|
124
|
-
find { |i| pat.match?(i.identifier) }
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
111
|
def build_mapping
|
129
112
|
@mapping = {}
|
130
113
|
each do |object|
|
@@ -120,19 +120,63 @@ module Nanoc
|
|
120
120
|
#
|
121
121
|
# @return [#identifier] if an object was found
|
122
122
|
def [](arg)
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
123
|
+
# The argument to #[] fall in two categories: exact matches, and
|
124
|
+
# patterns. An example of an exact match is '/about.md', while an
|
125
|
+
# example of a pattern is '/about.*'.
|
126
|
+
#
|
127
|
+
# If a Nanoc::Core::Identifier is given, we know it will need to be an
|
128
|
+
# exact match. If a String is given, it could be either. If a Regexp is
|
129
|
+
# given, we know it’s a pattern match.
|
130
|
+
#
|
131
|
+
# If we have a pattern match, create a dependency on the item
|
132
|
+
# collection, with a `raw_content` property that contains the pattern.
|
133
|
+
# If we have an exact match, do nothing -- there is no reason to create
|
134
|
+
# a dependency on the item itself, because accessing that item
|
135
|
+
# (attributes, compiled content, …) will create the dependency later.
|
136
|
+
|
137
|
+
object_from_exact_match = nil
|
138
|
+
object_from_pattern_match = nil
|
139
|
+
|
140
|
+
case arg
|
141
|
+
when Nanoc::Core::Identifier
|
142
|
+
# Can only be an exact match
|
143
|
+
object_from_exact_match = @objects.object_with_identifier(arg)
|
144
|
+
when String
|
145
|
+
# Can be an exact match, or a pattern match
|
146
|
+
tmp = @objects.object_with_identifier(arg)
|
147
|
+
if tmp
|
148
|
+
object_from_exact_match = tmp
|
129
149
|
else
|
130
|
-
|
150
|
+
object_from_pattern_match = @objects.object_matching_glob(arg)
|
131
151
|
end
|
152
|
+
when Regexp
|
153
|
+
# Can only be a pattern match
|
154
|
+
object_from_pattern_match = @objects.find { |i| i.identifier.to_s =~ arg }
|
155
|
+
else
|
156
|
+
raise ArgumentError, "Unexpected argument #{arg.class} to []: Can only pass strings, identfiers, and regular expressions"
|
157
|
+
end
|
132
158
|
|
133
|
-
|
134
|
-
|
135
|
-
|
159
|
+
unless object_from_exact_match
|
160
|
+
# We got this object from a pattern match. Create a dependency with
|
161
|
+
# this pattern, because if the objects matching this pattern change,
|
162
|
+
# then the result of #[] will change too.
|
163
|
+
#
|
164
|
+
# NOTE: object_from_exact_match can also be nil, but in that case
|
165
|
+
# we still need to create a dependency.
|
166
|
+
|
167
|
+
prop_attribute =
|
168
|
+
case arg
|
169
|
+
when Identifier
|
170
|
+
[arg.to_s]
|
171
|
+
when String, Regexp
|
172
|
+
[arg]
|
173
|
+
end
|
174
|
+
|
175
|
+
@context.dependency_tracker.bounce(_unwrap, raw_content: prop_attribute)
|
176
|
+
end
|
177
|
+
|
178
|
+
object = object_from_exact_match || object_from_pattern_match
|
179
|
+
object && view_class.new(object, @context)
|
136
180
|
end
|
137
181
|
end
|
138
182
|
end
|
data/lib/nanoc/core/item.rb
CHANGED
data/lib/nanoc/core/item_rep.rb
CHANGED
@@ -42,6 +42,9 @@ module Nanoc
|
|
42
42
|
# Reset flags
|
43
43
|
@compiled = false
|
44
44
|
@modified = false
|
45
|
+
|
46
|
+
# Precalculate for performance
|
47
|
+
@hash = [self.class, item, name].hash
|
45
48
|
end
|
46
49
|
|
47
50
|
contract C::HashOf[Symbol => C::IterOf[C::AbsolutePathString]] => C::HashOf[Symbol => C::IterOf[C::AbsolutePathString]]
|
@@ -75,6 +78,21 @@ module Nanoc
|
|
75
78
|
@paths.fetch(snapshot, []).first
|
76
79
|
end
|
77
80
|
|
81
|
+
contract C::None => C::Num
|
82
|
+
def hash
|
83
|
+
@hash
|
84
|
+
end
|
85
|
+
|
86
|
+
contract C::Any => C::Bool
|
87
|
+
def ==(other)
|
88
|
+
eql?(other)
|
89
|
+
end
|
90
|
+
|
91
|
+
contract C::Any => C::Bool
|
92
|
+
def eql?(other)
|
93
|
+
other.is_a?(self.class) && item == other.item && name == other.name
|
94
|
+
end
|
95
|
+
|
78
96
|
# Returns an object that can be used for uniquely identifying objects.
|
79
97
|
def reference
|
80
98
|
"item_rep:#{item.identifier}:#{name}"
|
@@ -25,15 +25,15 @@ module Nanoc
|
|
25
25
|
action_sequences = Nanoc::Core::ItemRepRouter.new(@reps, @action_provider, @site).run
|
26
26
|
|
27
27
|
@reps.each do |rep|
|
28
|
-
rep.snapshot_defs = self.class.snapshot_defs_for(action_sequences[rep])
|
28
|
+
rep.snapshot_defs = self.class.snapshot_defs_for(action_sequences[rep], rep)
|
29
29
|
end
|
30
30
|
|
31
31
|
action_sequences
|
32
32
|
end
|
33
33
|
|
34
|
-
contract Nanoc::Core::ActionSequence => C::ArrayOf[Nanoc::Core::SnapshotDef]
|
35
|
-
def self.snapshot_defs_for(action_sequence)
|
36
|
-
is_binary =
|
34
|
+
contract Nanoc::Core::ActionSequence, Nanoc::Core::ItemRep => C::ArrayOf[Nanoc::Core::SnapshotDef]
|
35
|
+
def self.snapshot_defs_for(action_sequence, rep)
|
36
|
+
is_binary = rep.item.content.binary?
|
37
37
|
snapshot_defs = []
|
38
38
|
|
39
39
|
action_sequence.each do |action|
|