byebug-skipper 0.3.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5d165edc95bf8040d55fa09985c47fb3c85b001b3c739855ec30c20c2a9e6eb6
4
+ data.tar.gz: 1183e8fbae3dd8785b357ed93365eaaaf17a9de521cb52b08e1366a7abee7e94
5
+ SHA512:
6
+ metadata.gz: 254077cf9ff026ebf763d2b4f5a4fa061e18241f239aaa228b5a641407e5ac86bc91500547725acce8e794a78a21b7d7e67b5de83fb8cb907bfa46f5d6d5a362
7
+ data.tar.gz: b5ee026c1455bbab9dea30054548c39f13b1c32258a5a2754a5576d2454d4e9761298af5bd9b5b221ac16c8ecadf7f54d6719bf8eb92824350ea4df07309bfe3
@@ -0,0 +1,46 @@
1
+ module Byebug::Skipper
2
+ extend self
3
+
4
+ DEFAULT_SKIP_MATCHERS = [
5
+ %r{/ruby/[^/]+(/bundler)?/gems/}, # gems installed globally or via Bundler
6
+ %r{/ruby-[^/]+/lib/ruby/[^/]+/}, # Ruby built-in files
7
+ ].freeze
8
+
9
+ def skip_matchers
10
+ @skip_matchers ||= DEFAULT_SKIP_MATCHERS
11
+ end
12
+
13
+ def skip_matchers=(matchers)
14
+ @skip_matchers = matchers
15
+ end
16
+
17
+ def skip?(location)
18
+ skip_matchers.any? { |sm| sm === location }
19
+ end
20
+ end
21
+
22
+ require 'delegate'
23
+ require 'byebug'
24
+ require 'byebug/command'
25
+ require 'byebug/helpers/frame'
26
+ require_relative 'skipper/ups_command'
27
+ require_relative 'skipper/downs_command'
28
+ require_relative 'skipper/finishs_command'
29
+ require_relative 'skipper/steps_command'
30
+
31
+ # Command classes need to be in the Byebug module or else they don't get picked
32
+ # up. Cool, bruh.
33
+ [
34
+ Byebug::Skipper::UpsCommand,
35
+ Byebug::Skipper::DownsCommand,
36
+ Byebug::Skipper::FinishsCommand,
37
+ Byebug::Skipper::StepsCommand,
38
+ ].each do |command_class|
39
+ Byebug.const_set(
40
+ command_class.name.split('::').last,
41
+ command_class,
42
+ )
43
+ end
44
+
45
+ require_relative 'skipper/pry' if defined?(PryByebug)
46
+
@@ -0,0 +1,30 @@
1
+ module Byebug::Skipper
2
+ # this class is partially copy/pasted from Byebug::DownCommand
3
+ class DownsCommand < Byebug::Command
4
+ include Byebug::Helpers::FrameHelper
5
+
6
+ self.allow_in_post_mortem = true
7
+
8
+ def self.regexp
9
+ /^ \s* downs \s* $/x
10
+ end
11
+
12
+ def self.short_description
13
+ "Same as `down` but skips garbage frames, e.g. from gems"
14
+ end
15
+
16
+ def self.description
17
+ short_description
18
+ end
19
+
20
+ def execute
21
+ loop do
22
+ break if out_of_bounds?(context.frame.pos - 1)
23
+ jump_frames(-1)
24
+ break if not Byebug::Skipper.skip?(context.location)
25
+ end
26
+
27
+ Byebug::ListCommand.new(processor).execute if Byebug::Setting[:autolist]
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,39 @@
1
+ module Byebug::Skipper
2
+ # this class is partially copy/pasted from Byebug::FinishsCommand
3
+ class FinishsCommand < Byebug::Command
4
+ include Byebug::Helpers::FrameHelper
5
+
6
+ self.allow_in_post_mortem = false
7
+
8
+ def self.regexp
9
+ /^ \s* fin(?:ish)?s \s* $/x
10
+ end
11
+
12
+ def self.short_description
13
+ "Same as `finish` but skips garbage frames, e.g. from gems"
14
+ end
15
+
16
+ def self.description
17
+ <<~TXT
18
+ finishs | fins
19
+
20
+ #{short_description}
21
+ TXT
22
+ end
23
+
24
+ def execute
25
+ frame = context.frame
26
+
27
+ loop do
28
+ frame = Byebug::Frame.new(context, frame.pos + 1)
29
+ next if frame.c_frame?
30
+ break if out_of_bounds?(frame.pos)
31
+ break if not Byebug::Skipper.skip?("#{frame.file}:#{frame.line}")
32
+ end
33
+
34
+ context.step_out(frame.pos, false)
35
+ context.frame = 0
36
+ processor.proceed!
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,52 @@
1
+ require_relative '../skipper'
2
+ require 'pry-byebug'
3
+
4
+ module Byebug::Skipper::Pry
5
+ COMMAND_NAMES = %w[ups downs steps finishs].freeze
6
+ COMMANDS_THAT_CONTINUE = %w[steps finishs].freeze
7
+ end
8
+
9
+ # All the Pry command classes are implemented the same
10
+ Byebug::Skipper::Pry::COMMAND_NAMES.each do |command_name|
11
+ command_class = Class.new(Pry::ClassCommand) do
12
+ include ::PryByebug::Helpers::Navigation
13
+
14
+ match command_name
15
+ group "Byebug Skipper"
16
+ description "Same as Byebug's `#{command_name.chomp('s')}` command but skips garbage frames (e.g. from gems)"
17
+
18
+ def process
19
+ PryByebug.check_file_context(target)
20
+ # This comes from pry-byebug, and we need to monkey patch it (see below)
21
+ # to get these custom command names to work properly.
22
+ breakout_navigation(command_name)
23
+ end
24
+ end
25
+
26
+ Byebug::Skipper::Pry.const_set("#{command_name.capitalize}Command", command_class)
27
+ Pry::Commands.add_command(command_class)
28
+ end
29
+
30
+ # This is a monkey patch for Byebug::PryProcessor in order to add extra Byebug
31
+ # commands to Pry. This needs to be overriden because there is a hard-coded
32
+ # whitelist of `action` values inside, and I need to add custom actions.
33
+ module Byebug::Skipper::Pry::ProcessorHacks
34
+ def perform(action, options = {})
35
+ # If it's not one of our commands, short circuit and use the typical
36
+ # behaviour.
37
+ return super unless Byebug::Skipper::Pry::COMMAND_NAMES.include?(action.to_s)
38
+
39
+ # Call the Byebug command objects directly. This seems kind of fragile to
40
+ # me, but I don't see any better options.
41
+ Byebug::Skipper.const_get("#{command_name.capitalize}Command")
42
+ .new(self, command_name)
43
+ .execute
44
+
45
+ unless Byebug::Skipper::Pry::COMMANDS_THAT_CONTINUE.include?(command_name)
46
+ # This shows the REPL again, preventing execution from continuing.
47
+ resume_pry
48
+ end
49
+ end
50
+ end
51
+
52
+ Byebug::PryProcessor.prepend(Byebug::Skipper::Pry::ProcessorHacks)
@@ -0,0 +1,52 @@
1
+ module Byebug::Skipper
2
+ # this class is partially copy/pasted from Byebug::StepsCommand
3
+ class StepsCommand < Byebug::Command
4
+ def self.regexp
5
+ /^ \s* s(?:tep)?s \s* $/x
6
+ end
7
+
8
+ def self.short_description
9
+ "Same as `step` but skips garbage frames, e.g. from gems"
10
+ end
11
+
12
+ def self.description
13
+ short_description
14
+ end
15
+
16
+ def execute
17
+ HackyProcessor.hack_into(context)
18
+ end
19
+
20
+ private
21
+
22
+ # We need to hijack the #at_line method of the processor, to prevent it
23
+ # from running the REPL when we want it to skip that frame. Sneakily
24
+ # replaces the processor with this wrapped/delegated version, and then
25
+ # unwraps/undelegates when no longer necessary.
26
+ class HackyProcessor < SimpleDelegator
27
+ def self.hack_into(context)
28
+ hack = new(context.send(:processor))
29
+ context.instance_variable_set(:@processor, hack)
30
+ hack.skip_this_frame!
31
+ end
32
+
33
+ def unhack!
34
+ context.instance_variable_set(:@processor, __getobj__)
35
+ end
36
+
37
+ def skip_this_frame!
38
+ context.step_into(1, context.frame.pos)
39
+ proceed!
40
+ end
41
+
42
+ def at_line
43
+ if Byebug::Skipper.skip?(context.location)
44
+ skip_this_frame! # don't stop, keep running
45
+ else
46
+ unhack!
47
+ super # will stop and show REPL
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,30 @@
1
+ module Byebug::Skipper
2
+ # this class is partially copy/pasted from Byebug::UpCommand
3
+ class UpsCommand < Byebug::Command
4
+ include Byebug::Helpers::FrameHelper
5
+
6
+ self.allow_in_post_mortem = true
7
+
8
+ def self.regexp
9
+ /^ \s* ups \s* $/x
10
+ end
11
+
12
+ def self.short_description
13
+ "Same as `up` but skips garbage frames, e.g. from gems"
14
+ end
15
+
16
+ def self.description
17
+ short_description
18
+ end
19
+
20
+ def execute
21
+ loop do
22
+ break if out_of_bounds?(context.frame.pos + 1)
23
+ jump_frames(1)
24
+ break if not Byebug::Skipper.skip?(context.location)
25
+ end
26
+
27
+ Byebug::ListCommand.new(processor).execute if Byebug::Setting[:autolist]
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,5 @@
1
+ module Byebug
2
+ module Skipper
3
+ VERSION = '0.3.3'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: byebug-skipper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.3
5
+ platform: ruby
6
+ authors:
7
+ - Tom Dalling
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-06-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: byebug
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: gem-release
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Additional commands for Byebug that skip over garbage frames
70
+ email: tom@tomdalling.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/byebug/skipper.rb
76
+ - lib/byebug/skipper/downs_command.rb
77
+ - lib/byebug/skipper/finishs_command.rb
78
+ - lib/byebug/skipper/pry.rb
79
+ - lib/byebug/skipper/steps_command.rb
80
+ - lib/byebug/skipper/ups_command.rb
81
+ - lib/byebug/skipper/version.rb
82
+ homepage: https://github.com/tomdalling/byebug-skipper
83
+ licenses:
84
+ - MIT
85
+ metadata: {}
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubygems_version: 3.1.6
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Additional commands for Byebug that skip over garbage frames
105
+ test_files: []