nanoc 4.11.12 → 4.11.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +7 -1
  3. data/bin/nanoc +1 -1
  4. data/lib/nanoc.rb +2 -27
  5. data/lib/nanoc/base.rb +3 -6
  6. data/lib/nanoc/base/errors.rb +6 -104
  7. data/lib/nanoc/checking/check.rb +4 -4
  8. data/lib/nanoc/checking/checks/external_links.rb +1 -1
  9. data/lib/nanoc/checking/checks/stale.rb +1 -1
  10. data/lib/nanoc/checking/runner.rb +2 -2
  11. data/lib/nanoc/data_sources/filesystem/tools.rb +4 -4
  12. data/lib/nanoc/extra.rb +1 -1
  13. data/lib/nanoc/helpers/blogging.rb +8 -8
  14. data/lib/nanoc/helpers/capturing.rb +1 -1
  15. data/lib/nanoc/helpers/link_to.rb +1 -1
  16. data/lib/nanoc/orig_cli.rb +20 -0
  17. data/lib/nanoc/{cli → orig_cli}/commands/check.rb +3 -3
  18. data/lib/nanoc/{cli → orig_cli}/commands/deploy.rb +8 -8
  19. data/lib/nanoc/{cli → orig_cli}/commands/show-rules.rb +3 -3
  20. data/lib/nanoc/rule_dsl/action_provider.rb +5 -5
  21. data/lib/nanoc/rule_dsl/action_recorder.rb +4 -4
  22. data/lib/nanoc/rule_dsl/compilation_rule_context.rb +1 -1
  23. data/lib/nanoc/rule_dsl/compiler_dsl.rb +1 -1
  24. data/lib/nanoc/rule_dsl/rule_context.rb +6 -6
  25. data/lib/nanoc/version.rb +1 -1
  26. metadata +13 -152
  27. data/lib/nanoc/base/error.rb +0 -7
  28. data/lib/nanoc/base/feature.rb +0 -104
  29. data/lib/nanoc/base/repos.rb +0 -4
  30. data/lib/nanoc/base/repos/config_loader.rb +0 -95
  31. data/lib/nanoc/base/repos/site_loader.rb +0 -102
  32. data/lib/nanoc/base/services.rb +0 -23
  33. data/lib/nanoc/base/services/compiler.rb +0 -214
  34. data/lib/nanoc/base/services/compiler/phases.rb +0 -19
  35. data/lib/nanoc/base/services/compiler/phases/abstract.rb +0 -50
  36. data/lib/nanoc/base/services/compiler/phases/cache.rb +0 -45
  37. data/lib/nanoc/base/services/compiler/phases/mark_done.rb +0 -25
  38. data/lib/nanoc/base/services/compiler/phases/notify.rb +0 -21
  39. data/lib/nanoc/base/services/compiler/phases/recalculate.rb +0 -51
  40. data/lib/nanoc/base/services/compiler/phases/resume.rb +0 -54
  41. data/lib/nanoc/base/services/compiler/phases/write.rb +0 -86
  42. data/lib/nanoc/base/services/compiler/stages.rb +0 -23
  43. data/lib/nanoc/base/services/compiler/stages/build_reps.rb +0 -38
  44. data/lib/nanoc/base/services/compiler/stages/calculate_checksums.rb +0 -44
  45. data/lib/nanoc/base/services/compiler/stages/cleanup.rb +0 -45
  46. data/lib/nanoc/base/services/compiler/stages/compile_reps.rb +0 -98
  47. data/lib/nanoc/base/services/compiler/stages/determine_outdatedness.rb +0 -51
  48. data/lib/nanoc/base/services/compiler/stages/forget_outdated_dependencies.rb +0 -22
  49. data/lib/nanoc/base/services/compiler/stages/load_stores.rb +0 -37
  50. data/lib/nanoc/base/services/compiler/stages/postprocess.rb +0 -23
  51. data/lib/nanoc/base/services/compiler/stages/preprocess.rb +0 -34
  52. data/lib/nanoc/base/services/compiler/stages/prune.rb +0 -32
  53. data/lib/nanoc/base/services/compiler/stages/store_post_compilation_state.rb +0 -22
  54. data/lib/nanoc/base/services/compiler/stages/store_pre_compilation_state.rb +0 -34
  55. data/lib/nanoc/base/services/compiler_loader.rb +0 -48
  56. data/lib/nanoc/base/services/executor.rb +0 -134
  57. data/lib/nanoc/base/services/filter.rb +0 -267
  58. data/lib/nanoc/base/services/item_rep_builder.rb +0 -54
  59. data/lib/nanoc/base/services/item_rep_selector.rb +0 -69
  60. data/lib/nanoc/base/services/item_rep_writer.rb +0 -86
  61. data/lib/nanoc/base/services/outdatedness_checker.rb +0 -222
  62. data/lib/nanoc/base/services/outdatedness_rules.rb +0 -18
  63. data/lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb +0 -41
  64. data/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb +0 -31
  65. data/lib/nanoc/base/services/outdatedness_rules/content_modified.rb +0 -21
  66. data/lib/nanoc/base/services/outdatedness_rules/item_collection_extended.rb +0 -20
  67. data/lib/nanoc/base/services/outdatedness_rules/layout_collection_extended.rb +0 -20
  68. data/lib/nanoc/base/services/outdatedness_rules/not_written.rb +0 -17
  69. data/lib/nanoc/base/services/outdatedness_rules/rules_modified.rb +0 -45
  70. data/lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb +0 -26
  71. data/lib/nanoc/base/services/pruner.rb +0 -123
  72. data/lib/nanoc/base/views.rb +0 -40
  73. data/lib/nanoc/base/views/basic_item_rep_collection_view.rb +0 -86
  74. data/lib/nanoc/base/views/basic_item_rep_view.rb +0 -81
  75. data/lib/nanoc/base/views/basic_item_view.rb +0 -52
  76. data/lib/nanoc/base/views/compilation_item_rep_collection_view.rb +0 -10
  77. data/lib/nanoc/base/views/compilation_item_rep_view.rb +0 -49
  78. data/lib/nanoc/base/views/compilation_item_view.rb +0 -45
  79. data/lib/nanoc/base/views/config_view.rb +0 -68
  80. data/lib/nanoc/base/views/identifiable_collection_view.rb +0 -109
  81. data/lib/nanoc/base/views/item_collection_with_reps_view.rb +0 -10
  82. data/lib/nanoc/base/views/item_collection_without_reps_view.rb +0 -10
  83. data/lib/nanoc/base/views/layout_collection_view.rb +0 -10
  84. data/lib/nanoc/base/views/layout_view.rb +0 -7
  85. data/lib/nanoc/base/views/mixins/document_view_mixin.rb +0 -88
  86. data/lib/nanoc/base/views/mixins/mutable_document_view_mixin.rb +0 -58
  87. data/lib/nanoc/base/views/mutable_config_view.rb +0 -14
  88. data/lib/nanoc/base/views/mutable_identifiable_collection_view.rb +0 -17
  89. data/lib/nanoc/base/views/mutable_item_collection_view.rb +0 -32
  90. data/lib/nanoc/base/views/mutable_item_view.rb +0 -7
  91. data/lib/nanoc/base/views/mutable_layout_collection_view.rb +0 -24
  92. data/lib/nanoc/base/views/mutable_layout_view.rb +0 -7
  93. data/lib/nanoc/base/views/post_compile_item_collection_view.rb +0 -10
  94. data/lib/nanoc/base/views/post_compile_item_rep_collection_view.rb +0 -10
  95. data/lib/nanoc/base/views/post_compile_item_rep_view.rb +0 -31
  96. data/lib/nanoc/base/views/post_compile_item_view.rb +0 -18
  97. data/lib/nanoc/base/views/view.rb +0 -41
  98. data/lib/nanoc/cli.rb +0 -241
  99. data/lib/nanoc/cli/ansi_string_colorizer.rb +0 -28
  100. data/lib/nanoc/cli/cleaning_stream.rb +0 -160
  101. data/lib/nanoc/cli/command_runner.rb +0 -72
  102. data/lib/nanoc/cli/commands/compile.rb +0 -57
  103. data/lib/nanoc/cli/commands/compile_listeners/abstract.rb +0 -58
  104. data/lib/nanoc/cli/commands/compile_listeners/aggregate.rb +0 -50
  105. data/lib/nanoc/cli/commands/compile_listeners/debug_printer.rb +0 -100
  106. data/lib/nanoc/cli/commands/compile_listeners/diff_generator.rb +0 -101
  107. data/lib/nanoc/cli/commands/compile_listeners/file_action_printer.rb +0 -76
  108. data/lib/nanoc/cli/commands/compile_listeners/timing_recorder.rb +0 -170
  109. data/lib/nanoc/cli/commands/create-site.rb +0 -257
  110. data/lib/nanoc/cli/commands/nanoc.rb +0 -42
  111. data/lib/nanoc/cli/commands/prune.rb +0 -49
  112. data/lib/nanoc/cli/commands/shell.rb +0 -57
  113. data/lib/nanoc/cli/commands/show-data.rb +0 -185
  114. data/lib/nanoc/cli/commands/show-plugins.rb +0 -89
  115. data/lib/nanoc/cli/commands/view.rb +0 -68
  116. data/lib/nanoc/cli/error_handler.rb +0 -365
  117. data/lib/nanoc/cli/logger.rb +0 -75
  118. data/lib/nanoc/cli/stack_trace_writer.rb +0 -50
  119. data/lib/nanoc/cli/stream_cleaners.rb +0 -10
  120. data/lib/nanoc/cli/stream_cleaners/abstract.rb +0 -21
  121. data/lib/nanoc/cli/stream_cleaners/ansi_colors.rb +0 -13
  122. data/lib/nanoc/cli/stream_cleaners/utf8.rb +0 -17
  123. data/lib/nanoc/cli/transform.rb +0 -16
  124. data/lib/nanoc/spec.rb +0 -240
@@ -1,365 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Nanoc::CLI
4
- # Catches errors and prints nice diagnostic messages, then exits.
5
- #
6
- # @api private
7
- class ErrorHandler
8
- # Enables error handling in the given block.
9
- #
10
- # @return [void]
11
- def self.handle_while(exit_on_error: true)
12
- if @disabled
13
- yield
14
- else
15
- new.handle_while(exit_on_error: exit_on_error) { yield }
16
- end
17
- end
18
-
19
- # Disables error handling. This is used by the test cases to prevent error
20
- # from being handled by the CLI while tests are running.
21
- def self.disable
22
- @disabled = true
23
- end
24
-
25
- # Re-enables error handling after it was disabled. This is used by the test
26
- # cases to prevent error from being handled by the CLI while tests are
27
- # running.
28
- def self.enable
29
- @disabled = false
30
- end
31
-
32
- # Enables error handling in the given block. This method should not be
33
- # called directly; use {Nanoc::CLI::ErrorHandler.handle_while} instead.
34
- #
35
- # @return [void]
36
- def handle_while(exit_on_error:)
37
- # Set exit handler
38
- %w[INT TERM].each do |signal|
39
- Signal.trap(signal) do
40
- puts
41
- exit!(0)
42
- end
43
- end
44
-
45
- # Set stack trace dump handler
46
- if !defined?(RUBY_ENGINE) || RUBY_ENGINE != 'jruby'
47
- begin
48
- Signal.trap('USR1') do
49
- puts 'Caught USR1; dumping a stack trace'
50
- puts caller.map { |i| " #{i}" }.join("\n")
51
- end
52
- rescue ArgumentError
53
- end
54
- end
55
-
56
- # Run
57
- yield
58
- rescue Interrupt
59
- exit(1)
60
- rescue StandardError, ScriptError => e
61
- handle_error(e, exit_on_error: exit_on_error)
62
- end
63
-
64
- def handle_error(error, exit_on_error:)
65
- if trivial?(error)
66
- $stderr.puts
67
- $stderr.puts "Error: #{error.message}"
68
- resolution = resolution_for(error)
69
- if resolution
70
- $stderr.puts
71
- $stderr.puts resolution
72
- end
73
- else
74
- print_error(error)
75
- end
76
- exit(1) if exit_on_error
77
- end
78
-
79
- # Prints the given error to stderr. Includes message, possible resolution
80
- # (see {#resolution_for}), compilation stack, backtrace, etc.
81
- #
82
- # @param [Error] error The error that should be described
83
- #
84
- # @return [void]
85
- def self.print_error(error)
86
- new.print_error(error)
87
- end
88
-
89
- # Prints the given error to stderr. Includes message, possible resolution
90
- # (see {#resolution_for}), compilation stack, backtrace, etc.
91
- #
92
- # @param [Error] error The error that should be described
93
- #
94
- # @return [void]
95
- def print_error(error)
96
- write_compact_error(error, $stderr)
97
-
98
- File.open('crash.log', 'w') do |io|
99
- cio = Nanoc::CLI.wrap_in_cleaning_stream(io)
100
- cio.add_stream_cleaner(::Nanoc::CLI::StreamCleaners::ANSIColors)
101
- write_verbose_error(error, cio)
102
- end
103
- end
104
-
105
- # Writes a compact representation of the error, suitable for a terminal, on
106
- # the given stream (probably stderr).
107
- #
108
- # @param [Error] error The error that should be described
109
- #
110
- # @param [IO] stream The stream to write the description too
111
- #
112
- # @return [void]
113
- def write_compact_error(error, stream)
114
- stream.puts
115
- stream.puts 'Captain! We’ve been hit!'
116
-
117
- if forwards_stack_trace?
118
- write_stack_trace(stream, error)
119
- write_error_message(stream, error)
120
- write_item_rep(stream, error)
121
- else
122
- write_error_message(stream, error)
123
- write_item_rep(stream, error)
124
- write_stack_trace(stream, error)
125
- end
126
-
127
- stream.puts
128
- stream.puts 'A detailed crash log has been written to ./crash.log.'
129
- end
130
-
131
- # Writes a verbose representation of the error on the given stream.
132
- #
133
- # @param [Error] error The error that should be described
134
- #
135
- # @param [IO] stream The stream to write the description too
136
- #
137
- # @return [void]
138
- def write_verbose_error(error, stream)
139
- stream.puts "Crashlog created at #{Time.now}"
140
-
141
- write_error_message(stream, error, verbose: true)
142
- write_item_rep(stream, error, verbose: true)
143
- write_stack_trace(stream, error, verbose: true)
144
- write_version_information(stream, verbose: true)
145
- write_system_information(stream, verbose: true)
146
- write_installed_gems(stream, verbose: true)
147
- write_gemfile_lock(stream, verbose: true)
148
- write_load_paths(stream, verbose: true)
149
- end
150
-
151
- # @api private
152
- def forwards_stack_trace?
153
- ruby_version.start_with?('2.5')
154
- end
155
-
156
- # @api private
157
- def trivial?(error)
158
- case error
159
- when Nanoc::Int::Errors::GenericTrivial, Errno::EADDRINUSE
160
- true
161
- when LoadError
162
- GEM_NAMES.key?(gem_name_from_load_error(error))
163
- else
164
- false
165
- end
166
- end
167
-
168
- protected
169
-
170
- # @return [Hash<String, Array>] A hash containing the gem names as keys and gem versions as value
171
- def gems_and_versions
172
- gems = {}
173
- Gem::Specification.find_all.sort_by { |s| [s.name, s.version] }.each do |spec|
174
- gems[spec.name] ||= []
175
- gems[spec.name] << spec.version.to_s
176
- end
177
- gems
178
- end
179
-
180
- # A hash that contains the name of the gem for a given required file. If a
181
- # `#require` fails, the gem name is looked up in this hash.
182
- GEM_NAMES = {
183
- 'adsf' => 'adsf',
184
- 'asciidoctor' => 'asciidoctor',
185
- 'bluecloth' => 'bluecloth',
186
- 'builder' => 'builder',
187
- 'coderay' => 'coderay',
188
- 'coffee-script' => 'coffee-script',
189
- 'cri' => 'cri',
190
- 'erubi' => 'erubi',
191
- 'erubis' => 'erubis',
192
- 'escape' => 'escape',
193
- 'fog' => 'fog',
194
- 'haml' => 'haml',
195
- 'json' => 'json',
196
- 'kramdown' => 'kramdown',
197
- 'less' => 'less',
198
- 'listen' => 'listen',
199
- 'markaby' => 'markaby',
200
- 'maruku' => 'maruku',
201
- 'mime/types' => 'mime-types',
202
- 'mustache' => 'mustache',
203
- 'nanoc/live' => 'nanoc-live',
204
- 'nokogiri' => 'nokogiri',
205
- 'nokogumbo' => 'nokogumbo',
206
- 'pandoc-ruby' => 'pandoc-ruby',
207
- 'pry' => 'pry',
208
- 'rack' => 'rack',
209
- 'rack/cache' => 'rack-cache',
210
- 'rainpress' => 'rainpress',
211
- 'rdiscount' => 'rdiscount',
212
- 'redcarpet' => 'redcarpet',
213
- 'redcloth' => 'RedCloth',
214
- 'ruby-handlebars' => 'hbs',
215
- 'rubypants' => 'rubypants',
216
- 'sass' => 'sass',
217
- 'slim' => 'slim',
218
- 'typogruby' => 'typogruby',
219
- 'uglifier' => 'uglifier',
220
- 'w3c_validators' => 'w3c_validators',
221
- 'yuicompressor' => 'yuicompressor',
222
- }.freeze
223
-
224
- # Attempts to find a resolution for the given error, or nil if no
225
- # resolution can be automatically obtained.
226
- #
227
- # @param [Error] error The error to find a resolution for
228
- #
229
- # @return [String] The resolution for the given error
230
- def resolution_for(error)
231
- error = unwrap_error(error)
232
-
233
- case error
234
- when LoadError
235
- gem_name = gem_name_from_load_error(error)
236
-
237
- if gem_name
238
- if using_bundler?
239
- <<~RES
240
- 1. Add `gem '#{gem_name}'` to your Gemfile
241
- 2. Run `bundle install`
242
- 3. Re-run this command
243
- RES
244
- else
245
- "Install the '#{gem_name}' gem using `gem install #{gem_name}`."
246
- end
247
- end
248
- when RuntimeError
249
- if /^can't modify frozen/.match?(error.message)
250
- 'You attempted to modify immutable data. Some data cannot ' \
251
- 'be modified once compilation has started. Such data includes ' \
252
- 'content and attributes of items and layouts, and filter arguments.'
253
- end
254
- when Errno::EADDRINUSE
255
- 'There already is a server running. Either shut down that one, or ' \
256
- 'specify a different port to run this server on.'
257
- end
258
- end
259
-
260
- def gem_name_from_load_error(error)
261
- matches = error.message.match(/(no such file to load|cannot load such file) -- ([^\s]+)/)
262
- return nil if matches.nil?
263
-
264
- GEM_NAMES[matches[2]]
265
- end
266
-
267
- def using_bundler?
268
- defined?(Bundler) && Bundler::SharedHelpers.in_bundle?
269
- end
270
-
271
- def ruby_version
272
- RUBY_VERSION
273
- end
274
-
275
- def write_section_header(stream, title, verbose: false)
276
- stream.puts
277
-
278
- if verbose
279
- stream.puts '===== ' + title.upcase + ':'
280
- stream.puts
281
- end
282
- end
283
-
284
- def write_error_message(stream, error, verbose: false)
285
- write_section_header(stream, 'Message', verbose: verbose)
286
-
287
- error = unwrap_error(error)
288
-
289
- message = "#{error.class}: #{message_for_error(error)}"
290
- unless verbose
291
- message = "\e[1m\e[31m" + message + "\e[0m"
292
- end
293
- stream.puts message
294
- resolution = resolution_for(error)
295
- stream.puts resolution.to_s if resolution
296
- end
297
-
298
- def message_for_error(error)
299
- case error
300
- when JsonSchema::AggregateError
301
- "\n" + error.errors.map { |e| " * #{e.pointer}: #{e.message}" }.join("\n")
302
- else
303
- error.message
304
- end
305
- end
306
-
307
- def write_item_rep(stream, error, verbose: false)
308
- return unless error.is_a?(Nanoc::Int::Errors::CompilationError)
309
-
310
- write_section_header(stream, 'Item being compiled', verbose: verbose)
311
-
312
- item_rep = error.item_rep
313
- stream.puts "Current item: #{item_rep.item.identifier} (#{item_rep.name.inspect} representation)"
314
- end
315
-
316
- def write_stack_trace(stream, error, verbose: false)
317
- write_section_header(stream, 'Stack trace', verbose: verbose)
318
-
319
- writer = StackTraceWriter.new(stream, forwards: forwards_stack_trace?)
320
- writer.write(unwrap_error(error), verbose: verbose)
321
- end
322
-
323
- def write_version_information(stream, verbose: false)
324
- write_section_header(stream, 'Version information', verbose: verbose)
325
- stream.puts Nanoc.version_information
326
- end
327
-
328
- def write_system_information(stream, verbose: false)
329
- uname = `uname -a`
330
- write_section_header(stream, 'System information', verbose: verbose)
331
- stream.puts uname
332
- rescue Errno::ENOENT
333
- end
334
-
335
- def write_installed_gems(stream, verbose: false)
336
- write_section_header(stream, 'Installed gems', verbose: verbose)
337
- gems_and_versions.each do |g|
338
- stream.puts " #{g.first} #{g.last.join(', ')}"
339
- end
340
- end
341
-
342
- def write_gemfile_lock(stream, verbose: false)
343
- if File.exist?('Gemfile.lock')
344
- write_section_header(stream, 'Gemfile.lock', verbose: verbose)
345
- stream.puts File.read('Gemfile.lock')
346
- end
347
- end
348
-
349
- def write_load_paths(stream, verbose: false)
350
- write_section_header(stream, 'Load paths', verbose: verbose)
351
- $LOAD_PATH.each_with_index do |i, index|
352
- stream.puts " #{index}. #{i}"
353
- end
354
- end
355
-
356
- def unwrap_error(e)
357
- case e
358
- when Nanoc::Int::Errors::CompilationError
359
- e.unwrap
360
- else
361
- e
362
- end
363
- end
364
- end
365
- end
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Nanoc::CLI
4
- # Nanoc::CLI::Logger is a singleton class responsible for generating
5
- # feedback in the terminal.
6
- #
7
- # @api private
8
- class Logger
9
- # Maps actions (`:create`, `:update`, `:identical`, `:cached`, `:skip` and `:delete`)
10
- # onto their ANSI color codes.
11
- ACTION_COLORS = {
12
- create: "\e[32m", # green
13
- update: "\e[33m", # yellow
14
- identical: '', # (nothing)
15
- cached: '', # (nothing)
16
- skip: '', # (nothing)
17
- delete: "\e[31m", # red
18
- }.freeze
19
-
20
- include Singleton
21
-
22
- # Returns the log level, which can be :high, :low or :off (which will log
23
- # all messages, only high-priority messages, or no messages at all,
24
- # respectively).
25
- #
26
- # @return [Symbol] The log level
27
- attr_accessor :level
28
-
29
- def initialize
30
- @level = :high
31
- @mutex = Mutex.new
32
- end
33
-
34
- # Logs a file-related action.
35
- #
36
- # @param [:high, :low] level The importance of this action
37
- #
38
- # @param [:create, :update, :identical, :cached, :skip, :delete] action The kind of file action
39
- #
40
- # @param [String] name The name of the file the action was performed on
41
- #
42
- # @return [void]
43
- def file(level, action, name, duration = nil)
44
- log(
45
- level,
46
- format(
47
- '%s%12s%s %s%s',
48
- ACTION_COLORS[action.to_sym],
49
- action,
50
- "\e[0m",
51
- duration.nil? ? '' : format('[%2.2fs] ', duration),
52
- name,
53
- ),
54
- )
55
- end
56
-
57
- # Logs a message.
58
- #
59
- # @param [:high, :low] level The importance of this message
60
- #
61
- # @param [String] message The message to be logged
62
- #
63
- # @param [#puts] io The stream to which the message should be written
64
- #
65
- # @return [void]
66
- def log(level, message, io = $stdout)
67
- return if @level == :off
68
- return if @level != :low && @level != level
69
-
70
- @mutex.synchronize do
71
- io.puts(message)
72
- end
73
- end
74
- end
75
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Nanoc::CLI
4
- # @api private
5
- class StackTraceWriter
6
- def initialize(stream, forwards:)
7
- @stream = stream
8
- @forwards = forwards
9
- end
10
-
11
- def write(error, verbose:)
12
- if @forwards
13
- write_forwards(error, verbose: verbose)
14
- else
15
- write_backwards(error, verbose: verbose)
16
- end
17
- end
18
-
19
- private
20
-
21
- def write_backwards(error, verbose:)
22
- count = verbose ? -1 : 10
23
-
24
- error.backtrace[0...count].each_with_index do |item, index|
25
- @stream.puts " #{index}. #{item}"
26
- end
27
-
28
- if !verbose && error.backtrace.size > count
29
- @stream.puts " ... #{error.backtrace.size - count} lines omitted (see crash.log for details)"
30
- end
31
- end
32
-
33
- def write_forwards(error, verbose:)
34
- count = 10
35
- backtrace = verbose ? error.backtrace : error.backtrace.take(count)
36
-
37
- if !verbose && error.backtrace.size > count
38
- @stream.puts " ... #{error.backtrace.size - count} lines omitted (see crash.log for details)"
39
- end
40
-
41
- backtrace.each_with_index.to_a.reverse_each do |(item, index)|
42
- if index.zero?
43
- @stream.puts " #{item}"
44
- else
45
- @stream.puts " #{index}. from #{item}"
46
- end
47
- end
48
- end
49
- end
50
- end