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 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