Skip to content

Commit 6b67657

Browse files
authored
Merge pull request rails#51705 from Shopify/update-irb
Build Rails console on top of IRB's latest official APIs
2 parents 549144b + 4c1f7d8 commit 6b67657

File tree

6 files changed

+215
-162
lines changed

6 files changed

+215
-162
lines changed

Gemfile.lock

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ PATH
112112
railties (7.2.0.alpha)
113113
actionpack (= 7.2.0.alpha)
114114
activesupport (= 7.2.0.alpha)
115-
irb
115+
irb (~> 1.13)
116116
rackup (>= 1.0.0)
117117
rake (>= 12.2)
118118
thor (~> 1.0, >= 1.2.2)
@@ -288,10 +288,10 @@ GEM
288288
actionpack (>= 6.0.0)
289289
activesupport (>= 6.0.0)
290290
railties (>= 6.0.0)
291-
io-console (0.7.1)
292-
irb (1.11.0)
293-
rdoc
294-
reline (>= 0.3.8)
291+
io-console (0.7.2)
292+
irb (1.13.0)
293+
rdoc (>= 4.0.0)
294+
reline (>= 0.4.2)
295295
jbuilder (2.11.5)
296296
actionview (>= 5.0.0)
297297
activesupport (>= 5.0.0)
@@ -415,7 +415,7 @@ GEM
415415
rb-inotify (0.10.1)
416416
ffi (~> 1.0)
417417
rbtree (0.4.6)
418-
rdoc (6.6.2)
418+
rdoc (6.6.3.1)
419419
psych (>= 4.0.0)
420420
redcarpet (3.2.3)
421421
redis (5.0.8)
@@ -425,7 +425,7 @@ GEM
425425
redis-namespace (1.11.0)
426426
redis (>= 4)
427427
regexp_parser (2.8.3)
428-
reline (0.4.1)
428+
reline (0.5.4)
429429
io-console (~> 0.5)
430430
representable (3.2.0)
431431
declarative (< 0.1.0)

railties/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
* Implement Rails console commands and helpers with IRB v1.13's extension APIs
2+
3+
Rails console users will now see `helper`, `controller`, `new_session`, and `app` under
4+
IRB help message's `Helper methods` category. And `reload!` command will be displayed under
5+
the new `Rails console` commands category.
6+
7+
Prior to this change, Rails console's commands and helper methods are added through IRB's
8+
private components and don't show up in its help message, which led to poor discoverability.
9+
10+
*Stan Lo*
11+
112
* Remove deprecated `Rails::Generators::Testing::Behaviour`.
213

314
*Rafael Mendonça França*

railties/lib/rails/commands/console/console_command.rb

Lines changed: 4 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4,66 +4,6 @@
44

55
module Rails
66
class Console
7-
module BacktraceCleaner
8-
def filter_backtrace(bt)
9-
if result = super
10-
Rails.backtrace_cleaner.filter([result]).first
11-
end
12-
end
13-
end
14-
15-
class IRBConsole
16-
def initialize(app)
17-
@app = app
18-
19-
require "irb"
20-
require "irb/completion"
21-
22-
IRB::WorkSpace.prepend(BacktraceCleaner)
23-
IRB::ExtendCommandBundle.include(Rails::ConsoleMethods)
24-
end
25-
26-
def name
27-
"IRB"
28-
end
29-
30-
def start
31-
IRB.setup(nil)
32-
33-
if !Rails.env.local? && !ENV.key?("IRB_USE_AUTOCOMPLETE")
34-
IRB.conf[:USE_AUTOCOMPLETE] = false
35-
end
36-
37-
env = colorized_env
38-
app_name = @app.class.module_parent_name.underscore.dasherize
39-
prompt_prefix = "#{app_name}(#{env})"
40-
41-
IRB.conf[:PROMPT][:RAILS_PROMPT] = {
42-
PROMPT_I: "#{prompt_prefix}> ",
43-
PROMPT_S: "#{prompt_prefix}%l ",
44-
PROMPT_C: "#{prompt_prefix}* ",
45-
RETURN: "=> %s\n"
46-
}
47-
48-
# Respect user's choice of prompt mode.
49-
IRB.conf[:PROMPT_MODE] = :RAILS_PROMPT if IRB.conf[:PROMPT_MODE] == :DEFAULT
50-
IRB::Irb.new.run(IRB.conf)
51-
end
52-
53-
def colorized_env
54-
case Rails.env
55-
when "development"
56-
IRB::Color.colorize("dev", [:BLUE])
57-
when "test"
58-
IRB::Color.colorize("test", [:BLUE])
59-
when "production"
60-
IRB::Color.colorize("prod", [:RED])
61-
else
62-
Rails.env
63-
end
64-
end
65-
end
66-
677
def self.start(*args)
688
new(*args).start
699
end
@@ -83,7 +23,10 @@ def initialize(app, options = {})
8323

8424
app.load_console
8525

86-
@console = app.config.console || IRBConsole.new(app)
26+
@console = app.config.console || begin
27+
require "rails/commands/console/irb_console"
28+
IRBConsole.new(app)
29+
end
8730
end
8831

8932
def sandbox?
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# frozen_string_literal: true
2+
3+
require "irb/helper_method"
4+
require "irb/command"
5+
6+
module Rails
7+
class Console
8+
class RailsHelperBase < IRB::HelperMethod::Base
9+
include ConsoleMethods
10+
end
11+
12+
class ControllerHelper < RailsHelperBase
13+
description "Gets the helper methods available to the controller."
14+
15+
# This method assumes an +ApplicationController+ exists, and that it extends ActionController::Base.
16+
def execute
17+
helper
18+
end
19+
end
20+
21+
class ControllerInstance < RailsHelperBase
22+
description "Gets a new instance of a controller object."
23+
24+
# This method assumes an +ApplicationController+ exists, and that it extends ActionController::Base.
25+
def execute
26+
controller
27+
end
28+
end
29+
30+
class NewSession < RailsHelperBase
31+
description "Create a new session. If a block is given, the new session will be yielded to the block before being returned."
32+
33+
def execute
34+
new_session
35+
end
36+
end
37+
38+
class AppInstance < RailsHelperBase
39+
description "Reference the global 'app' instance, created on demand. To recreate the instance, pass a non-false value as the parameter."
40+
41+
def execute(create = false)
42+
app(create)
43+
end
44+
end
45+
46+
class Reloader < IRB::Command::Base
47+
include ConsoleMethods
48+
49+
category "Rails console"
50+
description "Reloads the environment."
51+
52+
def execute(*)
53+
reload!
54+
end
55+
end
56+
57+
IRB::HelperMethod.register(:helper, ControllerHelper)
58+
IRB::HelperMethod.register(:controller, ControllerInstance)
59+
IRB::HelperMethod.register(:new_session, NewSession)
60+
IRB::HelperMethod.register(:app, AppInstance)
61+
IRB::Command.register(:reload!, Reloader)
62+
63+
class IRBConsole
64+
def initialize(app)
65+
@app = app
66+
67+
require "irb"
68+
require "irb/completion"
69+
end
70+
71+
def name
72+
"IRB"
73+
end
74+
75+
def start
76+
IRB.setup(nil)
77+
78+
if !Rails.env.local? && !ENV.key?("IRB_USE_AUTOCOMPLETE")
79+
IRB.conf[:USE_AUTOCOMPLETE] = false
80+
end
81+
82+
env = colorized_env
83+
app_name = @app.class.module_parent_name.underscore.dasherize
84+
prompt_prefix = "#{app_name}(#{env})"
85+
86+
IRB.conf[:PROMPT][:RAILS_PROMPT] = {
87+
PROMPT_I: "#{prompt_prefix}> ",
88+
PROMPT_S: "#{prompt_prefix}%l ",
89+
PROMPT_C: "#{prompt_prefix}* ",
90+
RETURN: "=> %s\n"
91+
}
92+
93+
if current_filter = IRB.conf[:BACKTRACE_FILTER]
94+
IRB.conf[:BACKTRACE_FILTER] = -> (backtrace) do
95+
backtrace = current_filter.call(backtrace)
96+
Rails.backtrace_cleaner.filter(backtrace)
97+
end
98+
else
99+
IRB.conf[:BACKTRACE_FILTER] = -> (backtrace) do
100+
Rails.backtrace_cleaner.filter(backtrace)
101+
end
102+
end
103+
104+
# Respect user's choice of prompt mode.
105+
IRB.conf[:PROMPT_MODE] = :RAILS_PROMPT if IRB.conf[:PROMPT_MODE] == :DEFAULT
106+
IRB::Irb.new.run(IRB.conf)
107+
end
108+
109+
def colorized_env
110+
case Rails.env
111+
when "development"
112+
IRB::Color.colorize("dev", [:BLUE])
113+
when "test"
114+
IRB::Color.colorize("test", [:BLUE])
115+
when "production"
116+
IRB::Color.colorize("prod", [:RED])
117+
else
118+
Rails.env
119+
end
120+
end
121+
end
122+
end
123+
end

railties/railties.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Gem::Specification.new do |s|
4444
s.add_dependency "rake", ">= 12.2"
4545
s.add_dependency "thor", "~> 1.0", ">= 1.2.2"
4646
s.add_dependency "zeitwerk", "~> 2.6"
47-
s.add_dependency "irb"
47+
s.add_dependency "irb", "~> 1.13"
4848

4949
s.add_development_dependency "actionview", version
5050
end

0 commit comments

Comments
 (0)