pry-moves 0.1.13 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|