1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
# frozen_string_literal: true
require "pry/byebug/breakpoints"
require "pry-byebug/helpers/breakpoints"
require "pry-byebug/helpers/location"
require "pry-byebug/helpers/multiline"
module PryByebug
#
# Add, show and remove breakpoints
#
class BreakCommand < Pry::ClassCommand
include Helpers::Breakpoints
include Helpers::Location
include Helpers::Multiline
match "break"
group "Byebug"
description "Set or edit a breakpoint."
banner <<-BANNER
Usage: break <METHOD | FILE:LINE | LINE> [if CONDITION]
break --condition N [CONDITION]
break [--show | --delete | --enable | --disable] N
break [--delete-all | --disable-all]
break
Set a breakpoint. Accepts a line number in the current file, a file and
line number, or a method, and an optional condition.
Pass appropriate flags to manipulate existing breakpoints.
Examples:
break SomeClass#run Break at the start of `SomeClass#run`.
break Foo#bar if baz? Break at `Foo#bar` only if `baz?`.
break app/models/user.rb:15 Break at line 15 in user.rb.
break 14 Break at line 14 in the current file.
break --condition 4 x > 2 Add/change condition on breakpoint #4.
break --condition 3 Remove the condition on breakpoint #3.
break --delete 5 Delete breakpoint #5.
break --disable-all Disable all breakpoints.
break --show 2 Show details about breakpoint #2.
break List all breakpoints.
BANNER
def options(opt)
defaults = { argument: true, as: Integer }
opt.on :c, :condition, "Change condition of a breakpoint.", defaults
opt.on :s, :show, "Show breakpoint details and source.", defaults
opt.on :D, :delete, "Delete a breakpoint.", defaults
opt.on :d, :disable, "Disable a breakpoint.", defaults
opt.on :e, :enable, "Enable a disabled breakpoint.", defaults
opt.on :'disable-all', "Disable all breakpoints."
opt.on :'delete-all', "Delete all breakpoints."
end
def process
return if check_multiline_context
PryByebug.check_file_context(target)
option, = opts.to_hash.find { |key, _value| opts.present?(key) }
return send(option_to_method(option)) if option
return new_breakpoint unless args.empty?
print_all
end
private
%w[delete disable enable disable_all delete_all].each do |command|
define_method(:"process_#{command}") do
breakpoints.send(*[command, opts[command]].compact)
print_all
end
end
def process_show
print_full_breakpoint(breakpoints.find_by_id(opts[:show]))
end
def process_condition
expr = args.empty? ? nil : args.join(" ")
breakpoints.change(opts[:condition], expr)
end
def new_breakpoint
place = args.shift
condition = args.join(" ") if args.shift == "if"
bp = add_breakpoint(place, condition)
print_full_breakpoint(bp)
end
def option_to_method(option)
"process_#{option.to_s.tr('-', '_')}"
end
def print_all
print_breakpoints_header
breakpoints.each { |b| print_short_breakpoint(b) }
end
def add_breakpoint(place, condition)
case place
when /^(\d+)$/
errmsg = "Line number declaration valid only in a file context."
PryByebug.check_file_context(target, errmsg)
lineno = Regexp.last_match[1].to_i
breakpoints.add_file(current_file, lineno, condition)
when /^(.+):(\d+)$/
file = Regexp.last_match[1]
lineno = Regexp.last_match[2].to_i
breakpoints.add_file(file, lineno, condition)
when /^(.*)[.#].+$/ # Method or class name
if Regexp.last_match[1].strip.empty?
errmsg = "Method name declaration valid only in a file context."
PryByebug.check_file_context(target, errmsg)
place = target.eval("self.class.to_s") + place
end
breakpoints.add_method(place, condition)
else
raise(ArgumentError, "Cannot identify arguments as breakpoint")
end
end
end
end
Pry::Commands.add_command(PryByebug::BreakCommand)
|