nanoc 4.4.1 → 4.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +11 -11
- data/NEWS.md +11 -0
- data/lib/nanoc/base/compilation/compiler.rb +13 -31
- data/lib/nanoc/base/errors.rb +15 -0
- data/lib/nanoc/base/services/dependency_tracker.rb +11 -8
- data/lib/nanoc/base/services/executor.rb +2 -6
- data/lib/nanoc/base/services/filter.rb +5 -0
- data/lib/nanoc/base/services/item_rep_selector.rb +17 -2
- data/lib/nanoc/cli/command_runner.rb +0 -7
- data/lib/nanoc/cli/error_handler.rb +24 -20
- data/lib/nanoc/filters/less.rb +46 -22
- data/lib/nanoc/helpers/rendering.rb +13 -21
- data/lib/nanoc/version.rb +1 -1
- data/test/cli/test_error_handler.rb +36 -1
- metadata +2 -3
- data/test/filters/test_less.rb +0 -71
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 321bc54ed62384061039f82d10745b494012e4ff
|
4
|
+
data.tar.gz: ec7e38daa14af1a0b6cc64bd71e3492585de9865
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e4fcde666aba2b332294e99ddb1381b3d988371f6cb8ee7a23501917f279694a69a0af19c9465c3c0608104243aecc3480732cf88c9e9d83ac9f313ee259a30
|
7
|
+
data.tar.gz: c233e8b716f68bc31569732bf7a1092ae7c4450b820281ccbc9c853ab63d3cbbd105a20dbead2f6cbef59ede2d9583d1df05a76548b5494263e7c1ea1df371c2
|
data/Gemfile.lock
CHANGED
@@ -18,7 +18,7 @@ PATH
|
|
18
18
|
GEM
|
19
19
|
remote: https://rubygems.org/
|
20
20
|
specs:
|
21
|
-
CFPropertyList (2.3.
|
21
|
+
CFPropertyList (2.3.4)
|
22
22
|
RedCloth (4.3.2)
|
23
23
|
addressable (2.5.0)
|
24
24
|
public_suffix (~> 2.0, >= 2.0.2)
|
@@ -36,7 +36,7 @@ GEM
|
|
36
36
|
coffee-script (2.4.1)
|
37
37
|
coffee-script-source
|
38
38
|
execjs
|
39
|
-
coffee-script-source (1.
|
39
|
+
coffee-script-source (1.11.1)
|
40
40
|
colored (1.2)
|
41
41
|
commonjs (0.2.7)
|
42
42
|
compass (1.0.3)
|
@@ -53,10 +53,10 @@ GEM
|
|
53
53
|
sass (>= 3.2, < 3.5)
|
54
54
|
concurrent-ruby (1.0.2)
|
55
55
|
contracts (0.14.0)
|
56
|
-
coveralls (0.8.
|
56
|
+
coveralls (0.8.16)
|
57
57
|
json (>= 1.8, < 3)
|
58
58
|
simplecov (~> 0.12.0)
|
59
|
-
term-ansicolor (~> 1.3)
|
59
|
+
term-ansicolor (~> 1.3.0)
|
60
60
|
thor (~> 0.19.1)
|
61
61
|
tins (>= 1.6.0, < 2)
|
62
62
|
crack (0.4.3)
|
@@ -142,7 +142,7 @@ GEM
|
|
142
142
|
multi_json (~> 1.10)
|
143
143
|
fog-local (0.3.1)
|
144
144
|
fog-core (~> 1.27)
|
145
|
-
fog-openstack (0.1.
|
145
|
+
fog-openstack (0.1.18)
|
146
146
|
fog-core (>= 1.40)
|
147
147
|
fog-json (>= 1.0)
|
148
148
|
ipaddress (>= 0.8)
|
@@ -220,11 +220,11 @@ GEM
|
|
220
220
|
handlebars-source (~> 4.0.5)
|
221
221
|
therubyracer (~> 0.12.1)
|
222
222
|
handlebars-source (4.0.6)
|
223
|
-
hashdiff (0.3.
|
223
|
+
hashdiff (0.3.1)
|
224
224
|
inflecto (0.0.2)
|
225
225
|
ipaddress (0.8.3)
|
226
226
|
json (2.0.2)
|
227
|
-
kramdown (1.13.
|
227
|
+
kramdown (1.13.1)
|
228
228
|
less (2.6.0)
|
229
229
|
commonjs (~> 0.2.7)
|
230
230
|
libv8 (3.16.14.17)
|
@@ -254,7 +254,7 @@ GEM
|
|
254
254
|
nenv (~> 0.1)
|
255
255
|
shellany (~> 0.0)
|
256
256
|
pandoc-ruby (2.0.1)
|
257
|
-
parallel (1.
|
257
|
+
parallel (1.10.0)
|
258
258
|
parser (2.3.2.0)
|
259
259
|
ast (~> 2.2)
|
260
260
|
posix-spawn (0.3.12)
|
@@ -316,15 +316,15 @@ GEM
|
|
316
316
|
tilt (>= 1.3.3, < 2.1)
|
317
317
|
slop (3.6.0)
|
318
318
|
temple (0.7.7)
|
319
|
-
term-ansicolor (1.
|
319
|
+
term-ansicolor (1.3.2)
|
320
320
|
tins (~> 1.0)
|
321
321
|
therubyracer (0.12.2)
|
322
322
|
libv8 (~> 3.16.14.0)
|
323
323
|
ref
|
324
|
-
thor (0.19.
|
324
|
+
thor (0.19.3)
|
325
325
|
tilt (2.0.5)
|
326
326
|
timecop (0.8.1)
|
327
|
-
tins (1.
|
327
|
+
tins (1.13.0)
|
328
328
|
trollop (2.1.2)
|
329
329
|
typogruby (1.0.18)
|
330
330
|
rubypants
|
data/NEWS.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Nanoc news
|
2
2
|
|
3
|
+
## 4.4.2 (2016-11-27)
|
4
|
+
|
5
|
+
Fixes:
|
6
|
+
|
7
|
+
* Fixed “Maximum call stack size exceeded” issue in the `less` filter (#1001)
|
8
|
+
* Fixed issue that could cause the `less` filter to not generate all necessary dependencies (#1003)
|
9
|
+
|
10
|
+
Enhancements:
|
11
|
+
|
12
|
+
* Improved the way that the crash log displays the item rep that is being compiled (#1000)
|
13
|
+
|
3
14
|
## 4.4.1 (2016-11-21)
|
4
15
|
|
5
16
|
Fixes:
|
@@ -16,26 +16,11 @@ 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
|
-
# * `processing_started` — indicates that the compiler has started
|
20
|
-
# processing the specified object, which can be an item representation
|
21
|
-
# (when it is compiled) or a layout (when it is used to lay out an item
|
22
|
-
# representation or when it is used as a partial)
|
23
|
-
#
|
24
|
-
# * `processing_ended` — indicates that the compiler has finished processing
|
25
|
-
# the specified object.
|
26
|
-
#
|
27
19
|
# @api private
|
28
20
|
class Compiler
|
29
21
|
# @api private
|
30
22
|
attr_reader :site
|
31
23
|
|
32
|
-
# The compilation stack. When the compiler begins compiling a rep or a
|
33
|
-
# layout, it will be placed on the stack; when it is done compiling the
|
34
|
-
# rep or layout, it will be removed from the stack.
|
35
|
-
#
|
36
|
-
# @return [Array] The compilation stack
|
37
|
-
attr_reader :stack
|
38
|
-
|
39
24
|
# @api private
|
40
25
|
attr_reader :compiled_content_cache
|
41
26
|
|
@@ -67,8 +52,6 @@ module Nanoc::Int
|
|
67
52
|
@outdatedness_checker = outdatedness_checker
|
68
53
|
@reps = reps
|
69
54
|
@action_provider = action_provider
|
70
|
-
|
71
|
-
@stack = []
|
72
55
|
end
|
73
56
|
|
74
57
|
def run_all
|
@@ -86,7 +69,6 @@ module Nanoc::Int
|
|
86
69
|
# Determine which reps need to be recompiled
|
87
70
|
forget_dependencies_if_outdated
|
88
71
|
|
89
|
-
@stack = []
|
90
72
|
compile_reps
|
91
73
|
store
|
92
74
|
ensure
|
@@ -194,10 +176,6 @@ module Nanoc::Int
|
|
194
176
|
end
|
195
177
|
|
196
178
|
def compile_reps
|
197
|
-
# Listen to processing start/stop
|
198
|
-
Nanoc::Int::NotificationCenter.on(:processing_started, self) { |obj| @stack.push(obj) }
|
199
|
-
Nanoc::Int::NotificationCenter.on(:processing_ended, self) { |_obj| @stack.pop }
|
200
|
-
|
201
179
|
# Assign snapshots
|
202
180
|
@reps.each do |rep|
|
203
181
|
rep.snapshot_defs = action_provider.snapshots_defs_for(rep)
|
@@ -207,12 +185,14 @@ module Nanoc::Int
|
|
207
185
|
outdated_reps = @reps.select { |r| outdatedness_checker.outdated?(r) }
|
208
186
|
selector = Nanoc::Int::ItemRepSelector.new(outdated_reps)
|
209
187
|
selector.each do |rep|
|
210
|
-
|
211
|
-
compile_rep(rep)
|
188
|
+
handle_errors_while(rep) { compile_rep(rep) }
|
212
189
|
end
|
213
|
-
|
214
|
-
|
215
|
-
|
190
|
+
end
|
191
|
+
|
192
|
+
def handle_errors_while(item_rep)
|
193
|
+
yield
|
194
|
+
rescue => e
|
195
|
+
raise Nanoc::Int::Errors::CompilationError.new(e, item_rep)
|
216
196
|
end
|
217
197
|
|
218
198
|
# Compiles the given item representation.
|
@@ -250,19 +230,21 @@ module Nanoc::Int
|
|
250
230
|
|
251
231
|
fiber = @fibers[rep]
|
252
232
|
while fiber.alive?
|
253
|
-
Nanoc::Int::NotificationCenter.post(:processing_started, rep)
|
254
233
|
Nanoc::Int::NotificationCenter.post(:compilation_started, rep)
|
255
234
|
res = fiber.resume
|
256
235
|
|
257
|
-
|
236
|
+
case res
|
237
|
+
when Nanoc::Int::Errors::UnmetDependency
|
258
238
|
Nanoc::Int::NotificationCenter.post(:compilation_suspended, rep, res)
|
259
|
-
Nanoc::Int::NotificationCenter.post(:processing_ended, rep)
|
260
239
|
raise(res)
|
240
|
+
when Proc
|
241
|
+
fiber.resume(res.call)
|
242
|
+
else
|
243
|
+
# TODO: raise
|
261
244
|
end
|
262
245
|
end
|
263
246
|
|
264
247
|
Nanoc::Int::NotificationCenter.post(:compilation_ended, rep)
|
265
|
-
Nanoc::Int::NotificationCenter.post(:processing_ended, rep)
|
266
248
|
end
|
267
249
|
|
268
250
|
# @return [Boolean]
|
data/lib/nanoc/base/errors.rb
CHANGED
@@ -10,6 +10,21 @@ module Nanoc::Int
|
|
10
10
|
class GenericTrivial < Generic
|
11
11
|
end
|
12
12
|
|
13
|
+
# Error that is raised when compilation of an item rep fails. The
|
14
|
+
# underlying error is available by calling `#unwrap`.
|
15
|
+
class CompilationError < Generic
|
16
|
+
attr_reader :item_rep
|
17
|
+
|
18
|
+
def initialize(wrapped, item_rep)
|
19
|
+
@wrapped = wrapped
|
20
|
+
@item_rep = item_rep
|
21
|
+
end
|
22
|
+
|
23
|
+
def unwrap
|
24
|
+
@wrapped
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
13
28
|
# Error that is raised when a site is loaded that uses a data source with
|
14
29
|
# an unknown identifier.
|
15
30
|
class UnknownDataSource < Generic
|
@@ -1,30 +1,33 @@
|
|
1
1
|
module Nanoc::Int
|
2
2
|
# @api private
|
3
3
|
class DependencyTracker
|
4
|
+
include Nanoc::Int::ContractsSupport
|
5
|
+
|
6
|
+
C_OBJ = C::Or[Nanoc::Int::Item, Nanoc::Int::Layout]
|
7
|
+
C_ARGS = C::KeywordArgs[raw_content: C::Optional[C::Bool], attributes: C::Optional[C::Bool], compiled_content: C::Optional[C::Bool], path: C::Optional[C::Bool]]
|
8
|
+
|
4
9
|
class Null
|
5
10
|
include Nanoc::Int::ContractsSupport
|
6
11
|
|
7
|
-
contract
|
12
|
+
contract C_OBJ, C_ARGS => C::Any
|
8
13
|
def enter(_obj, raw_content: false, attributes: false, compiled_content: false, path: false)
|
9
14
|
end
|
10
15
|
|
11
|
-
contract
|
16
|
+
contract C_OBJ => C::Any
|
12
17
|
def exit
|
13
18
|
end
|
14
19
|
|
15
|
-
contract
|
20
|
+
contract C_OBJ, C_ARGS => C::Any
|
16
21
|
def bounce(_obj, raw_content: false, attributes: false, compiled_content: false, path: false)
|
17
22
|
end
|
18
23
|
end
|
19
24
|
|
20
|
-
include Nanoc::Int::ContractsSupport
|
21
|
-
|
22
25
|
def initialize(dependency_store)
|
23
26
|
@dependency_store = dependency_store
|
24
27
|
@stack = []
|
25
28
|
end
|
26
29
|
|
27
|
-
contract
|
30
|
+
contract C_OBJ, C_ARGS => C::Any
|
28
31
|
def enter(obj, raw_content: false, attributes: false, compiled_content: false, path: false)
|
29
32
|
unless @stack.empty?
|
30
33
|
Nanoc::Int::NotificationCenter.post(:dependency_created, @stack.last, obj)
|
@@ -41,12 +44,12 @@ module Nanoc::Int
|
|
41
44
|
@stack.push(obj)
|
42
45
|
end
|
43
46
|
|
44
|
-
contract
|
47
|
+
contract C_OBJ => C::Any
|
45
48
|
def exit
|
46
49
|
@stack.pop
|
47
50
|
end
|
48
51
|
|
49
|
-
contract
|
52
|
+
contract C_OBJ, C_ARGS => C::Any
|
50
53
|
def bounce(obj, raw_content: false, attributes: false, compiled_content: false, path: false)
|
51
54
|
enter(obj, raw_content: raw_content, attributes: attributes, compiled_content: compiled_content, path: path)
|
52
55
|
exit
|
@@ -70,9 +70,7 @@ module Nanoc
|
|
70
70
|
@dependency_tracker.bounce(layout, raw_content: true)
|
71
71
|
|
72
72
|
begin
|
73
|
-
|
74
|
-
Nanoc::Int::NotificationCenter.post(:processing_started, layout)
|
75
|
-
Nanoc::Int::NotificationCenter.post(:filtering_started, rep, filter_name)
|
73
|
+
Nanoc::Int::NotificationCenter.post(:filtering_started, rep, filter_name)
|
76
74
|
|
77
75
|
# Layout
|
78
76
|
content = layout.content
|
@@ -83,9 +81,7 @@ module Nanoc
|
|
83
81
|
# Create "post" snapshot
|
84
82
|
snapshot(rep, :post, final: false)
|
85
83
|
ensure
|
86
|
-
|
87
|
-
Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, filter_name)
|
88
|
-
Nanoc::Int::NotificationCenter.post(:processing_ended, layout)
|
84
|
+
Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, filter_name)
|
89
85
|
end
|
90
86
|
end
|
91
87
|
|
@@ -184,6 +184,11 @@ module Nanoc
|
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
187
|
+
# @api private
|
188
|
+
def on_main_fiber(&block)
|
189
|
+
Fiber.yield(block)
|
190
|
+
end
|
191
|
+
|
187
192
|
# Creates a dependency from the item that is currently being filtered onto
|
188
193
|
# the given collection of items. In other words, require the given items
|
189
194
|
# to be compiled first before this items is processed.
|
@@ -17,8 +17,8 @@ module Nanoc::Int
|
|
17
17
|
begin
|
18
18
|
yield(rep)
|
19
19
|
graph.delete_vertex(rep)
|
20
|
-
rescue
|
21
|
-
|
20
|
+
rescue => e
|
21
|
+
handle_error(e, rep, graph)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -28,6 +28,21 @@ module Nanoc::Int
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
def handle_error(e, rep, graph)
|
32
|
+
actual_error =
|
33
|
+
if e.is_a?(Nanoc::Int::Errors::CompilationError)
|
34
|
+
e.unwrap
|
35
|
+
else
|
36
|
+
e
|
37
|
+
end
|
38
|
+
|
39
|
+
if actual_error.is_a?(Nanoc::Int::Errors::UnmetDependency)
|
40
|
+
handle_dependency_error(actual_error, rep, graph)
|
41
|
+
else
|
42
|
+
raise(e)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
31
46
|
def handle_dependency_error(e, rep, graph)
|
32
47
|
other_rep = e.rep
|
33
48
|
graph.add_edge(other_rep, rep)
|
@@ -113,7 +113,7 @@ module Nanoc::CLI
|
|
113
113
|
|
114
114
|
# Sections
|
115
115
|
write_error_message(stream, error)
|
116
|
-
|
116
|
+
write_item_rep(stream, error)
|
117
117
|
write_stack_trace(stream, error)
|
118
118
|
|
119
119
|
# Issue link
|
@@ -133,7 +133,7 @@ module Nanoc::CLI
|
|
133
133
|
|
134
134
|
# Sections
|
135
135
|
write_error_message(stream, error, verbose: true)
|
136
|
-
|
136
|
+
write_item_rep(stream, error, verbose: true)
|
137
137
|
write_stack_trace(stream, error, verbose: true)
|
138
138
|
write_version_information(stream, verbose: true)
|
139
139
|
write_system_information(stream, verbose: true)
|
@@ -161,11 +161,6 @@ module Nanoc::CLI
|
|
161
161
|
site && site.compiler
|
162
162
|
end
|
163
163
|
|
164
|
-
# @return [Array] The current compilation stack
|
165
|
-
def stack
|
166
|
-
(compiler && compiler.stack) || []
|
167
|
-
end
|
168
|
-
|
169
164
|
# @return [Hash<String, Array>] A hash containing the gem names as keys and gem versions as value
|
170
165
|
def gems_and_versions
|
171
166
|
gems = {}
|
@@ -216,6 +211,8 @@ module Nanoc::CLI
|
|
216
211
|
#
|
217
212
|
# @return [String] The resolution for the given error
|
218
213
|
def resolution_for(error)
|
214
|
+
error = unwrap_error(error)
|
215
|
+
|
219
216
|
case error
|
220
217
|
when LoadError
|
221
218
|
# Get gem name
|
@@ -257,30 +254,28 @@ module Nanoc::CLI
|
|
257
254
|
def write_error_message(stream, error, verbose: false)
|
258
255
|
write_section_header(stream, 'Message', verbose: verbose)
|
259
256
|
|
257
|
+
error = unwrap_error(error)
|
258
|
+
|
260
259
|
stream.puts "#{error.class}: #{error.message}"
|
261
260
|
resolution = resolution_for(error)
|
262
261
|
stream.puts resolution.to_s if resolution
|
263
262
|
end
|
264
263
|
|
265
|
-
def
|
266
|
-
|
264
|
+
def write_item_rep(stream, error, verbose: false)
|
265
|
+
return unless error.is_a?(Nanoc::Int::Errors::CompilationError)
|
267
266
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
stream.puts " - [item] #{obj.item.identifier} (rep #{obj.name})"
|
274
|
-
else # layout
|
275
|
-
stream.puts " - [layout] #{obj.identifier}"
|
276
|
-
end
|
277
|
-
end
|
278
|
-
end
|
267
|
+
write_section_header(stream, 'Item being compiled', verbose: verbose)
|
268
|
+
|
269
|
+
item_rep = error.item_rep
|
270
|
+
stream.puts "Item identifier: #{item_rep.item.identifier}"
|
271
|
+
stream.puts "Item rep name: #{item_rep.name.inspect}"
|
279
272
|
end
|
280
273
|
|
281
274
|
def write_stack_trace(stream, error, verbose: false)
|
282
275
|
write_section_header(stream, 'Stack trace', verbose: verbose)
|
283
276
|
|
277
|
+
error = unwrap_error(error)
|
278
|
+
|
284
279
|
count = verbose ? -1 : 10
|
285
280
|
error.backtrace[0...count].each_with_index do |item, index|
|
286
281
|
stream.puts " #{index}. #{item}"
|
@@ -330,5 +325,14 @@ module Nanoc::CLI
|
|
330
325
|
stream.puts " #{index}. #{i}"
|
331
326
|
end
|
332
327
|
end
|
328
|
+
|
329
|
+
def unwrap_error(e)
|
330
|
+
case e
|
331
|
+
when Nanoc::Int::Errors::CompilationError
|
332
|
+
e.unwrap
|
333
|
+
else
|
334
|
+
e
|
335
|
+
end
|
336
|
+
end
|
333
337
|
end
|
334
338
|
end
|
data/lib/nanoc/filters/less.rb
CHANGED
@@ -10,41 +10,65 @@ module Nanoc::Filters
|
|
10
10
|
#
|
11
11
|
# @return [String] The filtered content
|
12
12
|
def run(content, params = {})
|
13
|
-
#
|
13
|
+
# Create dependencies
|
14
|
+
imported_filenames = imported_filenames_from(content)
|
15
|
+
imported_items = imported_filenames_to_items(imported_filenames)
|
16
|
+
depend_on(imported_items)
|
17
|
+
|
18
|
+
# Add filename to load path
|
19
|
+
paths = [File.dirname(@item[:content_filename])]
|
20
|
+
on_main_fiber do
|
21
|
+
parser = ::Less::Parser.new(paths: paths)
|
22
|
+
parser.parse(content).to_css(params)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def imported_filenames_from(content)
|
14
27
|
imports = []
|
15
28
|
imports.concat(content.scan(/^@import\s+(["'])([^\1]+?)\1;/))
|
16
29
|
imports.concat(content.scan(/^@import\s+url\((["']?)([^)]+?)\1\);/))
|
17
|
-
imported_filenames = imports.map do |i|
|
18
|
-
i[1] =~ /\.(less|css)$/ ? i[1] : i[1] + '.less'
|
19
|
-
end
|
20
30
|
|
21
|
-
|
22
|
-
|
23
|
-
# Find directory for this item
|
24
|
-
current_dir_pathname = Pathname.new(@item[:content_filename]).dirname.realpath
|
31
|
+
imports.map { |i| i[1] =~ /\.(less|css)$/ ? i[1] : i[1] + '.less' }
|
32
|
+
end
|
25
33
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
34
|
+
def imported_filenames_to_items(imported_filenames)
|
35
|
+
item_dir_path = Pathname.new(@item[:content_filename]).dirname.realpath
|
36
|
+
cwd = Pathname.pwd # FIXME: ugly (get site dir instead)
|
37
|
+
|
38
|
+
imported_filenames.map do |filename|
|
39
|
+
full_paths = Set.new
|
40
|
+
|
41
|
+
imported_pathname = Pathname.new(filename)
|
42
|
+
full_paths << find_file(imported_pathname, item_dir_path)
|
43
|
+
full_paths << find_file(imported_pathname, cwd)
|
33
44
|
|
34
45
|
# Find matching item
|
35
46
|
@items.find do |i|
|
36
47
|
next if i[:content_filename].nil?
|
37
|
-
Pathname.new(i[:content_filename]).realpath
|
48
|
+
item_path = Pathname.new(i[:content_filename]).realpath
|
49
|
+
full_paths.any? { |fp| fp == item_path }
|
38
50
|
end
|
39
51
|
end.compact
|
52
|
+
end
|
40
53
|
|
41
|
-
|
42
|
-
|
54
|
+
# @param [Pathname] pathname Pathname of the file to find. Can be relative or absolute.
|
55
|
+
#
|
56
|
+
# @param [Pathname] root_pathname Directory pathname from which the search will start.
|
57
|
+
#
|
58
|
+
# @return [String, nil] A string containing the full path if a file is found, otherwise nil.
|
59
|
+
def find_file(pathname, root_pathname)
|
60
|
+
absolute_pathname =
|
61
|
+
if pathname.relative?
|
62
|
+
root_pathname + pathname
|
63
|
+
else
|
64
|
+
pathname
|
65
|
+
end
|
43
66
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
67
|
+
if absolute_pathname.exist?
|
68
|
+
absolute_pathname.realpath
|
69
|
+
else
|
70
|
+
nil
|
71
|
+
end
|
48
72
|
end
|
49
73
|
end
|
50
74
|
end
|
@@ -47,28 +47,20 @@ module Nanoc::Helpers
|
|
47
47
|
# Create filter
|
48
48
|
filter = filter_class.new(assigns)
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
# Layout
|
51
|
+
content = layout.content
|
52
|
+
arg = content.binary? ? content.filename : content.string
|
53
|
+
result = filter.setup_and_run(arg, filter_args)
|
53
54
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
erbout << result
|
64
|
-
''
|
65
|
-
else
|
66
|
-
# Return result
|
67
|
-
result
|
68
|
-
end
|
69
|
-
ensure
|
70
|
-
# Notify end
|
71
|
-
Nanoc::Int::NotificationCenter.post(:processing_ended, layout)
|
55
|
+
# Append to erbout if we have a block
|
56
|
+
if block_given?
|
57
|
+
# Append result and return nothing
|
58
|
+
erbout = eval('_erbout', block.binding)
|
59
|
+
erbout << result
|
60
|
+
''
|
61
|
+
else
|
62
|
+
# Return result
|
63
|
+
result
|
72
64
|
end
|
73
65
|
end
|
74
66
|
end
|
data/lib/nanoc/version.rb
CHANGED
@@ -46,7 +46,42 @@ class Nanoc::CLI::ErrorHandlerTest < Nanoc::TestCase
|
|
46
46
|
refute_match(/See full crash log for details./, stream.string)
|
47
47
|
end
|
48
48
|
|
49
|
-
def
|
49
|
+
def test_write_error_message_wrapped
|
50
|
+
stream = StringIO.new
|
51
|
+
@handler.send(:write_error_message, stream, new_wrapped_error(new_error), verbose: true)
|
52
|
+
refute_match(/CompilationError/, stream.string)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_write_stack_trace_wrapped
|
56
|
+
stream = StringIO.new
|
57
|
+
@handler.send(:write_stack_trace, stream, new_wrapped_error(new_error), verbose: false)
|
58
|
+
assert_match(/new_error/, stream.string)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_write_item_rep
|
62
|
+
stream = StringIO.new
|
63
|
+
@handler.send(:write_item_rep, stream, new_wrapped_error(new_error), verbose: false)
|
64
|
+
assert_match(/^Item identifier: \/about\.md$/, stream.string)
|
65
|
+
assert_match(/^Item rep name: :latex$/, stream.string)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_resolution_for_wrapped
|
69
|
+
def @handler.using_bundler?
|
70
|
+
true
|
71
|
+
end
|
72
|
+
error = new_wrapped_error(LoadError.new('no such file to load -- kramdown'))
|
73
|
+
assert_match(/^Make sure the gem is added to Gemfile/, @handler.send(:resolution_for, error))
|
74
|
+
end
|
75
|
+
|
76
|
+
def new_wrapped_error(wrapped)
|
77
|
+
item = Nanoc::Int::Item.new('asdf', {}, '/about.md')
|
78
|
+
item_rep = Nanoc::Int::ItemRep.new(item, :latex)
|
79
|
+
raise Nanoc::Int::Errors::CompilationError.new(wrapped, item_rep)
|
80
|
+
rescue => e
|
81
|
+
return e
|
82
|
+
end
|
83
|
+
|
84
|
+
def new_error(amount_factor = 1)
|
50
85
|
backtrace_generator = lambda do |af|
|
51
86
|
if af.zero?
|
52
87
|
raise 'finally!'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nanoc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.4.
|
4
|
+
version: 4.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Defreyne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cri
|
@@ -374,7 +374,6 @@ files:
|
|
374
374
|
- test/filters/test_haml.rb
|
375
375
|
- test/filters/test_handlebars.rb
|
376
376
|
- test/filters/test_kramdown.rb
|
377
|
-
- test/filters/test_less.rb
|
378
377
|
- test/filters/test_markaby.rb
|
379
378
|
- test/filters/test_maruku.rb
|
380
379
|
- test/filters/test_mustache.rb
|
data/test/filters/test_less.rb
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
class Nanoc::Filters::LessTest < Nanoc::TestCase
|
2
|
-
def view_context
|
3
|
-
dependency_tracker = Nanoc::Int::DependencyTracker.new(nil)
|
4
|
-
Nanoc::ViewContext.new(reps: nil, items: nil, dependency_tracker: dependency_tracker, compiler: nil)
|
5
|
-
end
|
6
|
-
|
7
|
-
def test_filter
|
8
|
-
if_have 'less' do
|
9
|
-
# Create item
|
10
|
-
@item = Nanoc::ItemWithRepsView.new(Nanoc::Int::Item.new('blah', { content_filename: 'content/foo/bar.txt' }, '/foo/bar/'), view_context)
|
11
|
-
|
12
|
-
# Create filter
|
13
|
-
filter = ::Nanoc::Filters::Less.new(item: @item, items: [@item])
|
14
|
-
|
15
|
-
# Run filter
|
16
|
-
result = filter.setup_and_run('.foo { bar: 1 + 1 }')
|
17
|
-
assert_match(/\.foo\s*\{\s*bar:\s*2;?\s*\}/, result)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_filter_with_paths_relative_to_site_directory
|
22
|
-
if_have 'less' do
|
23
|
-
# Create file to import
|
24
|
-
FileUtils.mkdir_p('content/foo/bar')
|
25
|
-
File.open('content/foo/bar/imported_file.less', 'w') { |io| io.write('p { color: red; }') }
|
26
|
-
|
27
|
-
# Create item
|
28
|
-
@item = Nanoc::ItemWithRepsView.new(Nanoc::Int::Item.new('blah', { content_filename: 'content/foo/bar.txt' }, '/foo/bar/'), view_context)
|
29
|
-
|
30
|
-
# Create filter
|
31
|
-
filter = ::Nanoc::Filters::Less.new(item: @item, items: [@item])
|
32
|
-
|
33
|
-
# Run filter
|
34
|
-
result = filter.setup_and_run('@import "content/foo/bar/imported_file.less";')
|
35
|
-
assert_match(/p\s*\{\s*color:\s*red;?\s*\}/, result)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_filter_with_paths_relative_to_current_file
|
40
|
-
if_have 'less' do
|
41
|
-
# Create file to import
|
42
|
-
FileUtils.mkdir_p('content/foo/bar')
|
43
|
-
File.open('content/foo/bar/imported_file.less', 'w') { |io| io.write('p { color: red; }') }
|
44
|
-
|
45
|
-
# Create item
|
46
|
-
File.open('content/foo/bar.txt', 'w') { |io| io.write('meh') }
|
47
|
-
@item = Nanoc::ItemWithRepsView.new(Nanoc::Int::Item.new('blah', { content_filename: 'content/foo/bar.txt' }, '/foo/bar/'), view_context)
|
48
|
-
|
49
|
-
# Create filter
|
50
|
-
filter = ::Nanoc::Filters::Less.new(item: @item, items: [@item])
|
51
|
-
|
52
|
-
# Run filter
|
53
|
-
result = filter.setup_and_run('@import "bar/imported_file.less";')
|
54
|
-
assert_match(/p\s*\{\s*color:\s*red;?\s*\}/, result)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def test_compression
|
59
|
-
if_have 'less' do
|
60
|
-
# Create item
|
61
|
-
@item = Nanoc::ItemWithRepsView.new(Nanoc::Int::Item.new('blah', { content_filename: 'content/foo/bar.txt' }, '/foo/bar/'), view_context)
|
62
|
-
|
63
|
-
# Create filter
|
64
|
-
filter = ::Nanoc::Filters::Less.new(item: @item, items: [@item])
|
65
|
-
|
66
|
-
# Run filter with compress option
|
67
|
-
result = filter.setup_and_run('.foo { bar: a; } .bar { foo: b; }', compress: true)
|
68
|
-
assert_match(/^\.foo\{bar:a\}\n?\.bar\{foo:b\}/, result)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|