nanoc 4.1.6 → 4.2.0b1
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/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|
|