nanoc 4.1.6 → 4.2.0b1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -1
- data/NEWS.md +11 -4
- data/lib/nanoc/base/checksummer.rb +135 -46
- data/lib/nanoc/base/compilation/compiler.rb +18 -28
- data/lib/nanoc/base/compilation/dependency_tracker.rb +22 -32
- data/lib/nanoc/base/compilation/filter.rb +2 -4
- data/lib/nanoc/base/entities.rb +1 -0
- data/lib/nanoc/base/entities/content.rb +14 -3
- data/lib/nanoc/base/entities/document.rb +14 -6
- data/lib/nanoc/base/entities/item.rb +0 -31
- data/lib/nanoc/base/entities/item_rep.rb +1 -1
- data/lib/nanoc/base/entities/lazy_value.rb +36 -0
- data/lib/nanoc/base/entities/pattern.rb +3 -2
- data/lib/nanoc/base/entities/site.rb +2 -0
- data/lib/nanoc/base/memoization.rb +17 -10
- data/lib/nanoc/base/repos/compiled_content_cache.rb +1 -1
- data/lib/nanoc/base/repos/data_source.rb +10 -6
- data/lib/nanoc/base/services/executor.rb +22 -22
- data/lib/nanoc/base/services/item_rep_router.rb +4 -5
- data/lib/nanoc/base/views.rb +0 -1
- data/lib/nanoc/base/views/item_rep_view.rb +3 -9
- data/lib/nanoc/base/views/mixins/document_view_mixin.rb +4 -11
- data/lib/nanoc/base/views/view.rb +1 -0
- data/lib/nanoc/base/views/view_context.rb +5 -1
- data/lib/nanoc/cli/commands/compile.rb +0 -6
- data/lib/nanoc/data_sources.rb +5 -5
- data/lib/nanoc/data_sources/filesystem.rb +219 -90
- data/lib/nanoc/extra/checking/check.rb +1 -2
- data/lib/nanoc/extra/checking/checks.rb +2 -0
- data/lib/nanoc/extra/checking/checks/css.rb +6 -14
- data/lib/nanoc/extra/checking/checks/html.rb +6 -14
- data/lib/nanoc/extra/checking/checks/internal_links.rb +14 -3
- data/lib/nanoc/extra/checking/checks/w3c_validator.rb +28 -0
- data/lib/nanoc/extra/deployers/fog.rb +134 -78
- data/lib/nanoc/extra/link_collector.rb +14 -18
- data/lib/nanoc/filters/sass.rb +3 -3
- data/lib/nanoc/helpers.rb +1 -0
- data/lib/nanoc/helpers/capturing.rb +16 -58
- data/lib/nanoc/helpers/child_parent.rb +51 -0
- data/lib/nanoc/helpers/filtering.rb +0 -1
- data/lib/nanoc/helpers/html_escape.rb +5 -0
- data/lib/nanoc/helpers/link_to.rb +2 -0
- data/lib/nanoc/helpers/rendering.rb +3 -4
- data/lib/nanoc/rule_dsl/action_provider.rb +20 -4
- data/lib/nanoc/rule_dsl/recording_executor.rb +3 -1
- data/lib/nanoc/rule_dsl/rule_context.rb +0 -1
- data/lib/nanoc/rule_dsl/rule_memory_calculator.rb +4 -1
- data/lib/nanoc/spec.rb +217 -0
- data/lib/nanoc/version.rb +1 -1
- data/test/base/test_data_source.rb +4 -2
- data/test/base/test_dependency_tracker.rb +5 -11
- data/test/data_sources/test_filesystem.rb +605 -69
- data/test/extra/checking/checks/test_internal_links.rb +25 -0
- data/test/extra/deployers/test_fog.rb +0 -177
- data/test/filters/test_less.rb +9 -4
- data/test/helpers/test_capturing.rb +38 -212
- data/test/helpers/test_link_to.rb +0 -205
- data/test/helpers/test_xml_sitemap.rb +2 -1
- metadata +7 -12
- data/lib/nanoc/base/views/site_view.rb +0 -14
- data/lib/nanoc/data_sources/filesystem_unified.rb +0 -101
- data/test/data_sources/test_filesystem_unified.rb +0 -559
- data/test/helpers/test_breadcrumbs.rb +0 -60
- data/test/helpers/test_filtering.rb +0 -112
- data/test/helpers/test_html_escape.rb +0 -26
- data/test/helpers/test_rendering.rb +0 -147
- data/test/helpers/test_tagging.rb +0 -92
- data/test/helpers/test_text.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc5bddbd9c1b7b365b227cd69def799b2a8da4a2
|
4
|
+
data.tar.gz: 1da63342f4909056377af782094d03c3293ca75f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de802f2ea52c8b4ee7e9d72bfeffb4870f09b83b6d0edf64fd35508092eb74104b76201754f88382ffcbbab1458af520071e5e77d02b100cb5f76cf62f2ab13c
|
7
|
+
data.tar.gz: d6f3d7751f3c8d0d8f95d7913cb7df7ebf972a47dbe1ad35a91d4d4491cf30919311011846e420c49fb8b9b559bca7f90c18442aa80021d929efa717ed62a7b7
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/NEWS.md
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
# Nanoc news
|
2
2
|
|
3
|
-
## 4.
|
3
|
+
## 4.2.0b1 (2016-04-17)
|
4
4
|
|
5
|
-
|
5
|
+
Features:
|
6
|
+
|
7
|
+
* Allow creating items and layouts with a pre-calculated checksum (#793) [Ruben Verborgh]
|
8
|
+
* Allow lazy-loading item/layout content and attributes (#794) [Ruben Verborgh]
|
9
|
+
* Added `exclude_origins` configuration option to internal links checker (#847)
|
10
|
+
* Added `ChildParent` helper, providing `#children_of` and `#parent_of` (#849)
|
11
|
+
|
12
|
+
Enhancements:
|
6
13
|
|
7
|
-
*
|
8
|
-
*
|
14
|
+
* Made `#html_escape` raise an appropriate error when the given argument is not a String (#840) [Micha Rosenbaum]
|
15
|
+
* Improved memory usage of memoized values by using weak refs (#846)
|
9
16
|
|
10
17
|
## 4.1.5 (2016-03-24)
|
11
18
|
|
@@ -48,70 +48,159 @@ module Nanoc::Int
|
|
48
48
|
|
49
49
|
def update(obj, digest, visited = Set.new)
|
50
50
|
digest.update(obj.class.to_s)
|
51
|
-
digest.update('<')
|
52
51
|
|
53
52
|
if visited.include?(obj)
|
54
|
-
digest.update('recur>')
|
55
|
-
|
53
|
+
digest.update('<recur>')
|
54
|
+
else
|
55
|
+
digest.update('<')
|
56
|
+
behavior_for(obj).update(obj, digest) { |o| update(o, digest, visited + [obj]) }
|
57
|
+
digest.update('>')
|
56
58
|
end
|
59
|
+
end
|
57
60
|
|
61
|
+
def behavior_for(obj)
|
58
62
|
case obj
|
59
|
-
when
|
60
|
-
|
61
|
-
when
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
when
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
74
|
-
when ::Pathname
|
75
|
-
filename = obj.to_s
|
76
|
-
if File.exist?(filename)
|
77
|
-
stat = File.stat(filename)
|
78
|
-
digest.update(stat.size.to_s + '-' + stat.mtime.to_i.to_s)
|
79
|
-
else
|
80
|
-
digest.update('???')
|
81
|
-
end
|
63
|
+
when String, Symbol, Numeric
|
64
|
+
RawUpdateBehavior
|
65
|
+
when Pathname
|
66
|
+
PathnameUpdateBehavior
|
67
|
+
when Nanoc::Int::BinaryContent
|
68
|
+
BinaryContentUpdateBehavior
|
69
|
+
when Array, Nanoc::Int::IdentifiableCollection
|
70
|
+
ArrayUpdateBehavior
|
71
|
+
when Hash, Nanoc::Int::Configuration
|
72
|
+
HashUpdateBehavior
|
73
|
+
when Nanoc::Int::Item, Nanoc::Int::Layout
|
74
|
+
DocumentUpdateBehavior
|
75
|
+
when NilClass, TrueClass, FalseClass
|
76
|
+
NoUpdateBehavior
|
82
77
|
when Time
|
83
|
-
|
78
|
+
ToIToSUpdateBehavior
|
84
79
|
when Nanoc::Identifier
|
85
|
-
|
86
|
-
# TODO: Use RuleMemory rather than RulesCollection
|
80
|
+
ToSUpdateBehavior
|
87
81
|
when Nanoc::RuleDSL::RulesCollection, Nanoc::Int::CodeSnippet
|
88
|
-
|
82
|
+
DataUpdateBehavior
|
89
83
|
when Nanoc::Int::TextualContent
|
90
|
-
|
91
|
-
when Nanoc::
|
92
|
-
|
93
|
-
|
84
|
+
StringUpdateBehavior
|
85
|
+
when Nanoc::View
|
86
|
+
UnwrapUpdateBehavior
|
87
|
+
else
|
88
|
+
RescueUpdateBehavior
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class UpdateBehavior
|
94
|
+
def self.update(_obj, _digest)
|
95
|
+
raise NotImpementedError
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class RawUpdateBehavior < UpdateBehavior
|
100
|
+
def self.update(obj, digest)
|
101
|
+
digest.update(obj.to_s)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class ToSUpdateBehavior < UpdateBehavior
|
106
|
+
def self.update(obj, _digest)
|
107
|
+
yield(obj.to_s)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class ToIToSUpdateBehavior < UpdateBehavior
|
112
|
+
def self.update(obj, digest)
|
113
|
+
digest.update(obj.to_i.to_s)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class StringUpdateBehavior < UpdateBehavior
|
118
|
+
def self.update(obj, _digest)
|
119
|
+
yield(obj.string)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class DataUpdateBehavior < UpdateBehavior
|
124
|
+
def self.update(obj, _digest)
|
125
|
+
yield(obj.data)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
class NoUpdateBehavior < UpdateBehavior
|
130
|
+
def self.update(_obj, _digest)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class UnwrapUpdateBehavior < UpdateBehavior
|
135
|
+
def self.update(obj, _digest)
|
136
|
+
yield(obj.unwrap)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class ArrayUpdateBehavior < UpdateBehavior
|
141
|
+
def self.update(obj, digest)
|
142
|
+
obj.each do |el|
|
143
|
+
yield(el)
|
144
|
+
digest.update(',')
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class HashUpdateBehavior < UpdateBehavior
|
150
|
+
def self.update(obj, digest)
|
151
|
+
obj.each do |key, value|
|
152
|
+
yield(key)
|
153
|
+
digest.update('=')
|
154
|
+
yield(value)
|
155
|
+
digest.update(',')
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
class DocumentUpdateBehavior < UpdateBehavior
|
161
|
+
def self.update(obj, digest)
|
162
|
+
if obj.checksum_data
|
163
|
+
digest.update('checksum_data=' + obj.checksum_data)
|
164
|
+
else
|
94
165
|
digest.update('content=')
|
95
|
-
|
166
|
+
yield(obj.content)
|
96
167
|
|
97
168
|
digest.update(',attributes=')
|
98
|
-
|
169
|
+
yield(obj.attributes)
|
99
170
|
|
100
171
|
digest.update(',identifier=')
|
101
|
-
|
102
|
-
|
103
|
-
|
172
|
+
yield(obj.identifier)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
class PathnameUpdateBehavior < UpdateBehavior
|
178
|
+
def self.update(obj, digest)
|
179
|
+
filename = obj.to_s
|
180
|
+
if File.exist?(filename)
|
181
|
+
stat = File.stat(filename)
|
182
|
+
digest.update(stat.size.to_s + '-' + stat.mtime.to_i.to_s)
|
104
183
|
else
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
184
|
+
digest.update('???')
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
class BinaryContentUpdateBehavior < UpdateBehavior
|
190
|
+
def self.update(obj, _digest)
|
191
|
+
yield(Pathname.new(obj.filename))
|
192
|
+
end
|
193
|
+
end
|
110
194
|
|
111
|
-
|
195
|
+
class RescueUpdateBehavior < UpdateBehavior
|
196
|
+
def self.update(obj, digest)
|
197
|
+
data = begin
|
198
|
+
Marshal.dump(obj)
|
199
|
+
rescue
|
200
|
+
obj.inspect
|
112
201
|
end
|
113
202
|
|
114
|
-
digest.update(
|
203
|
+
digest.update(data)
|
115
204
|
end
|
116
205
|
end
|
117
206
|
end
|
@@ -16,18 +16,6 @@ module Nanoc::Int
|
|
16
16
|
# this item representation (either successfully or with failure). Has one
|
17
17
|
# argument: the item representation itself.
|
18
18
|
#
|
19
|
-
# * `visit_started` — indicates that the compiler requires content or
|
20
|
-
# attributes from the item representation that will be visited. Has one
|
21
|
-
# argument: the visited item identifier. This notification is used to
|
22
|
-
# track dependencies of items on other items; a `visit_started` event
|
23
|
-
# followed by another `visit_started` event indicates that the item
|
24
|
-
# corresponding to the former event will depend on the item from the
|
25
|
-
# latter event.
|
26
|
-
#
|
27
|
-
# * `visit_ended` — indicates that the compiler has finished visiting the
|
28
|
-
# item representation and that the requested attributes or content have
|
29
|
-
# been fetched (either successfully or with failure)
|
30
|
-
#
|
31
19
|
# * `processing_started` — indicates that the compiler has started
|
32
20
|
# processing the specified object, which can be an item representation
|
33
21
|
# (when it is compiled) or a layout (when it is used to lay out an item
|
@@ -98,10 +86,7 @@ module Nanoc::Int
|
|
98
86
|
forget_dependencies_if_outdated
|
99
87
|
|
100
88
|
@stack = []
|
101
|
-
|
102
|
-
dependency_tracker.run do
|
103
|
-
compile_reps
|
104
|
-
end
|
89
|
+
compile_reps
|
105
90
|
store
|
106
91
|
ensure
|
107
92
|
Nanoc::Int::TempFilenameFactory.instance.cleanup(
|
@@ -147,7 +132,7 @@ module Nanoc::Int
|
|
147
132
|
# operation
|
148
133
|
#
|
149
134
|
# @api private
|
150
|
-
def assigns_for(rep)
|
135
|
+
def assigns_for(rep, dependency_tracker)
|
151
136
|
content_or_filename_assigns =
|
152
137
|
if rep.binary?
|
153
138
|
{ filename: rep.snapshot_contents[:last].filename }
|
@@ -155,9 +140,8 @@ module Nanoc::Int
|
|
155
140
|
{ content: rep.snapshot_contents[:last].string }
|
156
141
|
end
|
157
142
|
|
158
|
-
view_context = create_view_context
|
143
|
+
view_context = create_view_context(dependency_tracker)
|
159
144
|
|
160
|
-
# TODO: Do not expose @site (necessary for captures store though…)
|
161
145
|
content_or_filename_assigns.merge(
|
162
146
|
item: Nanoc::ItemWithRepsView.new(rep.item, view_context),
|
163
147
|
rep: Nanoc::ItemRepView.new(rep, view_context),
|
@@ -165,12 +149,16 @@ module Nanoc::Int
|
|
165
149
|
items: Nanoc::ItemCollectionWithRepsView.new(site.items, view_context),
|
166
150
|
layouts: Nanoc::LayoutCollectionView.new(site.layouts, view_context),
|
167
151
|
config: Nanoc::ConfigView.new(site.config, view_context),
|
168
|
-
site: Nanoc::SiteView.new(site, view_context),
|
169
152
|
)
|
170
153
|
end
|
171
154
|
|
172
|
-
def create_view_context
|
173
|
-
Nanoc::ViewContext.new(
|
155
|
+
def create_view_context(dependency_tracker)
|
156
|
+
Nanoc::ViewContext.new(
|
157
|
+
reps: @reps,
|
158
|
+
items: @site.items,
|
159
|
+
dependency_tracker: dependency_tracker,
|
160
|
+
compiler: self,
|
161
|
+
)
|
174
162
|
end
|
175
163
|
|
176
164
|
# @api private
|
@@ -216,15 +204,17 @@ module Nanoc::Int
|
|
216
204
|
#
|
217
205
|
# @return [void]
|
218
206
|
def compile_rep(rep)
|
207
|
+
dependency_tracker = Nanoc::Int::DependencyTracker.new(@dependency_store)
|
208
|
+
|
219
209
|
Nanoc::Int::NotificationCenter.post(:compilation_started, rep)
|
220
210
|
Nanoc::Int::NotificationCenter.post(:processing_started, rep)
|
221
|
-
|
211
|
+
dependency_tracker.enter(rep.item)
|
222
212
|
|
223
213
|
if can_reuse_content_for_rep?(rep)
|
224
214
|
Nanoc::Int::NotificationCenter.post(:cached_content_used, rep)
|
225
215
|
rep.snapshot_contents = compiled_content_cache[rep]
|
226
216
|
else
|
227
|
-
recalculate_content_for_rep(rep)
|
217
|
+
recalculate_content_for_rep(rep, dependency_tracker)
|
228
218
|
end
|
229
219
|
|
230
220
|
rep.compiled = true
|
@@ -237,17 +227,17 @@ module Nanoc::Int
|
|
237
227
|
Nanoc::Int::NotificationCenter.post(:compilation_failed, rep, e)
|
238
228
|
raise e
|
239
229
|
ensure
|
240
|
-
|
230
|
+
dependency_tracker.exit(rep.item)
|
241
231
|
end
|
242
232
|
|
243
233
|
# @return [Boolean]
|
244
234
|
def can_reuse_content_for_rep?(rep)
|
245
|
-
!
|
235
|
+
!outdatedness_checker.outdated?(rep) && compiled_content_cache[rep]
|
246
236
|
end
|
247
237
|
|
248
238
|
# @return [void]
|
249
|
-
def recalculate_content_for_rep(rep)
|
250
|
-
executor = Nanoc::Int::Executor.new(self)
|
239
|
+
def recalculate_content_for_rep(rep, dependency_tracker)
|
240
|
+
executor = Nanoc::Int::Executor.new(self, dependency_tracker)
|
251
241
|
|
252
242
|
action_provider.memory_for(rep).each do |action|
|
253
243
|
case action
|
@@ -1,48 +1,38 @@
|
|
1
1
|
module Nanoc::Int
|
2
2
|
# @api private
|
3
3
|
class DependencyTracker
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
class Null
|
5
|
+
def enter(_obj)
|
6
|
+
end
|
7
7
|
|
8
|
-
|
9
|
-
#
|
10
|
-
# @return [void]
|
11
|
-
def run
|
12
|
-
unless block_given?
|
13
|
-
raise ArgumentError, 'No block given'
|
8
|
+
def exit(_obj)
|
14
9
|
end
|
15
10
|
|
16
|
-
|
17
|
-
|
18
|
-
yield
|
19
|
-
ensure
|
20
|
-
stop_tracking(stack)
|
11
|
+
def bounce(_obj)
|
12
|
+
end
|
21
13
|
end
|
22
14
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
Nanoc::Int::NotificationCenter.post(:dependency_created, stack.last, obj)
|
28
|
-
@dependency_store.record_dependency(stack.last, obj)
|
29
|
-
end
|
30
|
-
stack.push(obj)
|
31
|
-
end
|
15
|
+
def initialize(dependency_store)
|
16
|
+
@dependency_store = dependency_store
|
17
|
+
@stack = []
|
18
|
+
end
|
32
19
|
|
33
|
-
|
34
|
-
|
20
|
+
def enter(obj)
|
21
|
+
unless @stack.empty?
|
22
|
+
Nanoc::Int::NotificationCenter.post(:dependency_created, @stack.last, obj)
|
23
|
+
@dependency_store.record_dependency(@stack.last, obj)
|
35
24
|
end
|
25
|
+
|
26
|
+
@stack.push(obj)
|
36
27
|
end
|
37
28
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
raise 'Internal inconsistency: dependency tracker stack not empty at end of compilation'
|
42
|
-
end
|
29
|
+
def exit(_obj)
|
30
|
+
@stack.pop
|
31
|
+
end
|
43
32
|
|
44
|
-
|
45
|
-
|
33
|
+
def bounce(obj)
|
34
|
+
enter(obj)
|
35
|
+
exit(obj)
|
46
36
|
end
|
47
37
|
end
|
48
38
|
end
|
@@ -187,10 +187,8 @@ module Nanoc
|
|
187
187
|
items = items.map { |i| i.is_a?(Nanoc::ItemWithRepsView) ? i.unwrap : i }
|
188
188
|
|
189
189
|
# Notify
|
190
|
-
|
191
|
-
|
192
|
-
Nanoc::Int::NotificationCenter.post(:visit_ended, item)
|
193
|
-
end
|
190
|
+
dependency_tracker = @assigns[:item]._context.dependency_tracker
|
191
|
+
items.each { |item| dependency_tracker.bounce(item) }
|
194
192
|
|
195
193
|
# Raise unmet dependency error if necessary
|
196
194
|
items.each do |item|
|