From 2e6c807ccec2a0601d2bdccdaf4d5f94bc00ef91 Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Tue, 2 Jan 2024 13:20:39 +0000 Subject: [PATCH] Make irb_console toggleable with config update 1. When the user sets `irb_console` to `true` through the command, the `irb:rdbg` will now be enabled the same way as typing the `irb` command. 2. When the user sets `irb_console` to `false` through the command, the `irb:rdbg` will now be disabled. 3. Users can now enable `irb:rdbg` by setting `irb_console` to `true` in their `.rdbgrc` file. --- lib/debug/config.rb | 20 ++++++++++++++++++++ lib/debug/session.rb | 22 +++++++++++++++------- lib/debug/thread_client.rb | 3 --- test/console/irb_test.rb | 35 ++++++++++++++++++++++++++--------- 4 files changed, 61 insertions(+), 19 deletions(-) diff --git a/lib/debug/config.rb b/lib/debug/config.rb index ab4c9c559..eb132ce4a 100644 --- a/lib/debug/config.rb +++ b/lib/debug/config.rb @@ -158,6 +158,26 @@ def update conf SESSION.set_no_sigint_hook old, new end end + + if_updated old_conf, conf, :irb_console do |old, new| + if defined?(SESSION) && SESSION.active? + # irb_console is switched from true to false + if old + Reline.completion_proc = nil + Reline.output_modifier_proc = nil + Reline.autocompletion = false + Reline.dig_perfect_match_proc = nil + SESSION.reset_ui UI_LocalConsole.new + # irb_console is switched from false to true + else + if CONFIG[:open] + SESSION.instance_variable_get(:@ui).puts "\nIRB is not supported on the remote console." + else + SESSION.activate_irb_integration + end + end + end + end end private def if_updated old_conf, new_conf, key diff --git a/lib/debug/session.rb b/lib/debug/session.rb index f76f9dc6d..769102dce 100644 --- a/lib/debug/session.rb +++ b/lib/debug/session.rb @@ -202,11 +202,6 @@ def activate ui = nil, on_fork: false end @tp_thread_end.enable - if CONFIG[:irb_console] && !CONFIG[:open] - require_relative "irb_integration" - thc.activate_irb_integration - end - # session start q << true session_server_main @@ -214,6 +209,12 @@ def activate ui = nil, on_fork: false first_q << :ok q.pop + + # For activating irb:rdbg with startup config like `RUBY_DEBUG_IRB_CONSOLE=1` + # Because in that case the `Config#if_updated` callback would not be triggered + if CONFIG[:irb_console] && !CONFIG[:open] + activate_irb_integration + end end def deactivate @@ -942,10 +943,11 @@ def register_default_command register_command 'irb' do |arg| if @ui.remote? @ui.puts "\nIRB is not supported on the remote console." - :retry else - request_eval :irb, nil + config_set :irb_console, true end + + :retry end ### Trace @@ -1876,6 +1878,12 @@ def check_unsafe end end + def activate_irb_integration + require_relative "irb_integration" + thc = get_thread_client(@session_server) + thc.activate_irb_integration + end + def enter_postmortem_session exc return unless exc.instance_variable_defined? :@__debugger_postmortem_frames diff --git a/lib/debug/thread_client.rb b/lib/debug/thread_client.rb index 753898560..e10d4d97f 100644 --- a/lib/debug/thread_client.rb +++ b/lib/debug/thread_client.rb @@ -1056,9 +1056,6 @@ def wait_next_action_ end when :call result = frame_eval(eval_src) - when :irb - 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 index 478a37036..515a240c7 100644 --- a/test/console/irb_test.rb +++ b/test/console/irb_test.rb @@ -4,15 +4,6 @@ module DEBUGGER__ class IrbTest < ConsoleTestCase - def setup - @original_pager = ENV["PAGER"] - ENV["PAGER"] = "cat" - end - - def teardown - ENV["PAGER"] = @original_pager - end - def program <<~RUBY 1| a = 1 @@ -26,6 +17,12 @@ def test_irb_command_is_disabled_in_remote_mode assert_line_text 'IRB is not supported on the remote console.' type 'q!' end + + debug_code(program, remote: :remote_only) do + type 'config set irb_console true' + assert_line_text 'IRB is not supported on the remote console.' + type 'q!' + end end def test_irb_command_switches_console_to_irb @@ -38,6 +35,11 @@ def test_irb_command_switches_console_to_irb type 'next' type 'info' assert_line_text([/a = 1/, /b = nil/]) + + # disable irb console + type 'config set irb_console false' + type '456' + assert_raw_line_text '(rdbg) 456' type 'q!' end end @@ -53,10 +55,25 @@ def test_irb_console_config_activates_irb type 'next' type 'info' assert_line_text([/a = 1/, /b = nil/]) + + # disable irb console + type 'config set irb_console false' + type '456' + assert_raw_line_text '(rdbg) 456' type 'q!' end ensure ENV["RUBY_DEBUG_IRB_CONSOLE"] = nil end + + private + + # assert_line_text ignores the prompt line, so we can't use it to assert the prompt transition + # assert_raw_line_text is a workaround for that + def assert_raw_line_text(expectation) + @scenario.push(Proc.new do |test_info| + assert_include(test_info.last_backlog.join, expectation) + end) + end end end