From dd7fbd8b0163d803122129f49f51bc05462b055f Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Mon, 9 Oct 2023 13:05:51 +0100 Subject: [PATCH] Upgrade the irb command to use irb:debug integration This means that user will get an IRB session that has access to the debug commands too by activating IRB's debug integration automatically: https://github.com/ruby/irb#debugging-with-irb --- debug.gemspec | 2 +- lib/debug/irb_integration.rb | 27 +++++++++++++++++++++++++++ lib/debug/thread_client.rb | 9 ++------- test/console/irb_test.rb | 28 ++++++++++++++++++++++++++++ test/support/console_test_case.rb | 1 + 5 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 lib/debug/irb_integration.rb create mode 100644 test/console/irb_test.rb diff --git a/debug.gemspec b/debug.gemspec index a07018a77..4dc71a826 100644 --- a/debug.gemspec +++ b/debug.gemspec @@ -27,6 +27,6 @@ Gem::Specification.new do |spec| spec.require_paths = ["lib"] spec.extensions = ['ext/debug/extconf.rb'] - spec.add_dependency "irb", ">= 1.5.0" # for binding.irb(show_code: false) + spec.add_dependency "irb", ">= 1.8.3" # for irb:debug integration spec.add_dependency "reline", ">= 0.3.8" end diff --git a/lib/debug/irb_integration.rb b/lib/debug/irb_integration.rb new file mode 100644 index 000000000..a2ea34b65 --- /dev/null +++ b/lib/debug/irb_integration.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'irb' + +module DEBUGGER__ + module IrbPatch + def evaluate(line, line_no) + SESSION.send(:restart_all_threads) + super + # This is to communicate with the test framework so it can feed the next input + puts "INTERNAL_INFO: {}" if ENV['RUBY_DEBUG_TEST_UI'] == 'terminal' + ensure + SESSION.send(:stop_all_threads) + end + end + + class ThreadClient + def activate_irb_integration + IRB.setup(location, argv: []) + workspace = IRB::WorkSpace.new(current_frame&.binding || TOPLEVEL_BINDING) + irb = IRB::Irb.new(workspace) + IRB.conf[:MAIN_CONTEXT] = irb.context + IRB::Debug.setup(irb) + IRB::Context.prepend(IrbPatch) + end + end +end diff --git a/lib/debug/thread_client.rb b/lib/debug/thread_client.rb index 3ec53fb81..6f9da4af1 100644 --- a/lib/debug/thread_client.rb +++ b/lib/debug/thread_client.rb @@ -1048,13 +1048,8 @@ def wait_next_action_ when :call result = frame_eval(eval_src) when :irb - require 'irb' # prelude's binding.irb doesn't have show_code option - begin - result = frame_eval('binding.irb(show_code: false)', binding_location: true) - ensure - # workaround: https://github.com/ruby/debug/issues/308 - Reline.prompt_proc = nil if defined? Reline - end + require_relative "irb_integration" + activate_irb_integration when :display, :try_display failed_results = [] eval_src.each_with_index{|src, i| diff --git a/test/console/irb_test.rb b/test/console/irb_test.rb new file mode 100644 index 000000000..8cdf5801a --- /dev/null +++ b/test/console/irb_test.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require_relative '../support/console_test_case' + +module DEBUGGER__ + class IrbTest < ConsoleTestCase + def program + <<~RUBY + 1| a = 1 + 2| b = 2 + RUBY + end + + def test_irb_command_switches_console_to_irb + debug_code(program, remote: false) do + type 'irb' + type '123' + assert_line_text 'irb:rdbg(main):002> 123' + type 'irb_info' + assert_line_text('IRB version:') + type 'next' + type 'info' + assert_line_text([/a = 1/, /b = nil/]) + type 'q!' + end + end + end +end diff --git a/test/support/console_test_case.rb b/test/support/console_test_case.rb index 49e0bb87f..efdc1bafe 100644 --- a/test/support/console_test_case.rb +++ b/test/support/console_test_case.rb @@ -217,6 +217,7 @@ def prepare_test_environment(program, test_steps, &block) ENV['RUBY_DEBUG_TEST_UI'] = 'terminal' ENV['RUBY_DEBUG_NO_RELINE'] = 'true' ENV['RUBY_DEBUG_HISTORY_FILE'] = '' + ENV['TERM'] = 'dumb' write_temp_file(strip_line_num(program)) @scenario = []