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
|
@@ -46,6 +46,8 @@ module Nanoc
|
|
|
46
46
|
|
|
47
47
|
class Named < AbstractContract
|
|
48
48
|
def initialize(name)
|
|
49
|
+
super()
|
|
50
|
+
|
|
49
51
|
@name = name
|
|
50
52
|
end
|
|
51
53
|
|
|
@@ -60,11 +62,14 @@ module Nanoc
|
|
|
60
62
|
|
|
61
63
|
class IterOf < AbstractContract
|
|
62
64
|
def initialize(contract)
|
|
65
|
+
super()
|
|
66
|
+
|
|
63
67
|
@contract = contract
|
|
64
68
|
end
|
|
65
69
|
|
|
66
70
|
def valid?(val)
|
|
67
|
-
val.respond_to?(:each) &&
|
|
71
|
+
val.respond_to?(:each) &&
|
|
72
|
+
val.all? { |v| Contract.valid?(v, @contract) }
|
|
68
73
|
end
|
|
69
74
|
|
|
70
75
|
def inspect
|
|
@@ -97,13 +102,20 @@ module Nanoc
|
|
|
97
102
|
false
|
|
98
103
|
end
|
|
99
104
|
|
|
100
|
-
@_contracts_support__should_enable =
|
|
105
|
+
@_contracts_support__should_enable =
|
|
106
|
+
contracts_loadable && !ENV.key?('DISABLE_CONTRACTS')
|
|
101
107
|
|
|
102
108
|
if @_contracts_support__should_enable
|
|
103
109
|
# FIXME: ugly
|
|
104
|
-
::Contracts.const_set(
|
|
105
|
-
|
|
106
|
-
|
|
110
|
+
::Contracts.const_set(
|
|
111
|
+
'Named', EnabledContracts::Named
|
|
112
|
+
)
|
|
113
|
+
::Contracts.const_set(
|
|
114
|
+
'IterOf', EnabledContracts::IterOf
|
|
115
|
+
)
|
|
116
|
+
::Contracts.const_set(
|
|
117
|
+
'AbsolutePathString', EnabledContracts::AbsolutePathString
|
|
118
|
+
)
|
|
107
119
|
|
|
108
120
|
warn_about_performance
|
|
109
121
|
end
|
|
@@ -136,13 +148,19 @@ module Nanoc
|
|
|
136
148
|
|
|
137
149
|
puts '-' * 78
|
|
138
150
|
puts 'A NOTE ABOUT PERFORMANCE:'
|
|
139
|
-
puts 'The `contracts` gem is loaded, which enables extra run-time
|
|
151
|
+
puts 'The `contracts` gem is loaded, which enables extra run-time ' \
|
|
152
|
+
'checks, but can drastically reduce Nanoc’s performance. The ' \
|
|
153
|
+
'`contracts` gem is intended for development purposes, and is ' \
|
|
154
|
+
'not recommended for day-to-day Nanoc usage.'
|
|
140
155
|
puts
|
|
141
156
|
|
|
142
157
|
if defined?(Bundler)
|
|
143
|
-
puts 'To speed up compilation, remove `contracts` from the Gemfile
|
|
158
|
+
puts 'To speed up compilation, remove `contracts` from the Gemfile ' \
|
|
159
|
+
'and run `bundle install`.'
|
|
144
160
|
else
|
|
145
|
-
puts 'To speed up compilation, either uninstall the `contracts`
|
|
161
|
+
puts 'To speed up compilation, either uninstall the `contracts` ' \
|
|
162
|
+
'gem, or use Bundler (https://bundler.io/) with a Gemfile ' \
|
|
163
|
+
'that doesn’t include `contracts`.'
|
|
146
164
|
end
|
|
147
165
|
|
|
148
166
|
puts '-' * 78
|
|
@@ -13,7 +13,12 @@ module Nanoc
|
|
|
13
13
|
hash = {}
|
|
14
14
|
each_pair do |key, value|
|
|
15
15
|
new_key = key.respond_to?(:to_sym) ? key.to_sym : key
|
|
16
|
-
new_value =
|
|
16
|
+
new_value =
|
|
17
|
+
if value.respond_to?(:__nanoc_symbolize_keys_recursively)
|
|
18
|
+
value.__nanoc_symbolize_keys_recursively
|
|
19
|
+
else
|
|
20
|
+
value
|
|
21
|
+
end
|
|
17
22
|
hash[new_key] = new_value
|
|
18
23
|
end
|
|
19
24
|
hash
|
|
@@ -23,7 +28,12 @@ module Nanoc
|
|
|
23
28
|
hash = {}
|
|
24
29
|
each_pair do |key, value|
|
|
25
30
|
new_key = key.is_a?(Symbol) ? key.to_s : key
|
|
26
|
-
new_value =
|
|
31
|
+
new_value =
|
|
32
|
+
if value.respond_to?(:__nanoc_stringify_keys_recursively)
|
|
33
|
+
value.__nanoc_stringify_keys_recursively
|
|
34
|
+
else
|
|
35
|
+
value
|
|
36
|
+
end
|
|
27
37
|
hash[new_key] = new_value
|
|
28
38
|
end
|
|
29
39
|
hash
|
|
@@ -101,13 +101,15 @@ module Nanoc
|
|
|
101
101
|
|
|
102
102
|
# @api private
|
|
103
103
|
def item_changes
|
|
104
|
-
warn "Caution: Data source #{self.class.identifier.inspect} does not
|
|
104
|
+
warn "Caution: Data source #{self.class.identifier.inspect} does not " \
|
|
105
|
+
'implement #item_changes; live compilation will not pick up changes in this data source.'
|
|
105
106
|
Enumerator.new { |_y| sleep }
|
|
106
107
|
end
|
|
107
108
|
|
|
108
109
|
# @api private
|
|
109
110
|
def layout_changes
|
|
110
|
-
warn "Caution: Data source #{self.class.identifier.inspect} does not
|
|
111
|
+
warn "Caution: Data source #{self.class.identifier.inspect} does not " \
|
|
112
|
+
'implement #layout_changes; live compilation will not pick up changes in this data source.'
|
|
111
113
|
Enumerator.new { |_y| sleep }
|
|
112
114
|
end
|
|
113
115
|
|
|
@@ -143,9 +145,16 @@ module Nanoc
|
|
|
143
145
|
# @param [String, nil] content_checksum_data
|
|
144
146
|
#
|
|
145
147
|
# @param [String, nil] attributes_checksum_data
|
|
146
|
-
def new_item(
|
|
148
|
+
def new_item(
|
|
149
|
+
content, attributes, identifier,
|
|
150
|
+
binary: false, checksum_data: nil, content_checksum_data: nil,
|
|
151
|
+
attributes_checksum_data: nil
|
|
152
|
+
)
|
|
147
153
|
content = Nanoc::Core::Content.create(content, binary:)
|
|
148
|
-
Nanoc::Core::Item.new(
|
|
154
|
+
Nanoc::Core::Item.new(
|
|
155
|
+
content, attributes, identifier,
|
|
156
|
+
checksum_data:, content_checksum_data:, attributes_checksum_data:
|
|
157
|
+
)
|
|
149
158
|
end
|
|
150
159
|
|
|
151
160
|
# Creates a new in-memory layout instance. This is intended for use within
|
|
@@ -162,8 +171,15 @@ module Nanoc
|
|
|
162
171
|
# @param [String, nil] content_checksum_data
|
|
163
172
|
#
|
|
164
173
|
# @param [String, nil] attributes_checksum_data
|
|
165
|
-
def new_layout(
|
|
166
|
-
|
|
174
|
+
def new_layout(
|
|
175
|
+
raw_content, attributes, identifier,
|
|
176
|
+
checksum_data: nil, content_checksum_data: nil,
|
|
177
|
+
attributes_checksum_data: nil
|
|
178
|
+
)
|
|
179
|
+
Nanoc::Core::Layout.new(
|
|
180
|
+
raw_content, attributes, identifier,
|
|
181
|
+
checksum_data:, content_checksum_data:, attributes_checksum_data:
|
|
182
|
+
)
|
|
167
183
|
end
|
|
168
184
|
end
|
|
169
185
|
end
|
|
@@ -7,7 +7,11 @@ module Nanoc
|
|
|
7
7
|
class Dependency
|
|
8
8
|
include Nanoc::Core::ContractsSupport
|
|
9
9
|
|
|
10
|
-
C_OBJ_FROM = C::Or[
|
|
10
|
+
C_OBJ_FROM = C::Or[
|
|
11
|
+
Nanoc::Core::Item,
|
|
12
|
+
Nanoc::Core::Layout,
|
|
13
|
+
Nanoc::Core::Configuration,
|
|
14
|
+
Nanoc::Core::IdentifiableCollection]
|
|
11
15
|
C_OBJ_TO = Nanoc::Core::Item
|
|
12
16
|
|
|
13
17
|
contract C::None => C::Maybe[C_OBJ_FROM]
|
|
@@ -19,7 +23,9 @@ module Nanoc
|
|
|
19
23
|
contract C::None => Nanoc::Core::DependencyProps
|
|
20
24
|
attr_reader :props
|
|
21
25
|
|
|
22
|
-
contract C::Maybe[C_OBJ_FROM],
|
|
26
|
+
contract C::Maybe[C_OBJ_FROM],
|
|
27
|
+
C::Maybe[C_OBJ_TO],
|
|
28
|
+
Nanoc::Core::DependencyProps => C::Any
|
|
23
29
|
def initialize(from, to, props)
|
|
24
30
|
@from = from
|
|
25
31
|
@to = to
|
|
@@ -6,6 +6,11 @@ module Nanoc
|
|
|
6
6
|
class DependencyProps
|
|
7
7
|
include Nanoc::Core::ContractsSupport
|
|
8
8
|
|
|
9
|
+
BIT_PATTERN_RAW_CONTENT = 0x01
|
|
10
|
+
BIT_PATTERN_ATTRIBUTES = 0x02
|
|
11
|
+
BIT_PATTERN_COMPILED_CONTENT = 0x04
|
|
12
|
+
BIT_PATTERN_PATH = 0x08
|
|
13
|
+
|
|
9
14
|
attr_reader :attributes
|
|
10
15
|
attr_reader :raw_content
|
|
11
16
|
|
|
@@ -42,8 +47,20 @@ module Nanoc
|
|
|
42
47
|
path: C::Optional[C::Bool],
|
|
43
48
|
]
|
|
44
49
|
|
|
50
|
+
def self.format_bit_pattern(pat)
|
|
51
|
+
(+'').tap do |s|
|
|
52
|
+
s << (pat.nobits?(BIT_PATTERN_RAW_CONTENT) ? '_' : 'r')
|
|
53
|
+
s << (pat.nobits?(BIT_PATTERN_ATTRIBUTES) ? '_' : 'a')
|
|
54
|
+
s << (pat.nobits?(BIT_PATTERN_COMPILED_CONTENT) ? '_' : 'c')
|
|
55
|
+
s << (pat.nobits?(BIT_PATTERN_PATH) ? '_' : 'p')
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
45
59
|
contract C_ARGS => C::Any
|
|
46
|
-
def initialize(
|
|
60
|
+
def initialize(
|
|
61
|
+
raw_content: false, attributes: false,
|
|
62
|
+
compiled_content: false, path: false
|
|
63
|
+
)
|
|
47
64
|
@raw_content = raw_content
|
|
48
65
|
@attributes = attributes
|
|
49
66
|
@compiled_content = compiled_content
|
|
@@ -155,14 +172,16 @@ module Nanoc
|
|
|
155
172
|
end
|
|
156
173
|
end
|
|
157
174
|
|
|
158
|
-
contract C::None =>
|
|
175
|
+
contract C::None => C::Num
|
|
159
176
|
def active
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
177
|
+
res = 0x00
|
|
178
|
+
|
|
179
|
+
res |= BIT_PATTERN_RAW_CONTENT if raw_content?
|
|
180
|
+
res |= BIT_PATTERN_ATTRIBUTES if attributes?
|
|
181
|
+
res |= BIT_PATTERN_COMPILED_CONTENT if compiled_content?
|
|
182
|
+
res |= BIT_PATTERN_PATH if path?
|
|
183
|
+
|
|
184
|
+
res
|
|
166
185
|
end
|
|
167
186
|
|
|
168
187
|
def attribute_keys
|
|
@@ -27,22 +27,28 @@ module Nanoc
|
|
|
27
27
|
path: C::Optional[C::Bool],
|
|
28
28
|
]
|
|
29
29
|
|
|
30
|
-
C_OBJ_SRC =
|
|
31
|
-
|
|
32
|
-
C_OBJ_DST =
|
|
30
|
+
C_OBJ_SRC =
|
|
33
31
|
C::Or[
|
|
32
|
+
nil,
|
|
34
33
|
Nanoc::Core::Item,
|
|
35
34
|
Nanoc::Core::Layout,
|
|
36
35
|
Nanoc::Core::Configuration,
|
|
37
36
|
Nanoc::Core::IdentifiableCollection,
|
|
38
37
|
]
|
|
39
38
|
|
|
39
|
+
C_OBJ_DST = Nanoc::Core::Item
|
|
40
|
+
|
|
40
41
|
attr_reader :items
|
|
41
42
|
attr_reader :layouts
|
|
42
43
|
|
|
43
|
-
contract Nanoc::Core::ItemCollection,
|
|
44
|
+
contract Nanoc::Core::ItemCollection,
|
|
45
|
+
Nanoc::Core::LayoutCollection,
|
|
46
|
+
Nanoc::Core::Configuration => C::Any
|
|
44
47
|
def initialize(items, layouts, config)
|
|
45
|
-
super(
|
|
48
|
+
super(
|
|
49
|
+
self.class.tmp_path_for(config:, store_name: 'dependencies'),
|
|
50
|
+
6,
|
|
51
|
+
)
|
|
46
52
|
|
|
47
53
|
@config = config
|
|
48
54
|
@items = items
|
|
@@ -51,7 +57,9 @@ module Nanoc
|
|
|
51
57
|
rebuild_refs2objs
|
|
52
58
|
|
|
53
59
|
@new_objects = []
|
|
54
|
-
@graph = Nanoc::Core::DirectedGraph.new(
|
|
60
|
+
@graph = Nanoc::Core::DirectedGraph.new(
|
|
61
|
+
[nil] + objs2refs(@items) + objs2refs(@layouts),
|
|
62
|
+
)
|
|
55
63
|
end
|
|
56
64
|
|
|
57
65
|
def rebuild_refs2objs
|
|
@@ -63,7 +71,7 @@ module Nanoc
|
|
|
63
71
|
add_vertex_for(@layouts)
|
|
64
72
|
end
|
|
65
73
|
|
|
66
|
-
contract
|
|
74
|
+
contract C_OBJ_DST => C::ArrayOf[Nanoc::Core::Dependency]
|
|
67
75
|
def dependencies_causing_outdatedness_of(object)
|
|
68
76
|
objects_causing_outdatedness_of(object).map do |other_object|
|
|
69
77
|
props = props_for(other_object, object)
|
|
@@ -76,6 +84,19 @@ module Nanoc
|
|
|
76
84
|
end
|
|
77
85
|
end
|
|
78
86
|
|
|
87
|
+
contract C_OBJ_SRC => C::ArrayOf[Nanoc::Core::Dependency]
|
|
88
|
+
def dependencies_outdated_because_of(object)
|
|
89
|
+
objects_outdated_because_of(object).map do |other_object|
|
|
90
|
+
props = props_for(object, other_object)
|
|
91
|
+
|
|
92
|
+
Nanoc::Core::Dependency.new(
|
|
93
|
+
object,
|
|
94
|
+
other_object,
|
|
95
|
+
props,
|
|
96
|
+
)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
79
100
|
def items=(items)
|
|
80
101
|
@items = items
|
|
81
102
|
rebuild_refs2objs
|
|
@@ -87,11 +108,11 @@ module Nanoc
|
|
|
87
108
|
end
|
|
88
109
|
|
|
89
110
|
def new_items
|
|
90
|
-
@new_objects.
|
|
111
|
+
@new_objects.grep(Nanoc::Core::Item)
|
|
91
112
|
end
|
|
92
113
|
|
|
93
114
|
def new_layouts
|
|
94
|
-
@new_objects.
|
|
115
|
+
@new_objects.grep(Nanoc::Core::Layout)
|
|
95
116
|
end
|
|
96
117
|
|
|
97
118
|
# Returns the direct dependencies for the given object.
|
|
@@ -115,19 +136,29 @@ module Nanoc
|
|
|
115
136
|
refs2objs(@graph.direct_predecessors_of(obj2ref(object)))
|
|
116
137
|
end
|
|
117
138
|
|
|
118
|
-
|
|
139
|
+
def objects_outdated_because_of(object)
|
|
140
|
+
refs2objs(@graph.direct_successors_of(obj2ref(object)))
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
contract C::Maybe[C_OBJ_SRC],
|
|
144
|
+
C::Maybe[C_OBJ_DST],
|
|
145
|
+
C_KEYWORD_PROPS => C::Any
|
|
119
146
|
# Records a dependency from `src` to `dst` in the dependency graph. When
|
|
120
|
-
# `
|
|
147
|
+
# `src` is oudated, `dst` will also become outdated.
|
|
121
148
|
#
|
|
122
|
-
# @param [Nanoc::Core::Item, Nanoc::Core::Layout] src The source of the
|
|
123
|
-
# i.e. the object that will
|
|
149
|
+
# @param [Nanoc::Core::Item, Nanoc::Core::Layout] src The source of the
|
|
150
|
+
# dependency, i.e. the object that will cause dst to become
|
|
151
|
+
# outdated
|
|
124
152
|
#
|
|
125
|
-
# @param [Nanoc::Core::Item, Nanoc::Core::Layout] dst The destination of
|
|
126
|
-
# dependency, i.e. the object that will
|
|
127
|
-
# outdated
|
|
153
|
+
# @param [Nanoc::Core::Item, Nanoc::Core::Layout] dst The destination of
|
|
154
|
+
# the dependency, i.e. the object that will become outdated if src is
|
|
155
|
+
# outdated
|
|
128
156
|
#
|
|
129
157
|
# @return [void]
|
|
130
|
-
def record_dependency(
|
|
158
|
+
def record_dependency(
|
|
159
|
+
src, dst, raw_content: false, attributes: false,
|
|
160
|
+
compiled_content: false, path: false
|
|
161
|
+
)
|
|
131
162
|
return if src == dst
|
|
132
163
|
|
|
133
164
|
add_vertex_for(src)
|
|
@@ -141,11 +172,13 @@ module Nanoc
|
|
|
141
172
|
attributes = attributes.to_a
|
|
142
173
|
end
|
|
143
174
|
|
|
144
|
-
existing_props = @graph.props_for(
|
|
145
|
-
new_props = Nanoc::Core::DependencyProps.new(
|
|
175
|
+
existing_props = @graph.props_for(src_ref, dst_ref)
|
|
176
|
+
new_props = Nanoc::Core::DependencyProps.new(
|
|
177
|
+
raw_content:, attributes:, compiled_content:, path:,
|
|
178
|
+
)
|
|
146
179
|
props = existing_props ? existing_props.merge(new_props) : new_props
|
|
147
180
|
|
|
148
|
-
@graph.add_edge(
|
|
181
|
+
@graph.add_edge(src_ref, dst_ref, props:)
|
|
149
182
|
end
|
|
150
183
|
|
|
151
184
|
def add_vertex_for(obj)
|
|
@@ -157,8 +190,8 @@ module Nanoc
|
|
|
157
190
|
# will stick around and new dependencies will appear twice. This function
|
|
158
191
|
# removes all incoming edges for the given vertex.
|
|
159
192
|
#
|
|
160
|
-
# @param [Nanoc::Core::Item, Nanoc::Core::Layout] object The object for
|
|
161
|
-
# forget all dependencies
|
|
193
|
+
# @param [Nanoc::Core::Item, Nanoc::Core::Layout] object The object for
|
|
194
|
+
# which to forget all dependencies
|
|
162
195
|
#
|
|
163
196
|
# @return [void]
|
|
164
197
|
def forget_dependencies_for(object)
|
|
@@ -44,12 +44,18 @@ module Nanoc
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
contract C_OBJ, C_ARGS => C::Any
|
|
47
|
-
def bounce(
|
|
47
|
+
def bounce(
|
|
48
|
+
obj,
|
|
49
|
+
raw_content: false,
|
|
50
|
+
attributes: false,
|
|
51
|
+
compiled_content: false,
|
|
52
|
+
path: false
|
|
53
|
+
)
|
|
48
54
|
Nanoc::Core::NotificationCenter.post(:dependency_created, @root, obj)
|
|
49
55
|
|
|
50
56
|
@dependency_store.record_dependency(
|
|
51
|
-
@root,
|
|
52
57
|
obj,
|
|
58
|
+
@root,
|
|
53
59
|
raw_content:,
|
|
54
60
|
attributes:,
|
|
55
61
|
compiled_content:,
|
|
@@ -60,10 +66,20 @@ module Nanoc
|
|
|
60
66
|
class Null < DependencyTracker
|
|
61
67
|
include Nanoc::Core::ContractsSupport
|
|
62
68
|
|
|
63
|
-
def initialize
|
|
69
|
+
def initialize
|
|
70
|
+
super(nil, root: nil)
|
|
71
|
+
end
|
|
64
72
|
|
|
65
73
|
contract C_OBJ, C_ARGS => C::Any
|
|
66
|
-
def bounce(
|
|
74
|
+
def bounce(
|
|
75
|
+
_obj,
|
|
76
|
+
raw_content: false,
|
|
77
|
+
attributes: false,
|
|
78
|
+
compiled_content: false,
|
|
79
|
+
path: false
|
|
80
|
+
)
|
|
81
|
+
# do nothing
|
|
82
|
+
end
|
|
67
83
|
end
|
|
68
84
|
end
|
|
69
85
|
end
|
|
@@ -21,8 +21,6 @@ module Nanoc
|
|
|
21
21
|
# # Get (direct) predecessors
|
|
22
22
|
# graph.direct_predecessors_of('b').sort
|
|
23
23
|
# # => %w( a )
|
|
24
|
-
# graph.predecessors_of('e').sort
|
|
25
|
-
# # => %w( a b c d )
|
|
26
24
|
#
|
|
27
25
|
# # Modify edges
|
|
28
26
|
# graph.delete_edges_to('c')
|
|
@@ -30,8 +28,6 @@ module Nanoc
|
|
|
30
28
|
# # Get (direct) predecessors again
|
|
31
29
|
# graph.direct_predecessors_of('e').sort
|
|
32
30
|
# # => %w( d )
|
|
33
|
-
# graph.predecessors_of('e').sort
|
|
34
|
-
# # => %w( c d )
|
|
35
31
|
class DirectedGraph
|
|
36
32
|
EMPTY_SET = Set.new.freeze
|
|
37
33
|
|
|
@@ -39,30 +35,34 @@ module Nanoc
|
|
|
39
35
|
|
|
40
36
|
# Creates a new directed graph with the given vertices.
|
|
41
37
|
def initialize(vertices)
|
|
42
|
-
@
|
|
38
|
+
@vertex_to_idx_map = {}
|
|
39
|
+
@vertices = []
|
|
43
40
|
@next_vertex_idx = 0
|
|
44
41
|
vertices.each do |v|
|
|
45
|
-
@vertices
|
|
42
|
+
@vertices << v
|
|
43
|
+
@vertex_to_idx_map[v] = @next_vertex_idx
|
|
46
44
|
@next_vertex_idx += 1
|
|
47
45
|
end
|
|
48
46
|
|
|
49
47
|
@to_graph = {}
|
|
48
|
+
@from_graph = {}
|
|
50
49
|
|
|
51
50
|
@edge_props = {}
|
|
52
|
-
|
|
53
|
-
invalidate_caches
|
|
54
51
|
end
|
|
55
52
|
|
|
56
53
|
def inspect
|
|
57
54
|
s = []
|
|
58
55
|
|
|
59
|
-
@vertices.
|
|
56
|
+
@vertices.each do |v2|
|
|
60
57
|
direct_predecessors_of(v2).each do |v1|
|
|
61
|
-
s << [
|
|
58
|
+
s << [
|
|
59
|
+
"#{v1.inspect} -> #{v2.inspect} " \
|
|
60
|
+
"props=#{@edge_props[[v1, v2]].inspect}",
|
|
61
|
+
]
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
self.class
|
|
65
|
+
"#{self.class}(#{s.join(', ')})"
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
# @group Modifying the graph
|
|
@@ -81,11 +81,12 @@ module Nanoc
|
|
|
81
81
|
@to_graph[to] ||= Set.new
|
|
82
82
|
@to_graph[to] << from
|
|
83
83
|
|
|
84
|
+
@from_graph[from] ||= Set.new
|
|
85
|
+
@from_graph[from] << to
|
|
86
|
+
|
|
84
87
|
if props
|
|
85
88
|
@edge_props[[from, to]] = props
|
|
86
89
|
end
|
|
87
|
-
|
|
88
|
-
invalidate_caches
|
|
89
90
|
end
|
|
90
91
|
|
|
91
92
|
# Adds the given vertex to the graph.
|
|
@@ -94,9 +95,10 @@ module Nanoc
|
|
|
94
95
|
#
|
|
95
96
|
# @return [void]
|
|
96
97
|
def add_vertex(vertex)
|
|
97
|
-
return if @
|
|
98
|
+
return if @vertex_to_idx_map.key?(vertex)
|
|
98
99
|
|
|
99
|
-
@vertices
|
|
100
|
+
@vertices << vertex
|
|
101
|
+
@vertex_to_idx_map[vertex] = @next_vertex_idx
|
|
100
102
|
@next_vertex_idx += 1
|
|
101
103
|
end
|
|
102
104
|
|
|
@@ -110,10 +112,9 @@ module Nanoc
|
|
|
110
112
|
|
|
111
113
|
@to_graph[to].each do |from|
|
|
112
114
|
@edge_props.delete([from, to])
|
|
115
|
+
@from_graph.delete(from)
|
|
113
116
|
end
|
|
114
117
|
@to_graph.delete(to)
|
|
115
|
-
|
|
116
|
-
invalidate_caches
|
|
117
118
|
end
|
|
118
119
|
|
|
119
120
|
# @group Querying the graph
|
|
@@ -128,14 +129,8 @@ module Nanoc
|
|
|
128
129
|
@to_graph.fetch(to, EMPTY_SET)
|
|
129
130
|
end
|
|
130
131
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
#
|
|
134
|
-
# @param to The vertex of which the predecessors should be calculated
|
|
135
|
-
#
|
|
136
|
-
# @return [Array] Predecessors of the given vertex
|
|
137
|
-
def predecessors_of(to)
|
|
138
|
-
@predecessors[to] ||= recursively_find_vertices(to, :direct_predecessors_of)
|
|
132
|
+
def direct_successors_of(from)
|
|
133
|
+
@from_graph.fetch(from, EMPTY_SET)
|
|
139
134
|
end
|
|
140
135
|
|
|
141
136
|
def props_for(from, to)
|
|
@@ -144,7 +139,7 @@ module Nanoc
|
|
|
144
139
|
|
|
145
140
|
# @return [Array] The list of all vertices in this graph.
|
|
146
141
|
def vertices
|
|
147
|
-
@vertices
|
|
142
|
+
@vertices
|
|
148
143
|
end
|
|
149
144
|
|
|
150
145
|
# Returns an array of tuples representing the edges. The result of this
|
|
@@ -153,47 +148,15 @@ module Nanoc
|
|
|
153
148
|
# @return [Array] The list of all edges in this graph.
|
|
154
149
|
def edges
|
|
155
150
|
result = []
|
|
156
|
-
@vertices.
|
|
157
|
-
direct_predecessors_of(v2)
|
|
158
|
-
|
|
159
|
-
|
|
151
|
+
@vertices.each_with_index do |v2, i2|
|
|
152
|
+
direct_predecessors_of(v2)
|
|
153
|
+
.map { |v1| [@vertex_to_idx_map[v1], v1] }
|
|
154
|
+
.each do |i1, v1|
|
|
155
|
+
result << [i1, i2, @edge_props[[v1, v2]]]
|
|
156
|
+
end
|
|
160
157
|
end
|
|
161
158
|
result
|
|
162
159
|
end
|
|
163
|
-
|
|
164
|
-
private
|
|
165
|
-
|
|
166
|
-
# Invalidates cached data. This method should be called when the internal
|
|
167
|
-
# graph representation is changed.
|
|
168
|
-
def invalidate_caches
|
|
169
|
-
@predecessors = {}
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
# Recursively finds vertices, starting at the vertex start, using the
|
|
173
|
-
# given method, which should be a symbol to a method that takes a vertex
|
|
174
|
-
# and returns related vertices (e.g. predecessors, successors).
|
|
175
|
-
def recursively_find_vertices(start, method)
|
|
176
|
-
all_vertices = Set.new
|
|
177
|
-
|
|
178
|
-
processed_vertices = Set.new
|
|
179
|
-
unprocessed_vertices = [start]
|
|
180
|
-
|
|
181
|
-
until unprocessed_vertices.empty?
|
|
182
|
-
# Get next unprocessed vertex
|
|
183
|
-
vertex = unprocessed_vertices.pop
|
|
184
|
-
next if processed_vertices.include?(vertex)
|
|
185
|
-
|
|
186
|
-
processed_vertices << vertex
|
|
187
|
-
|
|
188
|
-
# Add predecessors of this vertex
|
|
189
|
-
send(method, vertex).each do |v|
|
|
190
|
-
all_vertices << v unless all_vertices.include?(v)
|
|
191
|
-
unprocessed_vertices << v
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
all_vertices
|
|
196
|
-
end
|
|
197
160
|
end
|
|
198
161
|
end
|
|
199
162
|
end
|
data/lib/nanoc/core/document.rb
CHANGED
|
@@ -41,7 +41,10 @@ module Nanoc
|
|
|
41
41
|
# @param [String, nil] content_checksum_data
|
|
42
42
|
#
|
|
43
43
|
# @param [String, nil] attributes_checksum_data
|
|
44
|
-
def initialize(
|
|
44
|
+
def initialize(
|
|
45
|
+
content, attributes, identifier,
|
|
46
|
+
checksum_data: nil, content_checksum_data: nil, attributes_checksum_data: nil
|
|
47
|
+
)
|
|
45
48
|
@content = Nanoc::Core::Content.create(content)
|
|
46
49
|
@attributes = Nanoc::Core::LazyValue.new(attributes).map(&:__nanoc_symbolize_keys_recursively)
|
|
47
50
|
@identifier = Nanoc::Core::Identifier.from(identifier)
|