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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +6 -4
- data/README.md +15 -7
- data/lib/commands/debug.rb +17 -0
- data/lib/commands/finish.rb +26 -0
- data/lib/commands/goto.rb +19 -0
- data/lib/commands/iterate.rb +22 -0
- data/lib/commands/next.rb +37 -0
- data/lib/commands/next_breakpoint.rb +22 -0
- data/lib/commands/step.rb +83 -0
- data/lib/commands/trace_command.rb +87 -0
- data/lib/commands/trace_helpers.rb +49 -0
- data/lib/commands/traced_method.rb +71 -0
- data/lib/debug_sugar.rb +72 -0
- data/lib/pry-moves/add_suffix.rb +88 -0
- data/lib/pry-moves/backtrace.rb +67 -43
- data/lib/pry-moves/bindings_stack.rb +97 -0
- data/lib/pry-moves/commands.rb +42 -3
- data/lib/pry-moves/formatter.rb +74 -0
- data/lib/pry-moves/painter.rb +3 -2
- data/lib/pry-moves/pry_ext.rb +64 -16
- data/lib/pry-moves/pry_wrapper.rb +30 -17
- data/lib/pry-moves/restartable.rb +38 -0
- data/lib/pry-moves/version.rb +1 -1
- data/lib/pry-moves/watch.rb +3 -0
- data/lib/pry-moves.rb +65 -6
- data/lib/pry-stack_explorer/frame_manager.rb +6 -9
- data/lib/pry-stack_explorer/pry-stack_explorer.rb +1 -16
- data/lib/pry-stack_explorer/{commands.rb → stack_commands.rb} +10 -6
- data/lib/pry-stack_explorer/when_started_hook.rb +10 -65
- data/playground/Gemfile.lock +6 -4
- data/playground/README.md +1 -0
- data/playground/playground.rb +94 -9
- data/playground/test.rb +5 -1
- data/playground/test.sh +1 -0
- data/pry-moves.gemspec +3 -2
- data/publish.sh +2 -1
- data/spec/backtrace_spec.rb +11 -13
- data/spec/blocks_spec.rb +41 -8
- data/spec/commands_spec.rb +26 -25
- data/spec/pry_debugger.rb +5 -1
- data/spec/redirection_spec.rb +7 -0
- data/spec/spec_helper.rb +9 -4
- data/spec/step_spec.rb +51 -0
- metadata +43 -13
- data/lib/pry-moves/helpers.rb +0 -56
- data/lib/pry-moves/trace_commands.rb +0 -109
- data/lib/pry-moves/traced_method.rb +0 -61
- data/lib/pry-moves/tracer.rb +0 -140
- 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/
|
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::
|
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(
|
91
|
-
frame_index = find_frame_by_block(
|
92
|
-
|
93
|
-
not
|
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 #{
|
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
|
-
:
|
23
|
-
:initial_frame => 0
|
12
|
+
call_stack: true
|
24
13
|
}.merge!(options)
|
25
14
|
|
26
|
-
return
|
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 =
|
36
|
-
initial_frame
|
37
|
-
|
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:
|
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
|
data/playground/Gemfile.lock
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
pry-moves (0.
|
4
|
+
pry-moves (1.0.0)
|
5
5
|
binding_of_caller (~> 0.7)
|
6
|
-
|
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.
|
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.
|
29
|
+
1.17.3
|
data/playground/README.md
CHANGED
data/playground/playground.rb
CHANGED
@@ -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 =
|
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
|
105
|
-
:something #
|
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
data/playground/test.sh
ADDED
@@ -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.
|
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
data/spec/backtrace_spec.rb
CHANGED
@@ -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 '
|
12
|
-
expect(lines[2]).to
|
13
|
-
expect(lines[3]).to
|
14
|
-
expect(lines[4]).to
|
15
|
-
expect(lines
|
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
|
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
|
22
|
+
expect(lines.count).to be 11
|
22
23
|
}],
|
23
|
-
['
|
24
|
+
['up', lambda{|b, output|
|
24
25
|
lines = output.split("\n").reverse
|
25
|
-
expect(lines[
|
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
|