Skip to content

Commit

Permalink
Continue including Rails::ConsoleMethods to IRB's internal
Browse files Browse the repository at this point in the history
Due to some users/libs relying on Rails::ConsoleMethod to extend Rails
console, we need to keep including it to IRB's internal.

But to prevent also adding `app` and `helper` methods to the console,
which are already registered to IRB through its API, we need to remove
them from the Rails::ConsoleMethods. Additionally, we should raise
deprecation warning when users try to use Rails::ConsoleMethods in this
way.

This commit:
- Removes all methods from Rails::ConsoleMethods that are already
  registered to IRB. So it's now essentially empty.
- Raises a deprecation warning when modules are included to Rails::ConsoleMethods
  or methods are added to it.
- Adds a test to ensure that the deprecation warning is raised and the
  methods are available in the console.
  • Loading branch information
st0012 committed May 7, 2024
1 parent 6c73ee0 commit 484c026
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 65 deletions.
27 changes: 20 additions & 7 deletions railties/lib/rails/commands/console/irb_console.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class ControllerHelper < RailsHelperBase

# This method assumes an +ApplicationController+ exists, and that it extends ActionController::Base.
def execute
helper
ApplicationController.helpers
end
end

Expand All @@ -23,23 +23,31 @@ class ControllerInstance < RailsHelperBase

# This method assumes an +ApplicationController+ exists, and that it extends ActionController::Base.
def execute
controller
@controller ||= ApplicationController.new
end
end

class NewSession < RailsHelperBase
description "Create a new session. If a block is given, the new session will be yielded to the block before being returned."

def execute
new_session
def execute(*)
app = Rails.application
session = ActionDispatch::Integration::Session.new(app)

# This makes app.url_for and app.foo_path available in the console
session.extend(app.routes.url_helpers)
session.extend(app.routes.mounted_helpers)

session
end
end

class AppInstance < RailsHelperBase
class AppInstance < NewSession
description "Reference the global 'app' instance, created on demand. To recreate the instance, pass a non-false value as the parameter."

def execute(create = false)
app(create)
@app_integration_instance = nil if create
@app_integration_instance ||= super
end
end

Expand All @@ -50,7 +58,8 @@ class Reloader < IRB::Command::Base
description "Reloads the environment."

def execute(*)
reload!
puts "Reloading..."
Rails.application.reloader.reload!
end
end

Expand Down Expand Up @@ -101,6 +110,10 @@ def start
end
end

# Because some users/libs use Rails::ConsoleMethods to extend Rails console,
# we still include it for backward compatibility.
IRB::ExtendCommandBundle.include ConsoleMethods

# Respect user's choice of prompt mode.
IRB.conf[:PROMPT_MODE] = :RAILS_PROMPT if IRB.conf[:PROMPT_MODE] == :DEFAULT
IRB::Irb.new.run(IRB.conf)
Expand Down
35 changes: 0 additions & 35 deletions railties/lib/rails/console/app.rb

This file was deleted.

19 changes: 0 additions & 19 deletions railties/lib/rails/console/helpers.rb

This file was deleted.

23 changes: 23 additions & 0 deletions railties/lib/rails/console/methods.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

module Rails
module ConsoleMethods
def self.include(_mod, ...)
raise_deprecation_warning
super
end

def self.method_added(_method_name)
raise_deprecation_warning
super
end

def self.raise_deprecation_warning
ActiveSupport::Deprecation.new.warn(<<~MSG, caller_locations(1..1))
Extending Rails console through `Rails::ConsoleMethods` is deprecated and will be removed in Rails 7.3.
Please directly use IRB's extension API to add new commands or helpers to the console.
For more details, please visit: https://github.com/ruby/irb/blob/master/EXTEND_IRB.md
MSG
end
end
end
3 changes: 1 addition & 2 deletions railties/lib/rails/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,7 @@ def initialize
# Load console and invoke the registered hooks.
# Check Rails::Railtie.console for more info.
def load_console(app = self)
require "rails/console/app"
require "rails/console/helpers"
require "rails/console/methods"
run_console_blocks(app)
self
end
Expand Down
36 changes: 36 additions & 0 deletions railties/test/application/console_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,42 @@ def test_reload_command_fires_preparation_and_cleanup_callbacks
write_prompt "c", "=> 3"
end

def test_rails_console_methods_patch_backward_compatibility_with_module_inclusion
add_to_config <<-RUBY
module MyConsole
def foo
"this is foo"
end
end
console do
::Rails::ConsoleMethods.include(MyConsole)
end
RUBY

spawn_console("-e development", wait_for_prompt: false)

assert_output "Extending Rails console through `Rails::ConsoleMethods` is deprecated", @primary, 30
write_prompt "foo", "=> \"this is foo\""
end

def test_rails_console_methods_patch_backward_compatibility_with_module_reopening
add_to_config <<-RUBY
console do
::Rails::ConsoleMethods.module_eval do
def foo
"this is foo"
end
end
end
RUBY

spawn_console("-e development", wait_for_prompt: false)

assert_output "Extending Rails console through `Rails::ConsoleMethods` is deprecated", @primary, 30
write_prompt "foo", "=> \"this is foo\""
end

def test_reload_command_reload_constants
app_file "app/models/user.rb", <<-MODEL
class User
Expand Down
3 changes: 1 addition & 2 deletions railties/test/commands/console_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,7 @@ def config
end

def load_console
require "rails/console/app"
require "rails/console/helpers"
require "rails/console/methods"
end
end
mocked_app.new(console)
Expand Down

0 comments on commit 484c026

Please sign in to comment.