nanoc 4.4.1 → 4.4.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d2b9d8ce47580844e86624db8a37b07a0cb016a8
4
- data.tar.gz: 378d2207727e627067221f9aeb53fa6cbd75401e
3
+ metadata.gz: 321bc54ed62384061039f82d10745b494012e4ff
4
+ data.tar.gz: ec7e38daa14af1a0b6cc64bd71e3492585de9865
5
5
  SHA512:
6
- metadata.gz: a5da522b136025a8c2a114b3e59197879290f57d1879998dafbd2130ed3b1ed1374034d524a25d17c7143f5058b4cfed06558fccedaed71deeb140f00130f30d
7
- data.tar.gz: b4f5e54d978ea6da8b805adfaa24e5f143e4ad6d3ffb7ec3248ceaabe5f9b35ffac0a53a0332ac3d4ee25ebe6a699c20a43022902618ca153481f0ba2f9427b0
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.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.10.0)
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.15)
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.17)
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.0)
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.0)
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.9.0)
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.4.0)
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.1)
324
+ thor (0.19.3)
325
325
  tilt (2.0.5)
326
326
  timecop (0.8.1)
327
- tins (1.12.0)
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
- @stack = []
211
- compile_rep(rep)
188
+ handle_errors_while(rep) { compile_rep(rep) }
212
189
  end
213
- ensure
214
- Nanoc::Int::NotificationCenter.remove(:processing_started, self)
215
- Nanoc::Int::NotificationCenter.remove(:processing_ended, self)
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
- if res.is_a?(Nanoc::Int::Errors::UnmetDependency)
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]
@@ -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 C::Or[Nanoc::Int::Item, Nanoc::Int::Layout], C::KeywordArgs[raw_content: C::Optional[C::Bool], attributes: C::Optional[C::Bool], compiled_content: C::Optional[C::Bool], path: C::Optional[C::Bool]] => C::Any
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 C::None => C::Any
16
+ contract C_OBJ => C::Any
12
17
  def exit
13
18
  end
14
19
 
15
- contract C::Or[Nanoc::Int::Item, Nanoc::Int::Layout], C::KeywordArgs[raw_content: C::Optional[C::Bool], attributes: C::Optional[C::Bool], compiled_content: C::Optional[C::Bool], path: C::Optional[C::Bool]] => C::Any
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 C::Or[Nanoc::Int::Item, Nanoc::Int::Layout], C::KeywordArgs[raw_content: C::Optional[C::Bool], attributes: C::Optional[C::Bool], compiled_content: C::Optional[C::Bool], path: C::Optional[C::Bool]] => C::Any
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 C::None => C::Any
47
+ contract C_OBJ => C::Any
45
48
  def exit
46
49
  @stack.pop
47
50
  end
48
51
 
49
- contract C::Or[Nanoc::Int::Item, Nanoc::Int::Layout], C::KeywordArgs[raw_content: C::Optional[C::Bool], attributes: C::Optional[C::Bool], compiled_content: C::Optional[C::Bool], path: C::Optional[C::Bool]] => C::Any
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
- # Notify start
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
- # Notify end
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 Nanoc::Int::Errors::UnmetDependency => e
21
- handle_dependency_error(e, rep, graph)
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)
@@ -65,12 +65,5 @@ module Nanoc::CLI
65
65
  def debug?
66
66
  Nanoc::CLI.debug?
67
67
  end
68
-
69
- protected
70
-
71
- # @return [Array] The compilation stack.
72
- def stack
73
- (site && site.compiler.stack) || []
74
- end
75
68
  end
76
69
  end
@@ -113,7 +113,7 @@ module Nanoc::CLI
113
113
 
114
114
  # Sections
115
115
  write_error_message(stream, error)
116
- write_compilation_stack(stream, error)
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
- write_compilation_stack(stream, error, verbose: true)
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 write_compilation_stack(stream, _error, verbose: false)
266
- write_section_header(stream, 'Compilation stack', verbose: verbose)
264
+ def write_item_rep(stream, error, verbose: false)
265
+ return unless error.is_a?(Nanoc::Int::Errors::CompilationError)
267
266
 
268
- if stack.empty?
269
- stream.puts ' (empty)'
270
- else
271
- stack.reverse_each do |obj|
272
- if obj.is_a?(Nanoc::Int::ItemRep)
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
@@ -10,41 +10,65 @@ module Nanoc::Filters
10
10
  #
11
11
  # @return [String] The filtered content
12
12
  def run(content, params = {})
13
- # Find imports (hacky)
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
- # Convert to items
22
- imported_items = imported_filenames.map do |filename|
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
- # Find absolute pathname for imported item
27
- imported_pathname = Pathname.new(filename)
28
- if imported_pathname.relative?
29
- imported_pathname = current_dir_pathname + imported_pathname
30
- end
31
- next unless imported_pathname.exist?
32
- imported_filename = imported_pathname.realpath
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 == imported_filename
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
- # Create dependencies
42
- depend_on(imported_items)
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
- # Add filename to load path
45
- paths = [File.dirname(@item[:content_filename])]
46
- parser = ::Less::Parser.new(paths: paths)
47
- parser.parse(content).to_css params
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
- begin
51
- # Notify start
52
- Nanoc::Int::NotificationCenter.post(:processing_started, layout)
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
- # Layout
55
- content = layout.content
56
- arg = content.binary? ? content.filename : content.string
57
- result = filter.setup_and_run(arg, filter_args)
58
-
59
- # Append to erbout if we have a block
60
- if block_given?
61
- # Append result and return nothing
62
- erbout = eval('_erbout', block.binding)
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
@@ -1,4 +1,4 @@
1
1
  module Nanoc
2
2
  # The current Nanoc version.
3
- VERSION = '4.4.1'.freeze
3
+ VERSION = '4.4.2'.freeze
4
4
  end
@@ -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 new_error(amount_factor)
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.1
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-21 00:00:00.000000000 Z
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
@@ -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