pry-moves 0.1.13 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +6 -4
  4. data/README.md +15 -7
  5. data/lib/commands/debug.rb +17 -0
  6. data/lib/commands/finish.rb +26 -0
  7. data/lib/commands/goto.rb +19 -0
  8. data/lib/commands/iterate.rb +22 -0
  9. data/lib/commands/next.rb +37 -0
  10. data/lib/commands/next_breakpoint.rb +22 -0
  11. data/lib/commands/step.rb +83 -0
  12. data/lib/commands/trace_command.rb +87 -0
  13. data/lib/commands/trace_helpers.rb +49 -0
  14. data/lib/commands/traced_method.rb +71 -0
  15. data/lib/debug_sugar.rb +72 -0
  16. data/lib/pry-moves/add_suffix.rb +88 -0
  17. data/lib/pry-moves/backtrace.rb +67 -43
  18. data/lib/pry-moves/bindings_stack.rb +97 -0
  19. data/lib/pry-moves/commands.rb +42 -3
  20. data/lib/pry-moves/formatter.rb +74 -0
  21. data/lib/pry-moves/painter.rb +3 -2
  22. data/lib/pry-moves/pry_ext.rb +64 -16
  23. data/lib/pry-moves/pry_wrapper.rb +30 -17
  24. data/lib/pry-moves/restartable.rb +38 -0
  25. data/lib/pry-moves/version.rb +1 -1
  26. data/lib/pry-moves/watch.rb +3 -0
  27. data/lib/pry-moves.rb +65 -6
  28. data/lib/pry-stack_explorer/frame_manager.rb +6 -9
  29. data/lib/pry-stack_explorer/pry-stack_explorer.rb +1 -16
  30. data/lib/pry-stack_explorer/{commands.rb → stack_commands.rb} +10 -6
  31. data/lib/pry-stack_explorer/when_started_hook.rb +10 -65
  32. data/playground/Gemfile.lock +6 -4
  33. data/playground/README.md +1 -0
  34. data/playground/playground.rb +94 -9
  35. data/playground/test.rb +5 -1
  36. data/playground/test.sh +1 -0
  37. data/pry-moves.gemspec +3 -2
  38. data/publish.sh +2 -1
  39. data/spec/backtrace_spec.rb +11 -13
  40. data/spec/blocks_spec.rb +41 -8
  41. data/spec/commands_spec.rb +26 -25
  42. data/spec/pry_debugger.rb +5 -1
  43. data/spec/redirection_spec.rb +7 -0
  44. data/spec/spec_helper.rb +9 -4
  45. data/spec/step_spec.rb +51 -0
  46. metadata +43 -13
  47. data/lib/pry-moves/helpers.rb +0 -56
  48. data/lib/pry-moves/trace_commands.rb +0 -109
  49. data/lib/pry-moves/traced_method.rb +0 -61
  50. data/lib/pry-moves/tracer.rb +0 -140
  51. data/lib/pry-moves/traversing.rb +0 -69
@@ -33,13 +33,6 @@ module PryStackExplorer
33
33
  @prior_backtrace = _pry_.backtrace
34
34
  end
35
35
 
36
- def filter_bindings(vapid_frames: false)
37
- bindings.reject do |binding|
38
- !vapid_frames and
39
- binding.local_variable_defined?(:vapid_frame)
40
- end
41
- end
42
-
43
36
  # Iterate over all frames
44
37
  def each(&block)
45
38
  bindings.each(&block)
@@ -61,14 +54,18 @@ module PryStackExplorer
61
54
  # @param [Fixnum] index The index.
62
55
  def set_binding_index_safely(index)
63
56
  if index > bindings.size - 1
64
- raise Pry::CommandError, "At top of stack, cannot go further"
57
+ raise Pry::CommandError, "Shouldn't happen: At top of stack, cannot go further"
65
58
  elsif index < 0
66
- raise Pry::CommandError, "At bottom of stack, cannot go further"
59
+ raise Pry::CommandError, "Shouldn't happen: At bottom of stack, cannot go further"
67
60
  else
68
61
  self.binding_index = index
69
62
  end
70
63
  end
71
64
 
65
+ def goto_index index
66
+ change_frame_to bindings.index {|b| b.index == index }
67
+ end
68
+
72
69
  # Change active frame to the one indexed by `index`.
73
70
  # Note that indexing base is `0`
74
71
  # @param [Fixnum] index The index of the frame.
@@ -1,7 +1,7 @@
1
1
  # pry-stack_explorer.rb
2
2
  # (C) John Mair (banisterfiend); MIT license
3
3
 
4
- require "pry-stack_explorer/commands"
4
+ require "pry-stack_explorer/stack_commands"
5
5
  require "pry-stack_explorer/frame_manager"
6
6
  require "pry-stack_explorer/when_started_hook"
7
7
  require "binding_of_caller"
@@ -123,18 +123,3 @@ Pry.config.hooks.add_hook(:when_started, :save_caller_bindings, PryStackExplorer
123
123
  # Import the StackExplorer commands
124
124
  Pry.config.commands.import PryStackExplorer::Commands
125
125
 
126
- # monkey-patch the whereami command to show some frame information,
127
- # useful for navigating stack.
128
- Pry.config.hooks.add_hook(:before_whereami, :stack_explorer) do
129
- if PryStackExplorer.frame_manager(_pry_) && !internal_binding?(target)
130
- bindings = PryStackExplorer.frame_manager(_pry_).bindings
131
- binding_index = PryStackExplorer.frame_manager(_pry_).binding_index
132
-
133
- info = "#{Pry::Helpers::Text.bold('Frame:')} "+
134
- "#{binding_index}/#{bindings.size - 1} "+
135
- "#{bindings[binding_index].frame_type}"
136
-
137
- output.puts "\n"
138
- output.puts info
139
- end
140
- end
@@ -49,7 +49,7 @@ module PryStackExplorer
49
49
  b_self = b.eval('self')
50
50
  type = b.frame_type ? "[#{b.frame_type}]".ljust(9) : ""
51
51
  desc = b.frame_description ? "#{b.frame_description}" : "#{frame_description(b)}"
52
- sig = PryMoves::Helpers.method_signature_with_owner b
52
+ sig = PryMoves::Formatter.new.method_signature b
53
53
 
54
54
  self_clipped = "#{Pry.view_clip(b_self)}"
55
55
  path = "@ #{b.eval('__FILE__')}:#{b.eval('__LINE__')}"
@@ -87,14 +87,18 @@ module PryStackExplorer
87
87
  frame_manager.bindings.index(new_frame)
88
88
  end
89
89
 
90
- def find_frame_by_direction(up_or_down, step_into_vapid: false)
91
- frame_index = find_frame_by_block(up_or_down) do |b|
92
- step_into_vapid or
93
- not b.local_variable_defined?(:vapid_frame)
90
+ def find_frame_by_direction(dir, step_into_vapid: false)
91
+ frame_index = find_frame_by_block(dir) do |b|
92
+ step_into_vapid or
93
+ not frame_manager.bindings.vapid?(b)
94
94
  end
95
95
 
96
+ if !frame_index and !step_into_vapid
97
+ frame_index = find_frame_by_block(dir) {true}
98
+ end
99
+
96
100
  frame_index ||
97
- raise(Pry::CommandError, "At #{up_or_down == :up ? 'top' : 'bottom'} of stack, cannot go further")
101
+ raise(Pry::CommandError, "At #{dir == :up ? 'top' : 'bottom'} of stack, cannot go further")
98
102
  end
99
103
 
100
104
  def move(direction, param)
@@ -2,94 +2,39 @@ module PryStackExplorer
2
2
  class WhenStartedHook
3
3
  include Pry::Helpers::BaseHelpers
4
4
 
5
- def caller_bindings(target)
6
- bindings = binding.callers
7
- pre_callers = Thread.current[:pre_callers]
8
- bindings = bindings + pre_callers if pre_callers
9
- bindings = remove_internal_frames(bindings)
10
- mark_vapid_frames(bindings)
11
- bindings
12
- end
13
-
14
5
  def call(target, options, _pry_)
15
6
  start_from_console = target.eval('__callee__').nil? &&
16
7
  target.eval('__FILE__') == '<main>' &&
17
8
  target.eval('__LINE__') == 0
18
9
  return if start_from_console
19
10
 
20
- target ||= _pry_.binding_stack.first if _pry_
21
11
  options = {
22
- :call_stack => true,
23
- :initial_frame => 0
12
+ call_stack: true
24
13
  }.merge!(options)
25
14
 
26
- return if !options[:call_stack]
15
+ return unless options[:call_stack]
16
+ initial_frame = options[:initial_frame]
27
17
 
28
18
  if options[:call_stack].is_a?(Array)
29
19
  bindings = options[:call_stack]
30
-
20
+ initial_frame ||= 0
31
21
  unless valid_call_stack?(bindings)
32
22
  raise ArgumentError, ":call_stack must be an array of bindings"
33
23
  end
34
24
  else
35
- bindings = caller_bindings(target)
36
- initial_frame = bindings.find do |b|
37
- not b.local_variable_defined?(:vapid_frame)
25
+ bindings = PryMoves::BindingsStack.new
26
+ initial_frame ||= bindings.suggest_initial_frame_index
27
+ # if Thread.current[:pry_moves_debug] and initial_frame > 0
28
+ if initial_frame > 0
29
+ PryMoves.messages << "👽 Frames hidden: #{initial_frame}"
38
30
  end
39
- options[:initial_frame] = bindings.index initial_frame
40
31
  end
41
32
 
42
- PryStackExplorer.create_and_push_frame_manager bindings, _pry_, initial_frame: options[:initial_frame]
33
+ PryStackExplorer.create_and_push_frame_manager bindings, _pry_, initial_frame: initial_frame
43
34
  end
44
35
 
45
36
  private
46
37
 
47
- def mark_vapid_frames(bindings)
48
- stepped_out = false
49
- actual_file, actual_method = nil, nil
50
-
51
- bindings.each do |binding|
52
- if stepped_out
53
- if actual_file == binding.eval("__FILE__") and actual_method == binding.eval("__method__")
54
- stepped_out = false
55
- else
56
- binding.local_variable_set :vapid_frame, true
57
- end
58
- elsif binding.frame_type == :block
59
- stepped_out = true
60
- actual_file = binding.eval("__FILE__")
61
- actual_method = binding.eval("__method__")
62
- end
63
-
64
- if binding.local_variable_defined? :hide_from_stack
65
- binding.local_variable_set :vapid_frame, true
66
- end
67
- end
68
- end
69
-
70
- # remove internal frames related to setting up the session
71
- def remove_internal_frames(bindings)
72
- i = top_internal_frame_index(bindings)
73
- # DEBUG:
74
- #bindings.each_with_index do |b, index|
75
- # puts "#{index}: #{b.eval("self.class")} #{b.eval("__method__")}"
76
- #end
77
- #puts "FOUND top internal frame: #{bindings.size} => #{i}"
78
-
79
- bindings.drop i+1
80
- end
81
-
82
- def top_internal_frame_index(bindings)
83
- bindings.rindex do |b|
84
- if b.frame_type == :method
85
- self_, method = b.eval("self"), b.eval("__method__")
86
- self_.equal?(Pry) && method == :start ||
87
- self_.class == Binding && method == :pry ||
88
- self_.class == PryMoves::Tracer && method == :tracing_func
89
- end
90
- end
91
- end
92
-
93
38
  def valid_call_stack?(bindings)
94
39
  bindings.any? && bindings.all? { |v| v.is_a?(Binding) }
95
40
  end
@@ -1,16 +1,18 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- pry-moves (0.1.11)
4
+ pry-moves (1.0.0)
5
5
  binding_of_caller (~> 0.7)
6
- pry (>= 0.10.4, < 1)
6
+ colorize (~> 0.8)
7
+ pry (>= 0.10.4, < 0.13)
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
10
11
  specs:
11
12
  binding_of_caller (0.8.0)
12
13
  debug_inspector (>= 0.0.1)
13
- coderay (1.1.2)
14
+ coderay (1.1.3)
15
+ colorize (0.8.1)
14
16
  debug_inspector (0.0.3)
15
17
  method_source (0.9.2)
16
18
  pry (0.12.2)
@@ -24,4 +26,4 @@ DEPENDENCIES
24
26
  pry-moves!
25
27
 
26
28
  BUNDLED WITH
27
- 1.17.0
29
+ 1.17.3
data/playground/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  ```
4
4
  be ruby sand.rb
5
+ be ruby test.rb
5
6
  ```
6
7
 
7
8
  ## Conditions to be met
@@ -16,6 +16,23 @@ class Playground
16
16
  binding.pry # step_into stop
17
17
  something_inside # point to step inside
18
18
  end
19
+
20
+ def skip_hidden_impl
21
+ binding.pry # skip_hidden_impl stop
22
+ hidden_self.something_inside # point to step inside
23
+ end
24
+
25
+ def hidden_self
26
+ hide_from_stack = true # hidden_self 1
27
+ self # hidden_self 2
28
+ end
29
+
30
+ def hidden_stop
31
+ hide_from_stack = true
32
+ binding.pry # hidden stop
33
+ dummy = :ok_next # hidden_stop for next
34
+ dummy = :ok_step # hidden_stop for step
35
+ end
19
36
 
20
37
  def continue
21
38
  binding.pry # first stop
@@ -39,6 +56,16 @@ class Playground
39
56
  step_by_name
40
57
  :after_step_by_name # after_step_by_name
41
58
  end
59
+
60
+ def early_return_wrap
61
+ early_return
62
+ :after_return # after early return
63
+ end
64
+
65
+ def early_return
66
+ return true if level_c # at early return
67
+ dummy = 1
68
+ end
42
69
 
43
70
  def level_a
44
71
  level_b # inside of level_a
@@ -52,7 +79,7 @@ class Playground
52
79
  def level_c(param = nil)
53
80
  binding.pry # stop in level_c
54
81
  self
55
- end
82
+ end # exit from level_c
56
83
 
57
84
  def nested_block(early_return: false)
58
85
  binding.pry # stop in nested_block
@@ -62,7 +89,7 @@ class Playground
62
89
  end
63
90
  :after_block # after block
64
91
  end
65
-
92
+
66
93
  def native_block(early_return: false)
67
94
  binding.pry # stop in native_block
68
95
  2.times do |i| # iterator line
@@ -72,25 +99,83 @@ class Playground
72
99
  :after_block # after block
73
100
  end
74
101
 
102
+ def one_line_in_block
103
+ binding.pry # stop in one_line_in_block
104
+ iterator do |i| # iterator line
105
+ dummy = 1 # inside block
106
+ end
107
+ :after_block # after block
108
+ end
109
+
110
+ def one_line_block
111
+ binding.pry # stop in one_line_block
112
+ iterator { |i| dummy = 1 } # iterator line
113
+ :after_block # after block
114
+ end
115
+
116
+ def parentheses_in_loop
117
+ binding.pry # stop in parentheses_in_loop
118
+ i = 2
119
+ while (i = i - 1) > 0 # iterator line
120
+ dummy = 1 # inside block
121
+ end
122
+ :after_block # after block
123
+ end
124
+
75
125
  def zaloop(pass = :root)
76
126
  binding.pry if pass == :root # stop in zaloop
77
- iterator do |i|
127
+ iterator do |i| # iterator line
78
128
  dummy = 1 # inside block
79
129
  zaloop i if pass == :root
130
+ return unless pass == :root # after sub-zaloop
80
131
  end
81
132
  :after_block # after block
82
- end
133
+ end # exit from zaloop
83
134
 
84
135
  def method_with_redirection
85
- debug_redirect = '=level_a' # at method_with_redirection
136
+ debug_redirect = :level_a # at method_with_redirection
86
137
  level_a
87
138
  end
88
139
 
140
+ def instant_redirection
141
+ debug_redirect = '=something_inside'
142
+ binding.pry # at instant_redirection
143
+ something_inside
144
+ end
145
+
89
146
  def redirection_host
90
147
  binding.pry # redirection host
91
148
  method_with_redirection
92
149
  end
93
150
 
151
+ def something_inside
152
+ :something # some internal line
153
+ end
154
+
155
+ def method_with_breakpoints
156
+ binding.pry # method_with_breakpoints host
157
+ dummy = 1 # some internal line
158
+ debug_ # breakpoint
159
+ dummy = 1 # after breakpoint
160
+ dummy = 1 # after after breakpoint
161
+ debug_ # breakpoint 2
162
+ dummy = 1 # after breakpoint 2
163
+ end
164
+
165
+ def skip_test
166
+ binding.pry # stop in skip_test
167
+ skipped_method.not_skipped_method # next step
168
+ end
169
+
170
+ def skipped_method
171
+ pry_moves_skip = true # at skipped_method
172
+ self # at skipped_method
173
+ end
174
+
175
+ def not_skipped_method
176
+ :not_skipped_method # at not_skipped_method
177
+ end
178
+
94
179
  private
95
180
 
96
181
  def iterator
@@ -99,10 +184,10 @@ class Playground
99
184
  yield i
100
185
  :post_yield # post_yield
101
186
  end
102
- end
103
-
104
- def something_inside
105
- :something # some internal line
187
+ end # exit from iterator
188
+
189
+ def debug_
190
+ :something # inside of debug method
106
191
  end
107
192
 
108
193
  end
data/playground/test.rb CHANGED
@@ -2,4 +2,8 @@ require 'pry-moves'
2
2
  require_relative '../playground/playground.rb'
3
3
 
4
4
  i = Playground.new
5
- i.recursion
5
+ if ARGV[0]
6
+ i.send ARGV[0]
7
+ else
8
+ i.zaloop
9
+ end
@@ -0,0 +1 @@
1
+ bundle exec ruby playground/test.rb $@
data/pry-moves.gemspec CHANGED
@@ -18,8 +18,9 @@ Gem::Specification.new do |gem|
18
18
  gem.require_paths = ["lib"]
19
19
 
20
20
  # Dependencies
21
- gem.required_ruby_version = '>= 1.8.7'
22
- gem.add_runtime_dependency 'pry', '>= 0.10.4', '< 0.12.0'
21
+ gem.required_ruby_version = '>= 1.8.7', '< 3'
22
+ gem.add_runtime_dependency 'pry', '>= 0.10.4', '< 0.13'
23
23
  gem.add_runtime_dependency 'binding_of_caller', '~> 0.7'
24
+ gem.add_runtime_dependency 'colorize', '~> 0.8'
24
25
  gem.add_development_dependency 'pry-remote', '~> 0.1.6'
25
26
  end
data/publish.sh CHANGED
@@ -1,2 +1,3 @@
1
- gem build pry-moves.gemspec
1
+ bundle exec rspec && \
2
+ gem build pry-moves.gemspec && \
2
3
  gem push pry-moves-`ruby -e 'require "./lib/pry-moves/version.rb"; puts PryMoves::VERSION'`.gem
@@ -7,25 +7,23 @@ describe 'backtrace' do
7
7
  [nil, 'stop in level_c'],
8
8
  ['bt', lambda{|b, output|
9
9
  lines = output.split("\n").reverse
10
- expect(lines[0]).to end_with 'level_c(param=?)'
11
- expect(lines[1]).to end_with 'level_a()'
12
- expect(lines[2]).to include 'Playground:'
13
- expect(lines[3]).to end_with ':block'
14
- expect(lines[4]).to include 'RSpec::ExampleGroups'
15
- expect(lines.count).to be 5
10
+ expect(lines[0]).to end_with 'level_c(param=? nil)'
11
+ expect(lines[1]).to end_with 'frames hidden: 1'
12
+ expect(lines[2]).to end_with 'level_a()'
13
+ expect(lines[3]).to include 'Playground'
14
+ expect(lines[4]).to end_with ':block'
15
+ expect(lines[5]).to include 'RSpec::ExampleGroups'
16
+ expect(lines.count).to be 7
16
17
  }],
17
- ['bt all', lambda{|b, output|
18
+ ['bt hidden', lambda{|b, output|
18
19
  lines = output.split("\n").reverse
19
20
  # show hidden frame
20
21
  expect(lines[1]).to end_with 'level_b()'
21
- expect(lines.count).to be 6
22
+ expect(lines.count).to be 11
22
23
  }],
23
- ['bt 2', lambda{|b, output|
24
+ ['up', lambda{|b, output|
24
25
  lines = output.split("\n").reverse
25
- expect(lines[0]).to end_with 'level_c(param=?)'
26
- expect(lines[1]).to end_with 'level_a()'
27
- expect(lines[3]).to start_with 'Latest 2 lines'
28
- expect(lines.count).to be 4
26
+ expect(lines[1]).to end_with 'level_b # inside of level_a'
29
27
  }],
30
28
  ]
31
29
  Playground.new.level_a