pry 0.10.4 → 0.12.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +251 -16
  3. data/LICENSE +1 -1
  4. data/README.md +35 -51
  5. data/bin/pry +3 -11
  6. data/lib/pry/basic_object.rb +6 -0
  7. data/lib/pry/cli.rb +50 -52
  8. data/lib/pry/code/code_file.rb +13 -6
  9. data/lib/pry/code/code_range.rb +3 -3
  10. data/lib/pry/code/loc.rb +14 -8
  11. data/lib/pry/code.rb +11 -6
  12. data/lib/pry/code_object.rb +27 -4
  13. data/lib/pry/color_printer.rb +20 -10
  14. data/lib/pry/command.rb +76 -45
  15. data/lib/pry/command_set.rb +17 -45
  16. data/lib/pry/commands/amend_line.rb +3 -4
  17. data/lib/pry/commands/bang.rb +1 -1
  18. data/lib/pry/commands/cat/exception_formatter.rb +10 -8
  19. data/lib/pry/commands/cat/file_formatter.rb +7 -3
  20. data/lib/pry/commands/cat/input_expression_formatter.rb +1 -1
  21. data/lib/pry/commands/cat.rb +7 -6
  22. data/lib/pry/commands/change_prompt.rb +29 -9
  23. data/lib/pry/commands/clear_screen.rb +14 -0
  24. data/lib/pry/commands/code_collector.rb +25 -23
  25. data/lib/pry/commands/easter_eggs.rb +12 -12
  26. data/lib/pry/commands/edit/file_and_line_locator.rb +1 -1
  27. data/lib/pry/commands/edit.rb +15 -10
  28. data/lib/pry/commands/exit.rb +2 -1
  29. data/lib/pry/commands/find_method.rb +12 -14
  30. data/lib/pry/commands/gem_cd.rb +1 -1
  31. data/lib/pry/commands/gem_install.rb +2 -2
  32. data/lib/pry/commands/gem_list.rb +2 -2
  33. data/lib/pry/commands/gem_open.rb +2 -2
  34. data/lib/pry/commands/gem_readme.rb +25 -0
  35. data/lib/pry/commands/gem_search.rb +40 -0
  36. data/lib/pry/commands/gem_stats.rb +83 -0
  37. data/lib/pry/commands/gist.rb +7 -6
  38. data/lib/pry/commands/help.rb +3 -3
  39. data/lib/pry/commands/hist.rb +11 -10
  40. data/lib/pry/commands/import_set.rb +2 -1
  41. data/lib/pry/commands/install_command.rb +7 -6
  42. data/lib/pry/commands/jump_to.rb +7 -7
  43. data/lib/pry/commands/list_inspectors.rb +2 -2
  44. data/lib/pry/commands/ls/constants.rb +14 -3
  45. data/lib/pry/commands/ls/formatter.rb +4 -2
  46. data/lib/pry/commands/ls/globals.rb +0 -2
  47. data/lib/pry/commands/ls/grep.rb +0 -2
  48. data/lib/pry/commands/ls/instance_vars.rb +0 -1
  49. data/lib/pry/commands/ls/jruby_hacks.rb +2 -2
  50. data/lib/pry/commands/ls/local_names.rb +0 -2
  51. data/lib/pry/commands/ls/local_vars.rb +0 -2
  52. data/lib/pry/commands/ls/ls_entity.rb +0 -1
  53. data/lib/pry/commands/ls/methods.rb +0 -3
  54. data/lib/pry/commands/ls/methods_helper.rb +1 -1
  55. data/lib/pry/commands/ls/self_methods.rb +2 -1
  56. data/lib/pry/commands/ls.rb +30 -31
  57. data/lib/pry/commands/play.rb +3 -4
  58. data/lib/pry/commands/pry_backtrace.rb +1 -1
  59. data/lib/pry/commands/raise_up.rb +2 -1
  60. data/lib/pry/commands/reload_code.rb +2 -2
  61. data/lib/pry/commands/ri.rb +9 -4
  62. data/lib/pry/commands/shell_command.rb +36 -9
  63. data/lib/pry/commands/shell_mode.rb +6 -6
  64. data/lib/pry/commands/show_doc.rb +5 -7
  65. data/lib/pry/commands/show_info.rb +35 -20
  66. data/lib/pry/commands/show_source.rb +5 -2
  67. data/lib/pry/commands/stat.rb +1 -1
  68. data/lib/pry/commands/watch_expression/expression.rb +1 -1
  69. data/lib/pry/commands/watch_expression.rb +9 -7
  70. data/lib/pry/commands/whereami.rb +11 -10
  71. data/lib/pry/commands/wtf.rb +15 -2
  72. data/lib/pry/config/behavior.rb +230 -114
  73. data/lib/pry/config/convenience.rb +24 -21
  74. data/lib/pry/config/default.rb +151 -153
  75. data/lib/pry/config/memoization.rb +48 -0
  76. data/lib/pry/config.rb +30 -19
  77. data/lib/pry/core_extensions.rb +15 -4
  78. data/lib/pry/editor.rb +5 -12
  79. data/lib/pry/exceptions.rb +1 -3
  80. data/lib/pry/forwardable.rb +23 -0
  81. data/lib/pry/helpers/base_helpers.rb +197 -110
  82. data/lib/pry/helpers/command_helpers.rb +5 -4
  83. data/lib/pry/helpers/documentation_helpers.rb +3 -2
  84. data/lib/pry/helpers/options_helpers.rb +6 -6
  85. data/lib/pry/helpers/platform.rb +58 -0
  86. data/lib/pry/helpers/table.rb +20 -15
  87. data/lib/pry/helpers/text.rb +82 -74
  88. data/lib/pry/helpers.rb +1 -0
  89. data/lib/pry/history.rb +43 -9
  90. data/lib/pry/hooks.rb +50 -109
  91. data/lib/pry/indent.rb +21 -19
  92. data/lib/pry/input_completer.rb +146 -123
  93. data/lib/pry/input_lock.rb +0 -2
  94. data/lib/pry/last_exception.rb +2 -2
  95. data/lib/pry/method/disowned.rb +3 -1
  96. data/lib/pry/method/patcher.rb +2 -5
  97. data/lib/pry/method/weird_method_locator.rb +21 -11
  98. data/lib/pry/method.rb +44 -38
  99. data/lib/pry/object_path.rb +5 -4
  100. data/lib/pry/output.rb +37 -37
  101. data/lib/pry/pager.rb +195 -184
  102. data/lib/pry/platform.rb +91 -0
  103. data/lib/pry/plugins.rb +27 -8
  104. data/lib/pry/prompt.rb +144 -25
  105. data/lib/pry/pry_class.rb +83 -33
  106. data/lib/pry/pry_instance.rb +94 -59
  107. data/lib/pry/repl.rb +70 -11
  108. data/lib/pry/repl_file_loader.rb +2 -3
  109. data/lib/pry/ring.rb +84 -0
  110. data/lib/pry/rubygem.rb +9 -7
  111. data/lib/pry/slop/LICENSE +20 -0
  112. data/lib/pry/slop/commands.rb +195 -0
  113. data/lib/pry/slop/option.rb +206 -0
  114. data/lib/pry/slop.rb +661 -0
  115. data/lib/pry/terminal.rb +18 -6
  116. data/lib/pry/testable/evalable.rb +15 -0
  117. data/lib/pry/testable/mockable.rb +14 -0
  118. data/lib/pry/testable/pry_tester.rb +73 -0
  119. data/lib/pry/testable/utility.rb +26 -0
  120. data/lib/pry/testable/variables.rb +46 -0
  121. data/lib/pry/testable.rb +70 -0
  122. data/lib/pry/version.rb +1 -1
  123. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +8 -14
  124. data/lib/pry/wrapped_module.rb +21 -21
  125. data/lib/pry.rb +21 -50
  126. metadata +29 -40
  127. data/lib/pry/commands/list_prompts.rb +0 -35
  128. data/lib/pry/commands/simple_prompt.rb +0 -22
  129. data/lib/pry/history_array.rb +0 -121
  130. data/lib/pry/rbx_path.rb +0 -22
  131. data/lib/pry/test/helper.rb +0 -170
@@ -3,8 +3,8 @@ class Pry
3
3
  match(/\.(.*)/)
4
4
  group 'Input and Output'
5
5
  description "All text following a '.' is forwarded to the shell."
6
- command_options :listing => '.<shell command>', :use_prefix => false,
7
- :takes_block => true
6
+ command_options listing: '.<shell command>', use_prefix: false,
7
+ takes_block: true
8
8
 
9
9
  banner <<-'BANNER'
10
10
  Usage: .COMMAND_NAME
@@ -30,18 +30,45 @@ class Pry
30
30
 
31
31
  private
32
32
 
33
- def parse_destination(dest)
34
- return "~" if dest.empty?
35
- return dest unless dest == "-"
36
- state.old_pwd || raise(CommandError, "No prior directory available")
37
- end
33
+ def parse_destination(dest)
34
+ return "~" if dest.empty?
35
+ return dest unless dest == "-"
36
+
37
+ state.old_pwd || raise(CommandError, "No prior directory available")
38
+ end
38
39
 
39
- def process_cd(dest)
40
+ def process_cd(dest)
41
+ begin
40
42
  state.old_pwd = Dir.pwd
41
- Dir.chdir File.expand_path(dest)
43
+ Dir.chdir(File.expand_path(path_from_cd_path(dest) || dest))
42
44
  rescue Errno::ENOENT
43
45
  raise CommandError, "No such directory: #{dest}"
44
46
  end
47
+ end
48
+
49
+ def cd_path_env
50
+ ENV['CDPATH']
51
+ end
52
+
53
+ def cd_path_exists?
54
+ cd_path_env && cd_path_env.length.nonzero?
55
+ end
56
+
57
+ def path_from_cd_path(dest)
58
+ return if !(dest && cd_path_exists?) || special_case_path?(dest)
59
+
60
+ cd_path_env.split(File::PATH_SEPARATOR).each do |path|
61
+ if File.directory?(path) && path.split(File::SEPARATOR).last == dest
62
+ return path
63
+ end
64
+ end
65
+
66
+ return nil
67
+ end
68
+
69
+ def special_case_path?(dest)
70
+ ['.', '..', '-'].include?(dest) || dest =~ /\A[#{File::PATH_SEPARATOR}~]/
71
+ end
45
72
  end
46
73
 
47
74
  Pry::Commands.add_command(Pry::Command::ShellCommand)
@@ -9,13 +9,13 @@ class Pry
9
9
  BANNER
10
10
 
11
11
  def process
12
- case _pry_.prompt
13
- when Pry::SHELL_PROMPT
14
- _pry_.pop_prompt
15
- _pry_.custom_completions = _pry_.config.file_completions
12
+ state.disabled ^= true
13
+
14
+ if state.disabled
15
+ state.prev_prompt = _pry_.prompt
16
+ _pry_.prompt = Pry::Prompt[:shell][:value]
16
17
  else
17
- _pry_.push_prompt Pry::SHELL_PROMPT
18
- _pry_.custom_completions = _pry_.config.command_completions
18
+ _pry_.prompt = state.prev_prompt
19
19
  end
20
20
  end
21
21
  end
@@ -62,19 +62,17 @@ class Pry
62
62
  # Which sections to include in the 'header', can toggle: :owner,
63
63
  # :signature and visibility.
64
64
  def header_options
65
- super.merge :signature => true
65
+ super.merge signature: true
66
66
  end
67
67
 
68
68
  # figure out start line of docs by back-calculating based on
69
69
  # number of lines in the comment and the start line of the code_object
70
70
  # @return [Fixnum] start line of docs
71
71
  def start_line_for(code_object)
72
- if code_object.command? || opts.present?(:'base-one')
73
- 1
74
- else
75
- code_object.source_line.nil? ? 1 :
76
- (code_object.source_line - code_object.doc.lines.count)
77
- end
72
+ return 1 if code_object.command? || opts.present?(:'base-one')
73
+ return 1 unless code_object.source_line
74
+
75
+ code_object.source_line - code_object.doc.lines.count
78
76
  end
79
77
  end
80
78
 
@@ -2,7 +2,7 @@ class Pry
2
2
  class Command::ShowInfo < Pry::ClassCommand
3
3
  extend Pry::Helpers::BaseHelpers
4
4
 
5
- command_options :shellwords => false, :interpolate => false
5
+ command_options shellwords: false, interpolate: false
6
6
 
7
7
  def initialize(*)
8
8
  super
@@ -11,18 +11,27 @@ class Pry
11
11
  end
12
12
 
13
13
  def options(opt)
14
- opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors", :as => :count
14
+ opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors", as: :count
15
15
  opt.on :l, "line-numbers", "Show line numbers"
16
16
  opt.on :b, "base-one", "Show line numbers but start numbering at 1 (useful for `amend-line` and `play` commands)"
17
- opt.on :a, :all, "Show all definitions and monkeypatches of the module/class"
17
+ opt.on :a, :all, "Show all definitions and monkeypatches of the module/class"
18
18
  end
19
19
 
20
20
  def process
21
- code_object = Pry::CodeObject.lookup(obj_name, _pry_, :super => opts[:super])
21
+ code_object = Pry::CodeObject.lookup(obj_name, _pry_, super: opts[:super])
22
22
  raise CommandError, no_definition_message if !code_object
23
+
23
24
  @original_code_object = code_object
24
25
 
25
- if show_all_modules?(code_object)
26
+ if !obj_name && code_object.c_module? && !opts[:all]
27
+ result = "Warning: You're inside an object, whose class is defined by means\n" +
28
+ " of the C Ruby API. Pry cannot display the information for\n" +
29
+ " this class."
30
+ if code_object.candidates.any?
31
+ result += "\n However, you can view monkey-patches applied to this class.\n" +
32
+ " Just execute the same command with the '--all' switch."
33
+ end
34
+ elsif show_all_modules?(code_object)
26
35
  # show all monkey patches for a module
27
36
 
28
37
  result = content_and_headers_for_all_module_candidates(code_object)
@@ -72,7 +81,7 @@ class Pry
72
81
  mod.number_of_candidates.times do |v|
73
82
  candidate = mod.candidate(v)
74
83
  begin
75
- result << "\nCandidate #{v+1}/#{mod.number_of_candidates}: #{candidate.source_file} @ line #{candidate.source_line}:\n"
84
+ result << "\nCandidate #{v + 1}/#{mod.number_of_candidates}: #{candidate.source_file} @ line #{candidate.source_line}:\n"
76
85
  content = content_for(candidate)
77
86
 
78
87
  result << "Number of lines: #{content.lines.count}\n\n" << content
@@ -85,18 +94,24 @@ class Pry
85
94
  end
86
95
 
87
96
  def no_definition_message
88
- "Couldn't locate a definition for #{obj_name}!"
97
+ "Couldn't locate a definition for #{obj_name}"
89
98
  end
90
99
 
91
100
  # Generate a header (meta-data information) for all the code
92
101
  # object types: methods, modules, commands, procs...
93
102
  def header(code_object)
94
103
  file_name, line_num = file_and_line_for(code_object)
95
- h = "\n#{Pry::Helpers::Text.bold('From:')} #{file_name} "
104
+ content = content_for(code_object)
105
+
106
+ h = "\n#{bold('From:')} #{file_name} "
96
107
  h << code_object_header(code_object, line_num)
97
- h << "\n#{Pry::Helpers::Text.bold('Number of lines:')} " <<
98
- "#{content_for(code_object).lines.count}\n\n"
99
- h << Helpers::Text.bold('** Warning:') << " Cannot find code for #{@original_code_object.nonblank_name}. Showing superclass #{code_object.nonblank_name} instead. **\n\n" if @used_super
108
+ h << "\n#{bold('Number of lines:')} " << "#{content.lines.count}\n\n"
109
+ h << bold('** Warning:') << " Cannot find code for #{@original_code_object.nonblank_name}. Showing superclass #{code_object.nonblank_name} instead. **\n\n" if @used_super
110
+
111
+ if content.lines.none?
112
+ h << bold('** Warning:') << " Cannot find code for '#{code_object.name}' (source_location is nil)"
113
+ end
114
+
100
115
  h
101
116
  end
102
117
 
@@ -125,11 +140,11 @@ class Pry
125
140
  def module_header(code_object, line_num)
126
141
  h = ""
127
142
  h << "@ line #{line_num}:\n"
128
- h << text.bold(code_object.module? ? "Module" : "Class")
129
- h << " #{text.bold('name:')} #{code_object.nonblank_name}"
143
+ h << bold(code_object.module? ? "Module" : "Class")
144
+ h << " #{bold('name:')} #{code_object.nonblank_name}"
130
145
 
131
146
  if code_object.number_of_candidates > 1
132
- h << (text.bold("\nNumber of monkeypatches: ") << code_object.number_of_candidates.to_s)
147
+ h << (bold("\nNumber of monkeypatches: ") << code_object.number_of_candidates.to_s)
133
148
  h << ". Use the `-a` option to display all available monkeypatches"
134
149
  end
135
150
  h
@@ -137,17 +152,17 @@ class Pry
137
152
 
138
153
  def method_sections(code_object)
139
154
  {
140
- :owner => "\n#{text.bold("Owner:")} #{code_object.owner || "N/A"}\n",
141
- :visibility => "#{text.bold("Visibility:")} #{code_object.visibility}",
142
- :signature => "\n#{text.bold("Signature:")} #{code_object.signature}"
155
+ owner: "\n#{bold("Owner:")} #{code_object.owner || "N/A"}\n",
156
+ visibility: "#{bold("Visibility:")} #{code_object.visibility}",
157
+ signature: "\n#{bold("Signature:")} #{code_object.signature}"
143
158
  }.merge(header_options) { |key, old, new| (new && old).to_s }
144
159
  end
145
160
 
146
161
  def header_options
147
162
  {
148
- :owner => true,
149
- :visibility => true,
150
- :signature => nil
163
+ owner: true,
164
+ visibility: true,
165
+ signature: nil
151
166
  }
152
167
  end
153
168
 
@@ -39,8 +39,11 @@ class Pry
39
39
 
40
40
  # The source for code_object prepared for display.
41
41
  def content_for(code_object)
42
- Code.new(code_object.source, start_line_for(code_object)).
43
- with_line_numbers(use_line_numbers?).highlighted
42
+ code = Code.new(
43
+ code_object.source || [],
44
+ start_line_for(code_object)
45
+ )
46
+ code.with_line_numbers(use_line_numbers?).highlighted
44
47
  end
45
48
  end
46
49
 
@@ -3,7 +3,7 @@ class Pry
3
3
  match 'stat'
4
4
  group 'Introspection'
5
5
  description 'View method information and set _file_ and _dir_ locals.'
6
- command_options :shellwords => false
6
+ command_options shellwords: false
7
7
 
8
8
  banner <<-'BANNER'
9
9
  Usage: stat [OPTIONS] [METH]
@@ -10,7 +10,7 @@ class Pry
10
10
  end
11
11
 
12
12
  def eval!
13
- @previous_value = @value
13
+ @previous_value = value
14
14
  @value = Pry::ColorPrinter.pp(target_eval(target, source), "")
15
15
  end
16
16
 
@@ -5,7 +5,7 @@ class Pry
5
5
  match 'watch'
6
6
  group 'Context'
7
7
  description 'Watch the value of an expression and print a notification whenever it changes.'
8
- command_options :use_prefix => false
8
+ command_options use_prefix: false
9
9
 
10
10
  banner <<-'BANNER'
11
11
  Usage: watch [EXPRESSION]
@@ -29,7 +29,7 @@ class Pry
29
29
  def options(opt)
30
30
  opt.on :d, :delete,
31
31
  "Delete the watch expression with the given index. If no index is given; clear all watch expressions.",
32
- :optional_argument => true, :as => Integer
32
+ optional_argument: true, as: Integer
33
33
  opt.on :l, :list,
34
34
  "Show all current watch expressions and their values. Calling watch with no expressions or options will also show the watch expressions."
35
35
  end
@@ -54,8 +54,8 @@ class Pry
54
54
 
55
55
  def delete(index)
56
56
  if index
57
- output.puts "Deleting watch expression ##{index}: #{expressions[index-1]}"
58
- expressions.delete_at(index-1)
57
+ output.puts "Deleting watch expression ##{index}: #{expressions[index - 1]}"
58
+ expressions.delete_at(index - 1)
59
59
  else
60
60
  output.puts "Deleting all watched expressions"
61
61
  expressions.clear
@@ -70,7 +70,7 @@ class Pry
70
70
  pager.puts "Listing all watched expressions:"
71
71
  pager.puts ""
72
72
  expressions.each_with_index do |expr, index|
73
- pager.print text.with_line_numbers(expr.to_s, index+1)
73
+ pager.print with_line_numbers(expr.to_s, index + 1)
74
74
  end
75
75
  pager.puts ""
76
76
  end
@@ -81,12 +81,14 @@ class Pry
81
81
  expressions.each do |expr|
82
82
  expr.eval!
83
83
  if expr.changed?
84
- output.puts "#{text.blue "watch"}: #{expr.to_s}"
84
+ output.puts "#{blue "watch"}: #{expr}"
85
85
  end
86
86
  end
87
87
  end
88
88
 
89
- def add_expression(arguments)
89
+ # TODO: fix arguments.
90
+ # https://github.com/pry/pry/commit/b031df2f2f5850ee6e9018f33d35f3485a9b0423
91
+ def add_expression(_arguments)
90
92
  expressions << Expression.new(_pry_, target, arg_string)
91
93
  output.puts "Watching #{Code.new(arg_string).highlighted}"
92
94
  end
@@ -1,6 +1,5 @@
1
1
  class Pry
2
2
  class Command::Whereami < Pry::ClassCommand
3
-
4
3
  def initialize(*)
5
4
  super
6
5
 
@@ -94,7 +93,7 @@ class Pry
94
93
 
95
94
  set_file_and_dir_locals(@file)
96
95
 
97
- out = "\n#{text.bold('From:')} #{location}:\n\n" <<
96
+ out = "\n#{bold('From:')} #{location}:\n\n" <<
98
97
  code.with_line_numbers(use_line_numbers?).with_marker(marker).highlighted << "\n"
99
98
 
100
99
  _pry_.pager.page out
@@ -154,17 +153,18 @@ class Pry
154
153
  # or it returns the class of `target_self` if `target_self` is not a class.
155
154
  # @return [Pry::WrappedModule]
156
155
  def target_class
157
- target_self.is_a?(Module) ? Pry::WrappedModule(target_self) :
158
- Pry::WrappedModule(target_self.class)
156
+ return Pry::WrappedModule(target_self) if target_self.is_a?(Module)
157
+
158
+ Pry::WrappedModule(target_self.class)
159
159
  end
160
160
 
161
161
  def class_code
162
- return @class_code if @class_code
163
-
164
- mod = @method ? Pry::WrappedModule(@method.owner) : target_class
165
-
166
- idx = mod.candidates.find_index { |v| expand_path(v.source_file) == @file }
167
- @class_code = idx && Pry::Code.from_module(mod, idx)
162
+ @class_code ||=
163
+ begin
164
+ mod = @method ? Pry::WrappedModule(@method.owner) : target_class
165
+ idx = mod.candidates.find_index { |v| expand_path(v.source_file) == @file }
166
+ idx && Pry::Code.from_module(mod, idx)
167
+ end
168
168
  end
169
169
 
170
170
  def valid_method?
@@ -193,4 +193,5 @@ class Pry
193
193
 
194
194
  Pry::Commands.add_command(Pry::Command::Whereami)
195
195
  Pry::Commands.alias_command '@', 'whereami'
196
+ Pry::Commands.alias_command(/whereami[!?]+/, 'whereami')
196
197
  end
@@ -3,7 +3,7 @@ class Pry
3
3
  match(/wtf([?!]*)/)
4
4
  group 'Context'
5
5
  description 'Show the backtrace of the most recent exception.'
6
- options :listing => 'wtf?'
6
+ options listing: 'wtf?'
7
7
 
8
8
  banner <<-'BANNER'
9
9
  Usage: wtf[?|!]
@@ -26,12 +26,25 @@ class Pry
26
26
  def process
27
27
  raise Pry::CommandError, "No most-recent exception" unless exception
28
28
 
29
- output.puts "#{text.bold('Exception:')} #{exception.class}: #{exception}\n--"
29
+ output.puts "#{bold('Exception:')} #{exception.class}: #{exception}\n--"
30
30
  if opts.verbose?
31
31
  output.puts with_line_numbers(backtrace)
32
32
  else
33
33
  output.puts with_line_numbers(backtrace.first(size_of_backtrace))
34
34
  end
35
+
36
+ if exception.respond_to? :cause
37
+ cause = exception.cause
38
+ while cause
39
+ output.puts "#{text.bold('Caused by:')} #{cause.class}: #{cause}\n--"
40
+ if opts.verbose?
41
+ output.puts with_line_numbers(cause.backtrace)
42
+ else
43
+ output.puts with_line_numbers(cause.backtrace.first(size_of_backtrace))
44
+ end
45
+ cause = cause.cause
46
+ end
47
+ end
35
48
  end
36
49
 
37
50
  private