From e38ff49d3e6cc182f3c29ce345ebb9e2c06e72f5 Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Tue, 6 Dec 2022 12:32:00 +0000 Subject: [PATCH] Disable Rails console IRB's autocompletion in production Reasons behind this change: 1. Autocompletion increases data transmission significantly. This could cause noticeable slowdown when connecting to remote servers, which is usually the case in production. 2. The autocompletion feature still has many issues, as listed in https://github.com/ruby/irb/issues/445. They may be just annoying when happened locally, but in production they could cause real issues (e.g. typos caused by slow backspacing). Due to these reasons, I think it's safer to disable this feature in production. About the implementation: Because `IRB.start` doesn't take configuration arguments and rebuilds the `IRB.conf` object, the only way we can turn off autocompletion is through the `IRB_USE_AUTOCOMPLETE` env var. The env var was added in https://github.com/ruby/irb/pull/469 and will be available for IRB 1.6+ and Ruby 3.2+. The name wasn't used before so it won't cause issues with older IRB versions. Note: Users can still turn it back on with `IRB_USE_AUTOCOMPLETE=true` --- .../rails/commands/console/console_command.rb | 4 ++ railties/test/commands/console_test.rb | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/railties/lib/rails/commands/console/console_command.rb b/railties/lib/rails/commands/console/console_command.rb index 7a9eaefea1f84..7fa33965372b9 100644 --- a/railties/lib/rails/commands/console/console_command.rb +++ b/railties/lib/rails/commands/console/console_command.rb @@ -38,6 +38,10 @@ def initialize(app, options = {}) if @console == IRB IRB::WorkSpace.prepend(BacktraceCleaner) + + if Rails.env == "production" + ENV["IRB_USE_AUTOCOMPLETE"] ||= "false" + end end end diff --git a/railties/test/commands/console_test.rb b/railties/test/commands/console_test.rb index ee4335e31df95..7d733ad84d1e1 100644 --- a/railties/test/commands/console_test.rb +++ b/railties/test/commands/console_test.rb @@ -58,6 +58,45 @@ def test_console_defaults_to_IRB assert_equal IRB, Rails::Console.new(app).console end + def test_console_disables_IRB_auto_completion_in_production + original_use_autocomplete = ENV["IRB_USE_AUTOCOMPLETE"] + ENV["IRB_USE_AUTOCOMPLETE"] = nil + + with_rack_env "production" do + app = build_app(nil) + assert_equal IRB, Rails::Console.new(app).console + assert_equal "false", ENV["IRB_USE_AUTOCOMPLETE"] + end + ensure + ENV["IRB_USE_AUTOCOMPLETE"] = original_use_autocomplete + end + + def test_console_accepts_override_on_IRB_auto_completion_flag + original_use_autocomplete = ENV["IRB_USE_AUTOCOMPLETE"] + ENV["IRB_USE_AUTOCOMPLETE"] = "true" + + with_rack_env "production" do + app = build_app(nil) + assert_equal IRB, Rails::Console.new(app).console + assert_equal "true", ENV["IRB_USE_AUTOCOMPLETE"] + end + ensure + ENV["IRB_USE_AUTOCOMPLETE"] = original_use_autocomplete + end + + def test_console_doesnt_disable_IRB_auto_completion_in_non_production + original_use_autocomplete = ENV["IRB_USE_AUTOCOMPLETE"] + ENV["IRB_USE_AUTOCOMPLETE"] = nil + + with_rails_env nil do + app = build_app(nil) + assert_equal IRB, Rails::Console.new(app).console + assert_nil ENV["IRB_USE_AUTOCOMPLETE"] + end + ensure + ENV["IRB_USE_AUTOCOMPLETE"] = original_use_autocomplete + end + def test_default_environment_with_no_rails_env with_rails_env nil do start