pry-moves 1.0.2 → 1.0.3
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.lock +4 -2
- data/README.md +21 -9
- data/bin/rspec +30 -0
- data/lib/commands/iterate.rb +7 -2
- data/lib/commands/next.rb +21 -16
- data/lib/commands/next_breakpoint.rb +8 -11
- data/lib/commands/step.rb +3 -2
- data/lib/commands/trace_command.rb +10 -6
- data/lib/pry-moves/backtrace.rb +23 -72
- data/lib/pry-moves/backtrace_builder.rb +92 -0
- data/lib/pry-moves/bindings_stack.rb +7 -6
- data/lib/pry-moves/code_reloader.rb +36 -0
- data/lib/pry-moves/commands.rb +11 -0
- data/lib/pry-moves/diff.rb +27 -0
- data/lib/pry-moves/formatter.rb +3 -1
- data/lib/pry-moves/pry_ext.rb +10 -4
- data/lib/pry-moves/pry_wrapper.rb +1 -1
- data/lib/pry-moves/restartable.rb +5 -1
- data/lib/pry-moves/tools.rb +22 -0
- data/lib/pry-moves/version.rb +1 -1
- data/lib/pry-moves.rb +42 -43
- data/lib/pry-stack_explorer/frame_helpers.rb +1 -0
- data/lib/requires.rb +38 -0
- data/lib/sugar/debug_of_missing.rb +44 -0
- data/lib/{debug_sugar.rb → sugar/debug_sugar.rb} +28 -9
- data/playground/Gemfile.lock +3 -3
- data/playground/playground.rb +7 -2
- data/pry-moves.gemspec +1 -0
- data/spec/backtrace_spec.rb +3 -0
- data/spec/commands_spec.rb +2 -0
- data/spec/spec_helper.rb +2 -1
- metadata +30 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf124819313d4f06ebe4b9d81d1b392cf06e96028ebef3ef67604642f9529c70
|
4
|
+
data.tar.gz: d07e5afae2c9bf9ce303a1731706af1921f79892496d188b9c5bf371f0160ed1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea4608c426807fbc02121a5bc32dddb36fe35fdf988872d964fe97424f9ce0d14d1b8bf28dd96012610ffcfdbb7d2567ceb97589a37b12e49a835c40eddc8fbc
|
7
|
+
data.tar.gz: d1fca032e8f5c76bd10012b9a170849238c335238ea1b899577c0d2ccb2109b2578b6f171ebcd2f6465f3fdba247c05feef0c9e0a77f481452dfd4c3c270e591
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
pry-moves (1.0.
|
4
|
+
pry-moves (1.0.3)
|
5
|
+
awesome_print (>= 1.8.0)
|
5
6
|
binding_of_caller (~> 0.7)
|
6
7
|
colorize (~> 0.8)
|
7
8
|
diffy (~> 3.4.0)
|
@@ -10,13 +11,14 @@ PATH
|
|
10
11
|
GEM
|
11
12
|
remote: https://rubygems.org/
|
12
13
|
specs:
|
14
|
+
awesome_print (1.9.2)
|
13
15
|
binding_of_caller (0.8.0)
|
14
16
|
debug_inspector (>= 0.0.1)
|
15
17
|
coderay (1.1.2)
|
16
18
|
colorize (0.8.1)
|
17
19
|
debug_inspector (1.1.0)
|
18
20
|
diff-lcs (1.3)
|
19
|
-
diffy (3.4.
|
21
|
+
diffy (3.4.2)
|
20
22
|
method_source (0.9.0)
|
21
23
|
pry (0.11.3)
|
22
24
|
coderay (~> 1.1.0)
|
data/README.md
CHANGED
@@ -18,16 +18,17 @@ Documentation for latest version. For [v0.1.12 see documentation here](https://g
|
|
18
18
|
* `s +` - step into function, including hidden frames
|
19
19
|
* `f` - **finish** execution of current frame (block or method) and stop at next line on higher level
|
20
20
|
* `c` - **continue**
|
21
|
-
* `b` - go to next breakpoint (
|
22
|
-
* `
|
21
|
+
* `b` - go to next breakpoint (methods marked with `pry_breakpoint = :some_scope` variable)
|
22
|
+
* `add-bp var_name [line_number]` - add to script in this place conditional breakpoint: `debug if var_name == <it's value>`
|
23
|
+
* `ir` - **iterate**, go to next iteration of current block
|
23
24
|
* `g 10` - **goto** line 10
|
24
25
|
* `bt` - show backtrace, excluding hidden frames
|
25
26
|
* `bt +` `bt hidden` - show backtrace including hidden frames
|
26
27
|
* `bt a` `bt all` - full backtrace with system and hidden frames
|
27
28
|
* `bt 10` - go to backtrace line 10
|
28
|
-
* `bt
|
29
|
-
* `bt diff` - diff with saved backtrace
|
29
|
+
* `bt diff` - diff of backtraces (`bt save` for persistent save of 1st backtrace)
|
30
30
|
* `bt > foo` - write backtrace to file `log/backtrace_foo.log`
|
31
|
+
* `bt ::ClassName` - list objects in backtrace which class name contains "ClassName"
|
31
32
|
* `up`/`down`/`top`/`bottom` (`bm`) - move over call stack
|
32
33
|
* `up +` - move up, including vapid frames (block callers, hidden frames)
|
33
34
|
* `up pattern` - move up till first frame which method name or file position in format `folder/script.rb:12` matches regexp pattern
|
@@ -36,7 +37,8 @@ Documentation for latest version. For [v0.1.12 see documentation here](https://g
|
|
36
37
|
* `debug some_method(some_param)` - call `some_method(some_param)` and interactively step into it. This way you can virtually "step back" by executing previous pieces of code from current method
|
37
38
|
* `.method` or `123` or `:hash_key` - Continue traversing of last object in history. E.g. `orders` will list array, then `3` will enter `orders[3]`, then `.price` will enter `orders[3].price`
|
38
39
|
* `watch variable` - display variable's value on each step
|
39
|
-
*
|
40
|
+
* `diff expression` - display difference between saved expression (on first run) and expression 2
|
41
|
+
* `@` - restart and reload scripts (in app/ & spec/ by default), reload rake tasks. Configurable.
|
40
42
|
* `#` - exit with code 3, can be wrapped in bash script to fully reload ruby scripts
|
41
43
|
* `!` - exit
|
42
44
|
|
@@ -79,12 +81,22 @@ end
|
|
79
81
|
## Configuration
|
80
82
|
|
81
83
|
Here is default configuration, you can reassign it:
|
82
|
-
|
83
84
|
```ruby
|
85
|
+
PryMoves.reload_ruby_scripts = {
|
86
|
+
monitor: %w(app spec),
|
87
|
+
except: %w(app/assets app/views)
|
88
|
+
}
|
89
|
+
PryMoves.reload_rake_tasks = true
|
84
90
|
PryMoves::Backtrace::filter =
|
85
91
|
/(\/gems\/|\/rubygems\/|\/bin\/|\/lib\/ruby\/|\/pry-moves\/)/
|
86
92
|
```
|
87
93
|
|
94
|
+
Turn off features with environment variables:
|
95
|
+
```bash
|
96
|
+
PRY_MOVES_DEBUG_MISSING=off
|
97
|
+
PRY_MOVES_RELOADER=off
|
98
|
+
```
|
99
|
+
|
88
100
|
## Threads, helpers
|
89
101
|
|
90
102
|
To allow traveling to parent thread, use:
|
@@ -135,9 +147,10 @@ Please note that debugging functionality is implemented through
|
|
135
147
|
## Testing
|
136
148
|
|
137
149
|
```
|
138
|
-
|
150
|
+
bin/rspec
|
151
|
+
bin/rspec -f d # Output result of each spec example
|
139
152
|
|
140
|
-
DEBUG=true
|
153
|
+
DEBUG=true bin/rspec -e 'backtrace should backtrace'
|
141
154
|
```
|
142
155
|
|
143
156
|
## ToDo
|
@@ -168,7 +181,6 @@ file an [issue][issues].
|
|
168
181
|
[set_trace_func]: http://www.ruby-doc.org/core-1.9.3/Kernel.html#method-i-set_trace_func
|
169
182
|
[pullrequests]: https://github.com/garmoshka-mo/pry-moves/pulls
|
170
183
|
[issues]: https://github.com/garmoshka-mo/pry-moves/issues
|
171
|
-
[changelog]: https://github.com/garmoshka-mo/pry-moves/blob/master/CHANGELOG.md
|
172
184
|
[debug.rb]: https://github.com/ruby/ruby/blob/trunk/lib/debug.rb
|
173
185
|
[Mon-Ouie]: https://github.com/Mon-Ouie
|
174
186
|
[pry_debug]: https://github.com/Mon-Ouie/pry_debug
|
data/bin/rspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require 'rspec/core'
|
5
|
+
|
6
|
+
RSpec::Core::Parser.class_eval do
|
7
|
+
|
8
|
+
alias original_parser parser
|
9
|
+
|
10
|
+
def parser(options)
|
11
|
+
parser = original_parser(options)
|
12
|
+
parser.on('-e', '--example STRING', "Run examples whose full nested names include STRING (may be",
|
13
|
+
" used more than once)") do |str|
|
14
|
+
|
15
|
+
str = str.split(" ").reject do |piece|
|
16
|
+
if (m = piece.match(/(\w+)=(.*)/))
|
17
|
+
ENV[m[1]] = m[2]
|
18
|
+
true
|
19
|
+
end
|
20
|
+
end.join(" ")
|
21
|
+
|
22
|
+
r = Regexp.compile(Regexp.escape(str), Regexp::IGNORECASE)
|
23
|
+
(options[:full_description] ||= []) << r
|
24
|
+
end
|
25
|
+
parser
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
load Gem.bin_path('rspec-core', 'rspec')
|
data/lib/commands/iterate.rb
CHANGED
@@ -3,20 +3,25 @@ class PryMoves::Iterate < PryMoves::TraceCommand
|
|
3
3
|
def init(binding_)
|
4
4
|
@iteration_start_line = binding_.eval('__LINE__')
|
5
5
|
@caller_digest = frame_digest(binding_)
|
6
|
+
@receiver = binding_.receiver
|
6
7
|
end
|
7
8
|
|
8
9
|
def trace(event, file, line, method, binding_)
|
9
10
|
return true if event == 'return' and
|
10
|
-
|
11
|
+
traced_method?(file, line, method, binding_)
|
11
12
|
|
12
13
|
# промотка итерации -
|
13
14
|
# попасть на ту же или предыдущую строку или выйти из дайджеста
|
14
15
|
# будучи в том же методе
|
15
16
|
event == 'line' and @call_depth == 0 and
|
16
|
-
|
17
|
+
traced_method?(file, line, method, binding_) and
|
17
18
|
(line <= @iteration_start_line or
|
18
19
|
@caller_digest != current_frame_digest
|
19
20
|
)
|
20
21
|
end
|
21
22
|
|
23
|
+
def traced_method?(file, line, method, binding_)
|
24
|
+
super and @receiver == binding_.receiver
|
25
|
+
end
|
26
|
+
|
22
27
|
end
|
data/lib/commands/next.rb
CHANGED
@@ -2,6 +2,7 @@ class PryMoves::Next < PryMoves::TraceCommand
|
|
2
2
|
|
3
3
|
def init(binding_)
|
4
4
|
@start_line = binding_.eval('__LINE__')
|
5
|
+
@receiver = binding_.receiver
|
5
6
|
@start_digest = frame_digest(binding_)
|
6
7
|
if @command[:param] == 'blockless'
|
7
8
|
@stay_at_frame = @start_digest
|
@@ -14,24 +15,28 @@ class PryMoves::Next < PryMoves::TraceCommand
|
|
14
15
|
|
15
16
|
return true if @call_depth < 0
|
16
17
|
|
17
|
-
return unless @call_depth == 0 and
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
18
|
+
return unless @call_depth == 0 and traced_method?(file, line, method, binding_)
|
19
|
+
|
20
|
+
if event == 'line'
|
21
|
+
if @stay_at_frame
|
22
|
+
return (
|
23
|
+
@stay_at_frame == current_frame_digest or
|
24
|
+
@c_stack_level < 0
|
25
|
+
)
|
26
|
+
elsif @start_line != line or (
|
27
|
+
@events_traced > 1 and # чтобы не застревало на while (vx = shift)
|
28
|
+
@start_digest == current_frame_digest # for correct iterating over one_line_in_block
|
29
|
+
)
|
30
|
+
return true
|
31
31
|
end
|
32
|
+
end
|
33
|
+
|
34
|
+
true if event == 'return' and
|
35
|
+
method == @method[:name] and @method.before_end?(line)
|
36
|
+
end
|
32
37
|
|
33
|
-
|
34
|
-
|
38
|
+
def traced_method?(file, line, method, binding_)
|
39
|
+
super and @receiver == binding_.receiver
|
35
40
|
end
|
36
41
|
|
37
42
|
end
|
@@ -1,22 +1,19 @@
|
|
1
1
|
class PryMoves::NextBreakpoint < PryMoves::TraceCommand
|
2
2
|
|
3
3
|
def init(binding_)
|
4
|
-
@reach_digest = frame_digest(binding_)
|
5
4
|
end
|
6
5
|
|
7
6
|
def trace(event, file, line, method, binding_)
|
8
|
-
if
|
9
|
-
|
10
|
-
|
11
|
-
else
|
12
|
-
return
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
if method.to_s.include? "debug"
|
17
|
-
@pry_start_options[:initial_frame] = 1
|
7
|
+
if binding_.local_variable_defined?(:pry_breakpoint) and
|
8
|
+
binding_.local_variable_get(:pry_breakpoint)
|
9
|
+
binding_.local_variable_set :pry_breakpoint, nil # reset breakpoint at visited method instance
|
18
10
|
true
|
19
11
|
end
|
12
|
+
|
13
|
+
# if method.to_s.include? "debug"
|
14
|
+
# @pry_start_options[:initial_frame] = 1
|
15
|
+
# true
|
16
|
+
# end
|
20
17
|
end
|
21
18
|
|
22
19
|
end
|
data/lib/commands/step.rb
CHANGED
@@ -7,7 +7,7 @@ class PryMoves::Step < PryMoves::TraceCommand
|
|
7
7
|
func = @command[:param]
|
8
8
|
redirect_step? binding_ # set @step_into_funcs from initial binding
|
9
9
|
if func == '+'
|
10
|
-
|
10
|
+
PryMoves.step_in_everywhere = true
|
11
11
|
elsif func
|
12
12
|
@find_straight_descendant = true
|
13
13
|
@step_into_funcs = [func]
|
@@ -18,6 +18,7 @@ class PryMoves::Step < PryMoves::TraceCommand
|
|
18
18
|
def trace(event, file, line, method, binding_)
|
19
19
|
if binding_.local_variable_defined? :pry_moves_skip
|
20
20
|
finish_cmd = {binding: binding_}
|
21
|
+
stop_tracing
|
21
22
|
PryMoves::Finish.new finish_cmd, @pry_start_options do |binding|
|
22
23
|
start_tracing
|
23
24
|
end
|
@@ -36,7 +37,7 @@ class PryMoves::Step < PryMoves::TraceCommand
|
|
36
37
|
|
37
38
|
return unless event == 'line'
|
38
39
|
|
39
|
-
if
|
40
|
+
if PryMoves.step_in_everywhere
|
40
41
|
return true
|
41
42
|
elsif @step_into_funcs
|
42
43
|
if @call_depth < 0
|
@@ -22,7 +22,7 @@ class TraceCommand
|
|
22
22
|
|
23
23
|
binding_ = @command[:binding] # =Command.target - more rich, contains required @iseq
|
24
24
|
unless binding_.instance_variable_get('@iseq')
|
25
|
-
binding_ = PryMoves::BindingsStack.new.initial_frame
|
25
|
+
binding_ = PryMoves::BindingsStack.new(@pry_start_options).initial_frame
|
26
26
|
end
|
27
27
|
@method = PryMoves::TracedMethod.new binding_
|
28
28
|
|
@@ -57,14 +57,14 @@ class TraceCommand
|
|
57
57
|
Thread.current : Kernel
|
58
58
|
end
|
59
59
|
|
60
|
-
def tracing_func(event, file, line,
|
60
|
+
def tracing_func(event, file, line, method, binding_, klass)
|
61
61
|
|
62
62
|
# Ignore traces inside pry-moves code
|
63
63
|
return if file && TRACE_IGNORE_FILES.include?(File.expand_path(file))
|
64
64
|
return unless binding_ # ignore strange cases
|
65
65
|
|
66
66
|
# for cases when currently traced method called more times recursively
|
67
|
-
if event == "call" and
|
67
|
+
if event == "call" and traced_method?(file, line, method, binding_)
|
68
68
|
@call_depth += 1
|
69
69
|
elsif %w(c-call c-return).include?(event)
|
70
70
|
# todo: может быть, c-return тоже правильнее делать после trace
|
@@ -72,16 +72,20 @@ class TraceCommand
|
|
72
72
|
@c_stack_level += delta
|
73
73
|
end
|
74
74
|
|
75
|
-
printf "👟 %8s %s:%-2d %10s %8s dep:#{@call_depth} c_st:#{@c_stack_level}\n", event, file, line,
|
75
|
+
printf "👟 %8s %s:%-2d %10s %8s dep:#{@call_depth} c_st:#{@c_stack_level}\n", event, file, line, method, klass if PryMoves.trace # TRACE_MOVES=1
|
76
76
|
|
77
|
-
if trace event, file, line,
|
77
|
+
if trace event, file, line, method, binding_
|
78
78
|
@pry_start_options[:exit_from_method] = true if event == 'return'
|
79
79
|
stop_tracing
|
80
80
|
@callback.call binding_
|
81
|
-
elsif event == "return" and
|
81
|
+
elsif event == "return" and traced_method?(file, line, method, binding_)
|
82
82
|
@call_depth -= 1
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
+
def traced_method?(file, line, method, binding_)
|
87
|
+
@method.within?(file, line, method)
|
88
|
+
end
|
89
|
+
|
86
90
|
end
|
87
91
|
end
|
data/lib/pry-moves/backtrace.rb
CHANGED
@@ -3,8 +3,10 @@ require 'fileutils'
|
|
3
3
|
class PryMoves::Backtrace
|
4
4
|
|
5
5
|
FILTERS = %w[/gems/ /rubygems/ /bin/ /lib/ruby/]
|
6
|
+
@@backtrace = nil
|
6
7
|
|
7
8
|
class << self
|
9
|
+
attr_accessor :trim_path
|
8
10
|
|
9
11
|
def filter
|
10
12
|
@filter ||= Regexp.new FILTERS.join("|")
|
@@ -25,21 +27,27 @@ class PryMoves::Backtrace
|
|
25
27
|
|
26
28
|
def initialize(pry)
|
27
29
|
@pry = pry
|
28
|
-
@
|
30
|
+
@builder = PryMoves::BacktraceBuilder.new frame_manager
|
29
31
|
end
|
30
32
|
|
31
33
|
def run_command(param, param2)
|
32
|
-
if param == 'save'
|
33
|
-
|
34
|
-
|
34
|
+
if param == 'save' || param == 'diff' && @@backtrace.nil?
|
35
|
+
@@hard_saved = param == 'save'
|
36
|
+
@builder.filter = 'hidden'
|
37
|
+
@builder.lines_numbers = false
|
38
|
+
@@backtrace = @builder.build_backtrace
|
35
39
|
@pry.output.puts "💾 Backtrace saved (#{@@backtrace.count} lines)"
|
36
40
|
elsif param == 'diff'
|
37
|
-
@filter = 'hidden'
|
41
|
+
@builder.filter = 'hidden'
|
42
|
+
@builder.lines_numbers = false
|
38
43
|
diff
|
44
|
+
@@backtrace = nil unless @@hard_saved
|
45
|
+
elsif param and (match = param.match /^::(\w*)/)
|
46
|
+
@builder.colorize = true
|
47
|
+
@pry.output.puts @builder.objects_of_class match[1]
|
39
48
|
elsif param.is_a?(String) and (match = param.match /^>(.*)/)
|
40
49
|
suffix = match[1].size > 0 ? match[1] : param2
|
41
|
-
@
|
42
|
-
write_to_file build_backtrace, suffix
|
50
|
+
write_to_file @builder.build_backtrace, suffix
|
43
51
|
elsif param and param.match /\d+/
|
44
52
|
index = param.to_i
|
45
53
|
frame_manager.goto_index index
|
@@ -51,68 +59,9 @@ class PryMoves::Backtrace
|
|
51
59
|
private
|
52
60
|
|
53
61
|
def print_backtrace filter
|
54
|
-
@colorize = true
|
55
|
-
@
|
56
|
-
@
|
57
|
-
@pry.output.puts build_backtrace
|
58
|
-
end
|
59
|
-
|
60
|
-
def build_backtrace
|
61
|
-
show_all = %w(a all).include?(@filter)
|
62
|
-
show_vapid = %w(+ hidden vapid).include?(@filter) || show_all
|
63
|
-
result = []
|
64
|
-
current_object, vapid_count = nil, 0
|
65
|
-
|
66
|
-
recursion = PryMoves::Recursion::Holder.new
|
67
|
-
|
68
|
-
frame_manager.bindings.reverse.each do |binding|
|
69
|
-
next if !show_all and binding.eval('__FILE__').match self.class::filter
|
70
|
-
|
71
|
-
if !show_vapid and binding.hidden
|
72
|
-
vapid_count += 1
|
73
|
-
next
|
74
|
-
end
|
75
|
-
|
76
|
-
if vapid_count > 0
|
77
|
-
result << "👽 frames hidden: #{vapid_count}"
|
78
|
-
vapid_count = 0
|
79
|
-
end
|
80
|
-
|
81
|
-
obj, debug_snapshot = binding.eval '[self, (debug_snapshot rescue nil)]'
|
82
|
-
# Comparison of objects directly may raise exception
|
83
|
-
if current_object.object_id != obj.object_id
|
84
|
-
result << "#{debug_snapshot || @formatter.format_obj(obj)}"
|
85
|
-
current_object = obj
|
86
|
-
end
|
87
|
-
|
88
|
-
file, line = binding.eval('[__FILE__, __LINE__]')
|
89
|
-
recursion.track file, line, result.count, binding.index unless show_vapid
|
90
|
-
result << build_line(binding, file, line)
|
91
|
-
end
|
92
|
-
|
93
|
-
# recursion.each { |t| t.apply result }
|
94
|
-
|
95
|
-
result << "👽 frames hidden: #{vapid_count}" if vapid_count > 0
|
96
|
-
|
97
|
-
result
|
98
|
-
end
|
99
|
-
|
100
|
-
def build_line(binding, file, line)
|
101
|
-
file = @formatter.shorten_path "#{file}"
|
102
|
-
|
103
|
-
signature = @formatter.method_signature binding
|
104
|
-
signature = ":#{binding.frame_type}" if !signature or signature.length < 1
|
105
|
-
|
106
|
-
indent = if frame_manager.current_frame == binding
|
107
|
-
'==> '
|
108
|
-
elsif true #@lines_numbers
|
109
|
-
s = "#{binding.index}:".ljust(4, ' ')
|
110
|
-
@colorize ? "\e[2;49;90m#{s}\e[0m" : s
|
111
|
-
else
|
112
|
-
' '
|
113
|
-
end
|
114
|
-
|
115
|
-
"#{indent}#{file}:#{line} #{signature}"
|
62
|
+
@builder.colorize = true
|
63
|
+
@builder.filter = filter if filter.is_a? String
|
64
|
+
@pry.output.puts @builder.build_backtrace
|
116
65
|
end
|
117
66
|
|
118
67
|
def frame_manager
|
@@ -135,9 +84,10 @@ class PryMoves::Backtrace
|
|
135
84
|
def diff
|
136
85
|
return STDERR.puts "No backtrace saved. Use `bt save` first".yellow unless defined? @@backtrace
|
137
86
|
|
138
|
-
|
139
|
-
|
140
|
-
|
87
|
+
@pry.output.puts Diffy.diff(
|
88
|
+
@@backtrace.join("\n"),
|
89
|
+
@builder.build_backtrace.join("\n")
|
90
|
+
)
|
141
91
|
end
|
142
92
|
|
143
93
|
end
|
@@ -164,4 +114,5 @@ Pry.config.exception_handler = proc do |output, exception, _|
|
|
164
114
|
end
|
165
115
|
end
|
166
116
|
end
|
117
|
+
|
167
118
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
class PryMoves::BacktraceBuilder
|
2
|
+
|
3
|
+
attr_writer :lines_numbers, :filter, :colorize
|
4
|
+
|
5
|
+
def initialize frame_manager
|
6
|
+
@frame_manager = frame_manager
|
7
|
+
@filter = nil
|
8
|
+
@colorize = false
|
9
|
+
@lines_numbers = true
|
10
|
+
@formatter = PryMoves::Formatter.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def build_backtrace
|
14
|
+
show_all = %w(a all).include?(@filter)
|
15
|
+
show_vapid = %w(+ hidden vapid).include?(@filter) || show_all
|
16
|
+
result = []
|
17
|
+
current_object, vapid_count = nil, 0
|
18
|
+
|
19
|
+
recursion = PryMoves::Recursion::Holder.new
|
20
|
+
|
21
|
+
@frame_manager.bindings.reverse.each do |binding|
|
22
|
+
next if !show_all and binding.eval('__FILE__').match PryMoves::Backtrace::filter
|
23
|
+
|
24
|
+
if !show_vapid and binding.hidden
|
25
|
+
vapid_count += 1
|
26
|
+
next
|
27
|
+
end
|
28
|
+
|
29
|
+
if vapid_count > 0
|
30
|
+
result << "👽 frames hidden: #{vapid_count}"
|
31
|
+
vapid_count = 0
|
32
|
+
end
|
33
|
+
|
34
|
+
obj, debug_snapshot = binding.eval '[self, (debug_snapshot rescue nil)]'
|
35
|
+
# Comparison of objects directly may raise exception
|
36
|
+
if current_object.object_id != obj.object_id
|
37
|
+
result << "#{debug_snapshot || @formatter.format_obj(obj)}"
|
38
|
+
current_object = obj
|
39
|
+
end
|
40
|
+
|
41
|
+
file, line = binding.eval('[__FILE__, __LINE__]')
|
42
|
+
recursion.track file, line, result.count, binding.index unless show_vapid
|
43
|
+
result << build_line(binding, file, line)
|
44
|
+
end
|
45
|
+
|
46
|
+
# recursion.each { |t| t.apply result }
|
47
|
+
|
48
|
+
result << "👽 frames hidden: #{vapid_count}" if vapid_count > 0
|
49
|
+
|
50
|
+
result
|
51
|
+
end
|
52
|
+
|
53
|
+
def objects_of_class class_pattern
|
54
|
+
result = []
|
55
|
+
last_object = nil
|
56
|
+
class_pattern.downcase!
|
57
|
+
@frame_manager.bindings.reverse.each do |binding|
|
58
|
+
obj = binding.eval 'self'
|
59
|
+
next if !obj.class.to_s.downcase.include?(class_pattern) ||
|
60
|
+
last_object.object_id == obj.object_id
|
61
|
+
|
62
|
+
result << "#{line_num binding}#{@formatter.format_obj(obj)}"
|
63
|
+
last_object = obj
|
64
|
+
end
|
65
|
+
result
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def line_num binding
|
71
|
+
num = "#{binding.index}:".ljust(4, ' ')
|
72
|
+
@colorize ? "\e[2;49;90m#{num}\e[0m" : num
|
73
|
+
end
|
74
|
+
|
75
|
+
def build_line(binding, file, line)
|
76
|
+
file = @formatter.shorten_path "#{file}"
|
77
|
+
|
78
|
+
signature = @formatter.method_signature binding
|
79
|
+
signature = ":#{binding.frame_type}" if !signature or signature.length < 1
|
80
|
+
|
81
|
+
indent = if @frame_manager.current_frame == binding
|
82
|
+
'==> '
|
83
|
+
elsif @lines_numbers
|
84
|
+
line_num binding
|
85
|
+
else
|
86
|
+
' '
|
87
|
+
end
|
88
|
+
|
89
|
+
"#{indent}#{file}:#{line} #{signature}"
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -14,16 +14,17 @@ class PryMoves::BindingsStack < Array
|
|
14
14
|
def suggest_initial_frame_index
|
15
15
|
m = PryMoves::TracedMethod.last
|
16
16
|
return 0 if m and m.binding_inside?(first)
|
17
|
-
index {|b|
|
17
|
+
index {|b| fits_for_initial_frame b} || 0
|
18
18
|
end
|
19
19
|
def initial_frame
|
20
|
-
find {|b|
|
20
|
+
find {|b| fits_for_initial_frame b}
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
def fits_for_initial_frame b
|
24
|
+
PryMoves.step_in_everywhere or
|
25
|
+
not b.hidden and (
|
26
|
+
@options[:is_error] or b.eval("__method__") != :initialize
|
27
|
+
)
|
27
28
|
end
|
28
29
|
|
29
30
|
private
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class CodeReloader
|
2
|
+
|
3
|
+
def initialize
|
4
|
+
@timestamps = {}
|
5
|
+
traverse_files do |path|
|
6
|
+
@timestamps[path] = File.mtime(path)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def reload
|
11
|
+
traverse_files do |path|
|
12
|
+
if @timestamps[path] != File.mtime(path)
|
13
|
+
@timestamps[path] = File.mtime(path)
|
14
|
+
load path
|
15
|
+
# Log.info "⚡️ file reloaded #{path}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def traverse_files
|
23
|
+
paths = PryMoves.reload_ruby_scripts[:monitor]
|
24
|
+
except = PryMoves.reload_ruby_scripts[:except]
|
25
|
+
paths.each do |root|
|
26
|
+
files = Dir.glob("#{root}/**/*")
|
27
|
+
files.each do |path|
|
28
|
+
if path.end_with? '.rb' and
|
29
|
+
not except.any? {|_| path.start_with? _}
|
30
|
+
yield path
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/lib/pry-moves/commands.rb
CHANGED
@@ -26,9 +26,15 @@ module PryMoves
|
|
26
26
|
end
|
27
27
|
alias_command 'b', 'next_breakpoint'
|
28
28
|
|
29
|
+
block_command 'add-bp', 'Add conditional breakpoint to script' do |var_name, line_number|
|
30
|
+
PryMoves::Tools.new(_pry_).add_breakpoint var_name, line_number&.to_i, target
|
31
|
+
run 'restart'
|
32
|
+
end
|
33
|
+
|
29
34
|
block_command 'iterate', 'Go to next iteration of current block' do |param|
|
30
35
|
breakout_navigation :iterate, param
|
31
36
|
end
|
37
|
+
alias_command 'ir', 'iterate'
|
32
38
|
|
33
39
|
block_command 'goto', 'goto line' do |param|
|
34
40
|
breakout_navigation :goto, param
|
@@ -45,6 +51,11 @@ module PryMoves
|
|
45
51
|
PryMoves::Watch.instance.process_cmd param, target
|
46
52
|
end
|
47
53
|
|
54
|
+
block_command 'diff', 'Display difference' do
|
55
|
+
cmd = arg_string.gsub(/^diff/, '').strip
|
56
|
+
PryMoves::Diff.new(_pry_, target).run_command cmd
|
57
|
+
end
|
58
|
+
|
48
59
|
block_command 'bt', 'Backtrace' do |param, param2|
|
49
60
|
PryMoves::Backtrace.new(_pry_).run_command param, param2
|
50
61
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class PryMoves::Diff
|
2
|
+
|
3
|
+
@@saved_dump = nil
|
4
|
+
|
5
|
+
def initialize(pry, binding)
|
6
|
+
@pry = pry
|
7
|
+
@binding = binding
|
8
|
+
end
|
9
|
+
|
10
|
+
def run_command cmd
|
11
|
+
if !@@saved_dump
|
12
|
+
@@saved_dump = eval_cmd cmd
|
13
|
+
@pry.output.puts "💾 Saved for diff compare:\n".cyan + @@saved_dump
|
14
|
+
else
|
15
|
+
diff = Diffy.diff @@saved_dump, eval_cmd(cmd)
|
16
|
+
@pry.output.puts diff
|
17
|
+
@@saved_dump = nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def eval_cmd cmd
|
24
|
+
"#{@binding.eval(cmd)}"
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/lib/pry-moves/formatter.rb
CHANGED
@@ -56,7 +56,9 @@ class PryMoves::Formatter
|
|
56
56
|
PATH_TRASH = defined?(Rails) ? Rails.root.to_s : Dir.pwd
|
57
57
|
|
58
58
|
def shorten_path(path)
|
59
|
-
path.gsub( /^#{PATH_TRASH}\//, '')
|
59
|
+
path = path.gsub( /^#{PATH_TRASH}\//, '')
|
60
|
+
PryMoves::Backtrace.trim_path ?
|
61
|
+
File.basename(path, ".*") : path
|
60
62
|
end
|
61
63
|
|
62
64
|
def format_obj(obj)
|
data/lib/pry-moves/pry_ext.rb
CHANGED
@@ -86,7 +86,8 @@ Pry::Command::Whereami.class_eval do
|
|
86
86
|
|
87
87
|
formatter = PryMoves::Formatter.new
|
88
88
|
prefix = Thread.current[:pry_moves_debug] ? "👾 " : ""
|
89
|
-
lines << "
|
89
|
+
lines << "🦆 step_in_everywhere" if PryMoves.step_in_everywhere
|
90
|
+
lines << "#{prefix}#{formatter.shorten_path location}:#{@line} #{me}"
|
90
91
|
lines << " ." + formatter.method_signature(target)
|
91
92
|
lines << ''
|
92
93
|
lines << "#{code.with_line_numbers(use_line_numbers?).with_marker(marker).highlighted}"
|
@@ -99,11 +100,14 @@ Pry::Command::Whereami.class_eval do
|
|
99
100
|
lines.join "\n"
|
100
101
|
end
|
101
102
|
|
102
|
-
def
|
103
|
+
def me
|
103
104
|
me = target.eval 'self' rescue nil
|
104
105
|
me = PryMoves::Painter.colorize me if me
|
105
|
-
|
106
|
-
|
106
|
+
me
|
107
|
+
end
|
108
|
+
|
109
|
+
def location
|
110
|
+
defined?(Rails) ? @file.gsub(Rails.root.to_s, '') : @file
|
107
111
|
end
|
108
112
|
end
|
109
113
|
|
@@ -123,7 +127,9 @@ Pry::Output.class_eval do
|
|
123
127
|
alias pry_moves_origin_for_puts puts
|
124
128
|
|
125
129
|
def puts *args
|
130
|
+
# <first> formatted by Pry.config.print = proc do |output, value|
|
126
131
|
first = args[0]
|
132
|
+
# Kernel.puts "Pry::Output.puts: #{first}"
|
127
133
|
if first.is_a? String and first.start_with? "(pry) output error"
|
128
134
|
first.slice! 400..-1
|
129
135
|
end
|
@@ -12,7 +12,7 @@ class PryWrapper
|
|
12
12
|
PryMoves.lock
|
13
13
|
|
14
14
|
initial_frame = PryMoves::BindingsStack.new(@pry_start_options).initial_frame
|
15
|
-
if not @pry_start_options[:pry_moves_loop] and
|
15
|
+
if not @pry_start_options[:pry_moves_loop] and initial_frame and
|
16
16
|
initial_frame.local_variable_defined? :debug_redirect
|
17
17
|
debug_redirect = initial_frame.local_variable_get(:debug_redirect)
|
18
18
|
PryMoves.messages << "⏩ redirected to #{debug_redirect}"
|
@@ -1,17 +1,21 @@
|
|
1
1
|
module PryMoves::Restartable
|
2
2
|
|
3
3
|
attr_accessor :restart_requested, :reload_requested,
|
4
|
+
:reload_ruby_scripts, :reloader,
|
4
5
|
:reload_rake_tasks
|
5
6
|
|
6
7
|
def restartable context
|
7
8
|
trigger :each_new_run, context
|
8
|
-
|
9
|
+
context[:retry] ||= 0
|
10
|
+
yield context
|
9
11
|
re_execution
|
10
12
|
rescue PryMoves::Restart
|
11
13
|
puts "🔄️ Restarting execution"
|
12
14
|
self.restart_requested = false
|
13
15
|
PryMoves.reset
|
16
|
+
PryMoves.reloader&.reload
|
14
17
|
trigger :restart, context
|
18
|
+
context[:retry] += 1
|
15
19
|
retry
|
16
20
|
rescue PryMoves::Reload
|
17
21
|
puts "🔮 try to use @ with reload"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class PryMoves::Tools
|
2
|
+
|
3
|
+
def initialize pry
|
4
|
+
@pry = pry
|
5
|
+
end
|
6
|
+
|
7
|
+
def add_breakpoint var_name, line_number, binding
|
8
|
+
file, line = binding.eval('[__FILE__, __LINE__]')
|
9
|
+
line_number ||= line
|
10
|
+
lines = IO.readlines(file)
|
11
|
+
|
12
|
+
value = binding.eval(var_name)
|
13
|
+
value = value.to_json if value.is_a? String
|
14
|
+
lines.insert line_number-1, "debug if #{var_name} == #{value}"
|
15
|
+
|
16
|
+
File.open(file, 'w') do |file|
|
17
|
+
file.puts lines
|
18
|
+
end
|
19
|
+
@pry.output.puts "🔴 Breakpoint added to #{File.basename file}:#{line_number}"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/lib/pry-moves/version.rb
CHANGED
data/lib/pry-moves.rb
CHANGED
@@ -1,37 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require 'colorize'
|
3
|
-
require 'diffy'
|
4
|
-
|
5
|
-
require 'pry-moves/version'
|
6
|
-
require 'pry-moves/pry_ext'
|
7
|
-
require 'pry-moves/commands'
|
8
|
-
require 'pry-moves/add_suffix'
|
9
|
-
require 'pry-moves/pry_wrapper'
|
10
|
-
require 'pry-moves/bindings_stack'
|
11
|
-
require 'pry-moves/formatter'
|
12
|
-
require 'pry-moves/backtrace'
|
13
|
-
require 'pry-moves/watch'
|
14
|
-
require 'pry-moves/painter'
|
15
|
-
require 'pry-moves/restartable'
|
16
|
-
require 'pry-moves/recursion_tracker'
|
17
|
-
require 'pry-moves/error_with_data'
|
18
|
-
|
19
|
-
require 'commands/traced_method'
|
20
|
-
require 'commands/trace_helpers'
|
21
|
-
require 'commands/trace_command'
|
22
|
-
require 'commands/debug'
|
23
|
-
require 'commands/finish'
|
24
|
-
require 'commands/goto'
|
25
|
-
require 'commands/iterate'
|
26
|
-
require 'commands/next'
|
27
|
-
require 'commands/next_breakpoint'
|
28
|
-
require 'commands/step'
|
29
|
-
|
30
|
-
require 'pry-stack_explorer/pry-stack_explorer'
|
31
|
-
require 'debug_sugar'
|
32
|
-
|
33
|
-
# Optionally load pry-remote monkey patches
|
34
|
-
require 'pry-moves/pry_remote_ext' if defined? PryRemote
|
1
|
+
require 'requires.rb'
|
35
2
|
|
36
3
|
module PryMoves
|
37
4
|
TRACE_IGNORE_FILES = Dir[File.join(File.dirname(__FILE__), '**', '*.rb')].map { |f| File.expand_path(f) }
|
@@ -40,22 +7,34 @@ module PryMoves
|
|
40
7
|
extend PryMoves::Restartable
|
41
8
|
|
42
9
|
attr_accessor :is_open, :trace, :stack_tips,
|
43
|
-
:stop_on_breakpoints, :launched_specs_examples,
|
10
|
+
:stop_on_breakpoints, :launched_specs_examples,
|
11
|
+
:debug_called_times, :step_in_everywhere
|
12
|
+
|
13
|
+
def init
|
14
|
+
reset
|
15
|
+
self.trace = true if ENV['TRACE_MOVES']
|
16
|
+
self.reload_ruby_scripts = {
|
17
|
+
monitor: %w(app spec),
|
18
|
+
except: %w(app/assets app/views)
|
19
|
+
}
|
20
|
+
self.reloader = CodeReloader.new unless ENV['PRY_MOVES_RELOADER'] == 'off'
|
21
|
+
self.reload_rake_tasks = true
|
22
|
+
end
|
44
23
|
|
45
24
|
def reset
|
46
25
|
self.launched_specs_examples = 0
|
47
26
|
self.stop_on_breakpoints = true
|
48
27
|
self.debug_called_times = 0
|
28
|
+
self.step_in_everywhere = false
|
49
29
|
end
|
50
30
|
|
51
|
-
def debug(message = nil, at: nil, options: nil)
|
31
|
+
def debug(message = nil, at: nil, from: nil, options: nil)
|
52
32
|
pry_moves_stack_end = true
|
53
33
|
PryMoves.re_execution
|
54
34
|
if PryMoves.stop_on_breakpoints
|
55
35
|
self.debug_called_times += 1
|
56
|
-
if at
|
57
|
-
|
58
|
-
end
|
36
|
+
return if at and self.debug_called_times != at
|
37
|
+
return if from and self.debug_called_times < from
|
59
38
|
if message
|
60
39
|
PryMoves.messages << (message.is_a?(String) ? message : message.ai)
|
61
40
|
end
|
@@ -64,7 +43,26 @@ module PryMoves
|
|
64
43
|
end
|
65
44
|
end
|
66
45
|
|
67
|
-
|
46
|
+
ROOT_DIR = File.expand_path(".")
|
47
|
+
|
48
|
+
def runtime_debug(instance)
|
49
|
+
do_debug = (
|
50
|
+
stop_on_breakpoints and
|
51
|
+
not open? and
|
52
|
+
caller[1].start_with?(ROOT_DIR) and
|
53
|
+
not [RubyVM::InstructionSequence].include?(instance)
|
54
|
+
)
|
55
|
+
if do_debug
|
56
|
+
hide_from_stack = true
|
57
|
+
err = yield
|
58
|
+
# HINT: when pry failed to start use: caller.reverse
|
59
|
+
PryMoves.debug_error err
|
60
|
+
true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def debug_error(message)
|
65
|
+
pry_moves_stack_end = true
|
68
66
|
debug message, options: {is_error: true}
|
69
67
|
end
|
70
68
|
|
@@ -123,7 +121,7 @@ module PryMoves
|
|
123
121
|
|
124
122
|
TRIGGERS = [:each_new_run, :restart]
|
125
123
|
def on(trigger, &block)
|
126
|
-
error "Invalid trigger, possible triggers: #{TRIGGERS}", trigger unless
|
124
|
+
error "Invalid trigger, possible triggers: #{TRIGGERS}", trigger unless TRIGGERS.include? trigger
|
127
125
|
triggers[trigger] << block
|
128
126
|
end
|
129
127
|
|
@@ -131,5 +129,6 @@ module PryMoves
|
|
131
129
|
attr_accessor :current_remote_server
|
132
130
|
end
|
133
131
|
|
134
|
-
PryMoves.
|
135
|
-
|
132
|
+
PryMoves.init
|
133
|
+
|
134
|
+
require 'sugar/debug_of_missing' # After PryMoves loaded
|
data/lib/requires.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'pry' unless defined? Pry
|
2
|
+
require 'colorize'
|
3
|
+
require 'diffy'
|
4
|
+
|
5
|
+
require 'pry-moves/version'
|
6
|
+
require 'pry-moves/pry_ext'
|
7
|
+
require 'pry-moves/commands'
|
8
|
+
require 'pry-moves/add_suffix'
|
9
|
+
require 'pry-moves/pry_wrapper'
|
10
|
+
require 'pry-moves/bindings_stack'
|
11
|
+
require 'pry-moves/code_reloader'
|
12
|
+
require 'pry-moves/formatter'
|
13
|
+
require 'pry-moves/backtrace'
|
14
|
+
require 'pry-moves/backtrace_builder'
|
15
|
+
require 'pry-moves/tools'
|
16
|
+
require 'pry-moves/watch'
|
17
|
+
require 'pry-moves/diff'
|
18
|
+
require 'pry-moves/painter'
|
19
|
+
require 'pry-moves/restartable'
|
20
|
+
require 'pry-moves/recursion_tracker'
|
21
|
+
require 'pry-moves/error_with_data'
|
22
|
+
|
23
|
+
require 'commands/traced_method'
|
24
|
+
require 'commands/trace_helpers'
|
25
|
+
require 'commands/trace_command'
|
26
|
+
require 'commands/debug'
|
27
|
+
require 'commands/finish'
|
28
|
+
require 'commands/goto'
|
29
|
+
require 'commands/iterate'
|
30
|
+
require 'commands/next'
|
31
|
+
require 'commands/next_breakpoint'
|
32
|
+
require 'commands/step'
|
33
|
+
|
34
|
+
require 'pry-stack_explorer/pry-stack_explorer'
|
35
|
+
require 'sugar/debug_sugar'
|
36
|
+
|
37
|
+
# Optionally load pry-remote monkey patches
|
38
|
+
require 'pry-moves/pry_remote_ext' if defined? PryRemote
|
@@ -0,0 +1,44 @@
|
|
1
|
+
Object.class_eval do
|
2
|
+
|
3
|
+
def method_missing(method, *args)
|
4
|
+
pry_moves_stack_end = true
|
5
|
+
pry_cancel_debug = true
|
6
|
+
|
7
|
+
debug_missing_method = (
|
8
|
+
not ([:begin, :to_s, :to_str, :to_int, :to_ary, :to_io, :to_hash].include? method) and
|
9
|
+
not caller[0].match PryMoves::Backtrace::filter
|
10
|
+
)
|
11
|
+
|
12
|
+
PryMoves.runtime_debug(self) do
|
13
|
+
message = self.nil? ?
|
14
|
+
"\e[31mCalling \e[1m#{method}\e[0m\e[31m on nil\e[0m" :
|
15
|
+
"\e[31mMethod \e[1m#{method}\e[0m\e[31m missing\e[0m"
|
16
|
+
subject = self.ai rescue "#{self.class} #{self}"
|
17
|
+
"#{subject}\n" +
|
18
|
+
"😱 #{message}"
|
19
|
+
end if debug_missing_method
|
20
|
+
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def should_be *classes
|
25
|
+
hide_from_stack = true
|
26
|
+
if self && !classes.some?{self.is_a?(_1)}
|
27
|
+
error("Expected class #{classes.join ", "}, got #{self.class.ai}", self)
|
28
|
+
end
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.const_missing(name)
|
33
|
+
super
|
34
|
+
rescue => e
|
35
|
+
unless PryMoves.open?
|
36
|
+
hide_from_stack = true
|
37
|
+
message = "😱 \e[31m#{e.to_s}\e[0m"
|
38
|
+
PryMoves.debug_error message
|
39
|
+
end
|
40
|
+
raise
|
41
|
+
end unless defined?(Rails)
|
42
|
+
|
43
|
+
end if ENV['PRY_MOVES_DEBUG_MISSING'] != 'off' and
|
44
|
+
not (defined?(Rails) and Rails.env.production?)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
def debug *args
|
2
|
+
return binding.pry_forced if args.first == :forced
|
2
3
|
pry_moves_stack_end = true
|
3
4
|
PryMoves.debug *args
|
4
5
|
end
|
@@ -10,7 +11,7 @@ def error(msg = "Error", debug_object = nil)
|
|
10
11
|
if PryMoves.stop_on_breakpoints
|
11
12
|
lines = [err.red]
|
12
13
|
lines.prepend debug_object.ai if debug_object
|
13
|
-
PryMoves.
|
14
|
+
PryMoves.debug_error lines.join("\n")
|
14
15
|
else
|
15
16
|
STDERR.puts debug_object.ai if debug_object
|
16
17
|
STDERR.puts err.ljust(80, ' ').red
|
@@ -26,14 +27,18 @@ def shit!(err = 'Oh, shit!', debug_object = nil)
|
|
26
27
|
raise err unless PryMoves.stop_on_breakpoints
|
27
28
|
lines = [message.red]
|
28
29
|
lines.prepend debug_object.ai if debug_object
|
29
|
-
PryMoves.
|
30
|
+
PryMoves.debug_error lines.join("\n")
|
30
31
|
nil
|
31
32
|
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
Object.class_eval do
|
35
|
+
|
36
|
+
def required!
|
37
|
+
pry_moves_stack_end = true
|
38
|
+
error("required parameter is missing") if self.nil?
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
37
42
|
end
|
38
43
|
|
39
44
|
RSpec.configure do |config|
|
@@ -41,7 +46,7 @@ RSpec.configure do |config|
|
|
41
46
|
config.before(:each) do
|
42
47
|
PryMoves.launched_specs_examples += 1
|
43
48
|
PryMoves.stop_on_breakpoints =
|
44
|
-
|
49
|
+
RSpec.configuration.world.example_count == 1
|
45
50
|
end
|
46
51
|
|
47
52
|
config.around(:each) do |example|
|
@@ -58,8 +63,8 @@ Rake::Task.class_eval do
|
|
58
63
|
|
59
64
|
def execute(args=nil)
|
60
65
|
args ||= EMPTY_TASK_ARGS
|
61
|
-
PryMoves.restartable(rake_args: args) do
|
62
|
-
reload_actions if PryMoves.reload_rake_tasks
|
66
|
+
PryMoves.restartable(rake_args: args) do |context|
|
67
|
+
reload_actions if PryMoves.reload_rake_tasks and context[:retry] > 0
|
63
68
|
execute_origin_for_pry_moves args
|
64
69
|
end
|
65
70
|
end
|
@@ -71,3 +76,17 @@ Rake::Task.class_eval do
|
|
71
76
|
end
|
72
77
|
|
73
78
|
end if defined? Rake and defined? Rake::Task
|
79
|
+
|
80
|
+
Diffy.module_eval do
|
81
|
+
|
82
|
+
class << self
|
83
|
+
def diff text1, text2
|
84
|
+
diff = Diffy::Diff.new(
|
85
|
+
text1 + "\n", text2 + "\n"
|
86
|
+
).to_s "color"
|
87
|
+
diff = 'Outputs are equal' if diff.strip.empty?
|
88
|
+
diff
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
data/playground/Gemfile.lock
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
pry-moves (1.0.
|
4
|
+
pry-moves (1.0.2)
|
5
5
|
binding_of_caller (~> 0.7)
|
6
6
|
colorize (~> 0.8)
|
7
|
-
diffy
|
7
|
+
diffy (~> 3.4.0)
|
8
8
|
pry (>= 0.10.4, < 0.13)
|
9
9
|
|
10
10
|
GEM
|
@@ -15,7 +15,7 @@ GEM
|
|
15
15
|
coderay (1.1.3)
|
16
16
|
colorize (0.8.1)
|
17
17
|
debug_inspector (1.1.0)
|
18
|
-
diffy (3.4.
|
18
|
+
diffy (3.4.2)
|
19
19
|
method_source (0.9.2)
|
20
20
|
pry (0.12.2)
|
21
21
|
coderay (~> 1.1.0)
|
data/playground/playground.rb
CHANGED
@@ -155,13 +155,18 @@ class Playground
|
|
155
155
|
def method_with_breakpoints
|
156
156
|
binding.pry # method_with_breakpoints host
|
157
157
|
dummy = 1 # some internal line
|
158
|
-
|
158
|
+
method_with_breakpoint # breakpoint
|
159
159
|
dummy = 1 # after breakpoint
|
160
160
|
dummy = 1 # after after breakpoint
|
161
|
-
|
161
|
+
method_with_breakpoint # breakpoint 2
|
162
162
|
dummy = 1 # after breakpoint 2
|
163
163
|
end
|
164
164
|
|
165
|
+
def method_with_breakpoint
|
166
|
+
pry_breakpoint = true
|
167
|
+
hide_from_stack = true
|
168
|
+
end
|
169
|
+
|
165
170
|
def skip_test
|
166
171
|
binding.pry # stop in skip_test
|
167
172
|
skipped_method.not_skipped_method # next step
|
data/pry-moves.gemspec
CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |gem|
|
|
22
22
|
gem.add_runtime_dependency 'pry', '>= 0.10.4', '< 0.13'
|
23
23
|
gem.add_runtime_dependency 'binding_of_caller', '~> 0.7'
|
24
24
|
gem.add_runtime_dependency 'colorize', '~> 0.8'
|
25
|
+
gem.add_runtime_dependency 'awesome_print', '>= 1.8.0'
|
25
26
|
gem.add_runtime_dependency 'diffy', '~> 3.4.0'
|
26
27
|
gem.add_development_dependency 'pry-remote', '~> 0.1.6'
|
27
28
|
end
|
data/spec/backtrace_spec.rb
CHANGED
@@ -17,6 +17,9 @@ describe 'backtrace' do
|
|
17
17
|
}],
|
18
18
|
['bt hidden', lambda{|b, output|
|
19
19
|
lines = output.split("\n").reverse
|
20
|
+
2.times do
|
21
|
+
lines.pop if lines.last.end_with? "main" # remove tech frames from bin/rspec
|
22
|
+
end
|
20
23
|
# show hidden frame
|
21
24
|
expect(lines[1]).to end_with 'level_b()'
|
22
25
|
expect(lines.count).to be 11
|
data/spec/commands_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -12,12 +12,13 @@ RSpec.configure do |config|
|
|
12
12
|
|
13
13
|
config.before(:example) do
|
14
14
|
PryMoves.unlock if PryMoves.semaphore.locked?
|
15
|
+
PryMoves.step_in_everywhere = false
|
15
16
|
end
|
16
17
|
|
17
18
|
config.after(:example) do |example|
|
18
19
|
unless example.exception
|
19
20
|
expect(PryDebugger.breakpoints.count).to be(0),
|
20
|
-
"not all breakpoints launched: #{PryDebugger.breakpoints.count}"
|
21
|
+
"not all breakpoints launched, left to launch: #{PryDebugger.breakpoints.count}. All following specs may fail."
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pry-moves
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- garmoshka-mo
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
@@ -58,6 +58,20 @@ dependencies:
|
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '0.8'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: awesome_print
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 1.8.0
|
68
|
+
type: :runtime
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 1.8.0
|
61
75
|
- !ruby/object:Gem::Dependency
|
62
76
|
name: diffy
|
63
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -89,7 +103,8 @@ dependencies:
|
|
89
103
|
description: Advanced debugger for ruby with natural `next` across blocks, debug of
|
90
104
|
dynamic calls, stepping into function by name, etc..
|
91
105
|
email: dan@coav.ru
|
92
|
-
executables:
|
106
|
+
executables:
|
107
|
+
- rspec
|
93
108
|
extensions: []
|
94
109
|
extra_rdoc_files: []
|
95
110
|
files:
|
@@ -99,6 +114,7 @@ files:
|
|
99
114
|
- LICENSE
|
100
115
|
- README.md
|
101
116
|
- Rakefile
|
117
|
+
- bin/rspec
|
102
118
|
- dynamic_debug_experiments.rb
|
103
119
|
- lib/commands/debug.rb
|
104
120
|
- lib/commands/finish.rb
|
@@ -110,13 +126,15 @@ files:
|
|
110
126
|
- lib/commands/trace_command.rb
|
111
127
|
- lib/commands/trace_helpers.rb
|
112
128
|
- lib/commands/traced_method.rb
|
113
|
-
- lib/debug_sugar.rb
|
114
129
|
- lib/pry-moves.rb
|
115
130
|
- lib/pry-moves/add_suffix.rb
|
116
131
|
- lib/pry-moves/backtrace.rb
|
132
|
+
- lib/pry-moves/backtrace_builder.rb
|
117
133
|
- lib/pry-moves/bindings_stack.rb
|
118
134
|
- lib/pry-moves/cli.rb
|
135
|
+
- lib/pry-moves/code_reloader.rb
|
119
136
|
- lib/pry-moves/commands.rb
|
137
|
+
- lib/pry-moves/diff.rb
|
120
138
|
- lib/pry-moves/error_with_data.rb
|
121
139
|
- lib/pry-moves/formatter.rb
|
122
140
|
- lib/pry-moves/painter.rb
|
@@ -125,6 +143,7 @@ files:
|
|
125
143
|
- lib/pry-moves/pry_wrapper.rb
|
126
144
|
- lib/pry-moves/recursion_tracker.rb
|
127
145
|
- lib/pry-moves/restartable.rb
|
146
|
+
- lib/pry-moves/tools.rb
|
128
147
|
- lib/pry-moves/version.rb
|
129
148
|
- lib/pry-moves/watch.rb
|
130
149
|
- lib/pry-stack_explorer/VERSION
|
@@ -133,6 +152,9 @@ files:
|
|
133
152
|
- lib/pry-stack_explorer/pry-stack_explorer.rb
|
134
153
|
- lib/pry-stack_explorer/stack_commands.rb
|
135
154
|
- lib/pry-stack_explorer/when_started_hook.rb
|
155
|
+
- lib/requires.rb
|
156
|
+
- lib/sugar/debug_of_missing.rb
|
157
|
+
- lib/sugar/debug_sugar.rb
|
136
158
|
- playground/Gemfile
|
137
159
|
- playground/Gemfile.lock
|
138
160
|
- playground/README.md
|
@@ -157,7 +179,7 @@ homepage: https://github.com/garmoshka-mo/pry-moves
|
|
157
179
|
licenses:
|
158
180
|
- MIT
|
159
181
|
metadata: {}
|
160
|
-
post_install_message:
|
182
|
+
post_install_message:
|
161
183
|
rdoc_options: []
|
162
184
|
require_paths:
|
163
185
|
- lib
|
@@ -175,8 +197,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
197
|
- !ruby/object:Gem::Version
|
176
198
|
version: '0'
|
177
199
|
requirements: []
|
178
|
-
rubygems_version: 3.1.
|
179
|
-
signing_key:
|
200
|
+
rubygems_version: 3.1.6
|
201
|
+
signing_key:
|
180
202
|
specification_version: 4
|
181
203
|
summary: Debugger for ruby
|
182
204
|
test_files:
|