gitlab-pry-byebug 3.9.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.
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pry-byebug/helpers/navigation"
4
+
5
+ module PryByebug
6
+ #
7
+ # Run a number of Ruby statements and then stop again
8
+ #
9
+ class StepCommand < Pry::ClassCommand
10
+ include Helpers::Navigation
11
+
12
+ match "step"
13
+ group "Byebug"
14
+ description "Step execution into the next line or method."
15
+
16
+ banner <<-BANNER
17
+ Usage: step [TIMES]
18
+
19
+ Step execution forward. By default, moves a single step.
20
+
21
+ Examples:
22
+ step #=> Move a single step forward.
23
+ step 5 #=> Execute the next 5 steps.
24
+ BANNER
25
+
26
+ def process
27
+ PryByebug.check_file_context(target)
28
+
29
+ breakout_navigation :step, times: args.first
30
+ end
31
+ end
32
+ end
33
+
34
+ Pry::Commands.add_command(PryByebug::StepCommand)
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pry-byebug/helpers/navigation"
4
+
5
+ module PryByebug
6
+ #
7
+ # Travel up the frame stack
8
+ #
9
+ class UpCommand < Pry::ClassCommand
10
+ include Helpers::Navigation
11
+
12
+ match "up"
13
+ group "Byebug"
14
+
15
+ description "Move current frame up."
16
+
17
+ banner <<-BANNER
18
+ Usage: up [TIMES]
19
+
20
+ Move current frame up. By default, moves by 1 frame.
21
+
22
+ Examples:
23
+ up #=> Move up 1 frame.
24
+ up 5 #=> Move up 5 frames.
25
+ BANNER
26
+
27
+ def process
28
+ PryByebug.check_file_context(target)
29
+
30
+ breakout_navigation :up, times: args.first
31
+ end
32
+ end
33
+ end
34
+
35
+ Pry::Commands.add_command(PryByebug::UpCommand)
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ original_handler = Pry.config.control_d_handler
4
+
5
+ Pry.config.control_d_handler = proc do |pry_instance|
6
+ Byebug.stop if Byebug.stoppable?
7
+
8
+ original_handler.call(pry_instance)
9
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "byebug"
4
+
5
+ module PryByebug
6
+ module Helpers
7
+ #
8
+ # Common helpers for breakpoint related commands
9
+ #
10
+ module Breakpoints
11
+ #
12
+ # Byebug's array of breakpoints.
13
+ #
14
+ def breakpoints
15
+ Pry::Byebug::Breakpoints
16
+ end
17
+
18
+ #
19
+ # Prints a message with bold font.
20
+ #
21
+ def bold_puts(msg)
22
+ output.puts(bold(msg))
23
+ end
24
+
25
+ #
26
+ # Print out full information about a breakpoint.
27
+ #
28
+ # Includes surrounding code at that point.
29
+ #
30
+ def print_full_breakpoint(breakpoint)
31
+ header = "Breakpoint #{breakpoint.id}:"
32
+ status = breakpoint.enabled? ? "Enabled" : "Disabled"
33
+ code = breakpoint.source_code.with_line_numbers.to_s
34
+ condition = if breakpoint.expr
35
+ "#{bold('Condition:')} #{breakpoint.expr}\n"
36
+ else
37
+ ""
38
+ end
39
+
40
+ output.puts <<-BREAKPOINT.gsub(/ {8}/, "")
41
+
42
+ #{bold(header)} #{breakpoint} (#{status}) #{condition}
43
+
44
+ #{code}
45
+
46
+ BREAKPOINT
47
+ end
48
+
49
+ #
50
+ # Print out concise information about a breakpoint.
51
+ #
52
+ def print_short_breakpoint(breakpoint)
53
+ id = format("%*d", max_width, breakpoint.id)
54
+ status = breakpoint.enabled? ? "Yes" : "No "
55
+ expr = breakpoint.expr ? " #{breakpoint.expr} " : ""
56
+
57
+ output.puts(" #{id} #{status} #{breakpoint}#{expr}")
58
+ end
59
+
60
+ #
61
+ # Prints a header for the breakpoint list.
62
+ #
63
+ def print_breakpoints_header
64
+ header = "#{' ' * (max_width - 1)}# Enabled At "
65
+
66
+ output.puts <<-BREAKPOINTS.gsub(/ {8}/, "")
67
+
68
+ #{bold(header)}
69
+ #{bold('-' * header.size)}
70
+
71
+ BREAKPOINTS
72
+ end
73
+
74
+ #
75
+ # Max width of breakpoints id column
76
+ #
77
+ def max_width
78
+ breakpoints.last ? breakpoints.last.id.to_s.length : 1
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PryByebug
4
+ module Helpers
5
+ #
6
+ # Compatibility helper to handle source location
7
+ #
8
+ module Location
9
+ module_function
10
+
11
+ #
12
+ # Current file in the target binding. Used as the default breakpoint
13
+ # location.
14
+ #
15
+ def current_file(source = target)
16
+ # Guard clause for Ruby >= 2.6 providing now Binding#source_location ...
17
+ return source.source_location[0] if source.respond_to?(:source_location)
18
+
19
+ # ... to avoid warning: 'eval may not return location in binding'
20
+ source.eval("__FILE__")
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PryByebug
4
+ module Helpers
5
+ #
6
+ # Helpers to help handling multiline inputs
7
+ #
8
+ module Multiline
9
+ #
10
+ # Returns true if we are in a multiline context and, as a side effect,
11
+ # updates the partial evaluation string with the current input.
12
+ #
13
+ # Returns false otherwise
14
+ #
15
+ def check_multiline_context
16
+ return false if eval_string.empty?
17
+
18
+ eval_string.replace("#{eval_string}#{match} #{arg_string}\n")
19
+ true
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PryByebug
4
+ module Helpers
5
+ #
6
+ # Helpers to aid breaking out of the REPL loop
7
+ #
8
+ module Navigation
9
+ #
10
+ # Breaks out of the REPL loop and signals tracer
11
+ #
12
+ def breakout_navigation(action, options = {})
13
+ pry_instance.binding_stack.clear
14
+
15
+ throw :breakout_nav, action: action, options: options, pry: pry_instance
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "byebug/processors/pry_processor"
4
+ require "byebug/processors/pry_remote_processor"
5
+
6
+ class << Pry
7
+ alias start_without_pry_byebug start
8
+
9
+ def start_with_pry_byebug(target = TOPLEVEL_BINDING, options = {})
10
+ if target.is_a?(Binding) && PryByebug.file_context?(target) && !ENV["DISABLE_PRY"]
11
+ run_remote? ? Byebug::PryRemoteProcessor.start : Byebug::PryProcessor.start
12
+ else
13
+ # No need for the tracer unless we have a file context to step through
14
+ start_without_pry_byebug(target, options)
15
+ end
16
+ end
17
+
18
+ def run_remote?
19
+ PryByebug.current_remote_server
20
+ end
21
+
22
+ alias start start_with_pry_byebug
23
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pry-remote"
4
+
5
+ module PryRemote
6
+ #
7
+ # Overrides PryRemote::Server
8
+ #
9
+ class Server
10
+ #
11
+ # Override the call to Pry.start to save off current Server, and not
12
+ # teardown the server right after Pry.start finishes.
13
+ #
14
+ def run
15
+ raise("Already running a pry-remote session!") if
16
+ PryByebug.current_remote_server
17
+
18
+ PryByebug.current_remote_server = self
19
+
20
+ setup
21
+ Pry.start @object, input: client.input_proxy, output: client.output
22
+ end
23
+
24
+ #
25
+ # Override to reset our saved global current server session.
26
+ #
27
+ alias teardown_without_pry_byebug teardown
28
+ def teardown_with_pry_byebug
29
+ return if @torn
30
+
31
+ teardown_without_pry_byebug
32
+ PryByebug.current_remote_server = nil
33
+ @torn = true
34
+ end
35
+ alias teardown teardown_with_pry_byebug
36
+ end
37
+ end
38
+
39
+ # Ensure cleanup when a program finishes without another break. For example,
40
+ # 'next' on the last line of a program won't hit Byebug::PryProcessor#run,
41
+ # which normally handles cleanup.
42
+ at_exit do
43
+ PryByebug.current_remote_server&.teardown
44
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Main container module for Pry-Byebug functionality
5
+ #
6
+ module PryByebug
7
+ VERSION = "3.9.0"
8
+ end
@@ -0,0 +1,167 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ module Byebug
5
+ #
6
+ # Wrapper for Byebug.breakpoints that respects our Processor and has better
7
+ # failure behavior. Acts as an Enumerable.
8
+ #
9
+ module Breakpoints
10
+ extend Enumerable
11
+ extend self
12
+
13
+ #
14
+ # Breakpoint in a file:line location
15
+ #
16
+ class FileBreakpoint < SimpleDelegator
17
+ def source_code
18
+ Pry::Code.from_file(source).around(pos, 3).with_marker(pos)
19
+ end
20
+
21
+ def to_s
22
+ "#{source} @ #{pos}"
23
+ end
24
+ end
25
+
26
+ #
27
+ # Breakpoint in a Class#method location
28
+ #
29
+ class MethodBreakpoint < SimpleDelegator
30
+ def initialize(byebug_bp, method)
31
+ __setobj__ byebug_bp
32
+ @method = method
33
+ end
34
+
35
+ def source_code
36
+ Pry::Code.from_method(Pry::Method.from_str(@method))
37
+ end
38
+
39
+ def to_s
40
+ @method
41
+ end
42
+ end
43
+
44
+ def breakpoints
45
+ @breakpoints ||= []
46
+ end
47
+
48
+ #
49
+ # Adds a method breakpoint.
50
+ #
51
+ def add_method(method, expression = nil)
52
+ validate_expression expression
53
+ owner, name = method.split(/[\.#]/)
54
+ byebug_bp = ::Byebug::Breakpoint.add(owner, name.to_sym, expression)
55
+ bp = MethodBreakpoint.new byebug_bp, method
56
+ breakpoints << bp
57
+ bp
58
+ end
59
+
60
+ #
61
+ # Adds a file breakpoint.
62
+ #
63
+ def add_file(file, line, expression = nil)
64
+ real_file = (file != Pry.eval_path)
65
+ raise(ArgumentError, "Invalid file!") if real_file && !File.exist?(file)
66
+
67
+ validate_expression expression
68
+
69
+ path = (real_file ? File.expand_path(file) : file)
70
+ bp = FileBreakpoint.new ::Byebug::Breakpoint.add(path, line, expression)
71
+ breakpoints << bp
72
+ bp
73
+ end
74
+
75
+ #
76
+ # Changes the conditional expression for a breakpoint.
77
+ #
78
+ def change(id, expression = nil)
79
+ validate_expression expression
80
+
81
+ breakpoint = find_by_id(id)
82
+ breakpoint.expr = expression
83
+ breakpoint
84
+ end
85
+
86
+ #
87
+ # Deletes an existing breakpoint with the given ID.
88
+ #
89
+ def delete(id)
90
+ deleted =
91
+ ::Byebug::Breakpoint.remove(id) &&
92
+ breakpoints.delete(find_by_id(id))
93
+
94
+ raise(ArgumentError, "No breakpoint ##{id}") unless deleted
95
+ end
96
+
97
+ #
98
+ # Deletes all breakpoints.
99
+ #
100
+ def delete_all
101
+ @breakpoints = []
102
+ ::Byebug.breakpoints.clear
103
+ end
104
+
105
+ #
106
+ # Enables a disabled breakpoint with the given ID.
107
+ #
108
+ def enable(id)
109
+ change_status id, true
110
+ end
111
+
112
+ #
113
+ # Disables a breakpoint with the given ID.
114
+ #
115
+ def disable(id)
116
+ change_status id, false
117
+ end
118
+
119
+ #
120
+ # Disables all breakpoints.
121
+ #
122
+ def disable_all
123
+ each do |breakpoint|
124
+ breakpoint.enabled = false
125
+ end
126
+ end
127
+
128
+ def to_a
129
+ breakpoints
130
+ end
131
+
132
+ def size
133
+ to_a.size
134
+ end
135
+
136
+ def each(&block)
137
+ to_a.each(&block)
138
+ end
139
+
140
+ def last
141
+ to_a.last
142
+ end
143
+
144
+ def find_by_id(id)
145
+ breakpoint = find { |b| b.id == id }
146
+ raise(ArgumentError, "No breakpoint ##{id}!") unless breakpoint
147
+
148
+ breakpoint
149
+ end
150
+
151
+ private
152
+
153
+ def change_status(id, enabled = true)
154
+ breakpoint = find_by_id(id)
155
+ breakpoint.enabled = enabled
156
+ breakpoint
157
+ end
158
+
159
+ def validate_expression(exp)
160
+ valid = exp && (exp.empty? || !Pry::Code.complete_expression?(exp))
161
+ return unless valid
162
+
163
+ raise("Invalid breakpoint conditional: #{expression}")
164
+ end
165
+ end
166
+ end
167
+ end