Skip to content

Commit b53ebc6

Browse files
hahmedst0012
andauthored
Add the ability to fetch and load multiple irb files. (#859)
This allows hierarchy when loading rc files for example both files below are loaded; project/.irbrc ~/.irbrc Co-authored-by: Stan Lo <stan001212@gmail.com>
1 parent 7efadc2 commit b53ebc6

6 files changed

Lines changed: 139 additions & 30 deletions

File tree

lib/irb/command/irb_info.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ def execute
1313
str += "IRB version: #{IRB.version}\n"
1414
str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
1515
str += "Completion: #{IRB.CurrentContext.io.respond_to?(:completion_info) ? IRB.CurrentContext.io.completion_info : 'off'}\n"
16-
str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file)
16+
rc_files = IRB.rc_files.select { |rc| File.exist?(rc) }
17+
str += ".irbrc paths: #{rc_files.join(", ")}\n" if rc_files.any?
1718
str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
1819
str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?
1920
str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty?

lib/irb/history.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def load_history
1616
if history_file = IRB.conf[:HISTORY_FILE]
1717
history_file = File.expand_path(history_file)
1818
end
19-
history_file = IRB.rc_file("_history") unless history_file
19+
history_file = IRB.rc_files("_history").first unless history_file
2020
if File.exist?(history_file)
2121
File.open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f|
2222
f.each { |l|
@@ -41,7 +41,7 @@ def save_history
4141
if history_file = IRB.conf[:HISTORY_FILE]
4242
history_file = File.expand_path(history_file)
4343
end
44-
history_file = IRB.rc_file("_history") unless history_file
44+
history_file = IRB.rc_files("_history").first unless history_file
4545

4646
# Change the permission of a file that already exists[BUG #7694]
4747
begin

lib/irb/init.rb

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -395,33 +395,41 @@ def IRB.parse_opts(argv: ::ARGV)
395395
# Run the config file
396396
def IRB.run_config
397397
if @CONF[:RC]
398-
begin
399-
file = rc_file
398+
rc_files.each do |rc|
400399
# Because rc_file always returns `HOME/.irbrc` even if no rc file is present, we can't warn users about missing rc files.
401400
# Otherwise, it'd be very noisy.
402-
load file if File.exist?(file)
401+
load rc if File.exist?(rc)
403402
rescue StandardError, ScriptError => e
404-
warn "Error loading RC file '#{file}':\n#{e.full_message(highlight: false)}"
403+
warn "Error loading RC file '#{rc}':\n#{e.full_message(highlight: false)}"
405404
end
406405
end
407406
end
408407

409408
IRBRC_EXT = "rc"
410409
def IRB.rc_file(ext = IRBRC_EXT)
410+
warn "rc_file is deprecated, please use rc_files instead."
411+
rc_files(ext).first
412+
end
413+
414+
def IRB.rc_files(ext = IRBRC_EXT)
411415
if !@CONF[:RC_NAME_GENERATOR]
416+
@CONF[:RC_NAME_GENERATOR] ||= []
417+
existing_rc_file_generators = []
418+
412419
rc_file_generators do |rcgen|
413-
@CONF[:RC_NAME_GENERATOR] ||= rcgen
414-
if File.exist?(rcgen.call(IRBRC_EXT))
415-
@CONF[:RC_NAME_GENERATOR] = rcgen
416-
break
417-
end
420+
@CONF[:RC_NAME_GENERATOR] << rcgen
421+
existing_rc_file_generators << rcgen if File.exist?(rcgen.call(ext))
422+
end
423+
424+
if existing_rc_file_generators.any?
425+
@CONF[:RC_NAME_GENERATOR] = existing_rc_file_generators
418426
end
419427
end
420-
case rc_file = @CONF[:RC_NAME_GENERATOR].call(ext)
421-
when String
428+
429+
@CONF[:RC_NAME_GENERATOR].map do |rc|
430+
rc_file = rc.call(ext)
431+
fail IllegalRCNameGenerator unless rc_file.is_a?(String)
422432
rc_file
423-
else
424-
fail IllegalRCNameGenerator
425433
end
426434
end
427435

test/irb/test_command.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def teardown
7575
def test_irb_info_multiline
7676
FileUtils.touch("#{@tmpdir}/.inputrc")
7777
FileUtils.touch("#{@tmpdir}/.irbrc")
78+
FileUtils.touch("#{@tmpdir}/_irbrc")
7879

7980
out, err = execute_lines(
8081
"irb_info",
@@ -86,7 +87,7 @@ def test_irb_info_multiline
8687
IRB\sversion:\sirb\s.+\n
8788
InputMethod:\sAbstract\sInputMethod\n
8889
Completion: .+\n
89-
\.irbrc\spath:\s.+\n
90+
\.irbrc\spaths:.*\.irbrc.*_irbrc\n
9091
RUBY_PLATFORM:\s.+\n
9192
East\sAsian\sAmbiguous\sWidth:\s\d\n
9293
#{@is_win ? 'Code\spage:\s\d+\n' : ''}
@@ -110,7 +111,7 @@ def test_irb_info_singleline
110111
IRB\sversion:\sirb\s.+\n
111112
InputMethod:\sAbstract\sInputMethod\n
112113
Completion: .+\n
113-
\.irbrc\spath:\s.+\n
114+
\.irbrc\spaths:\s.+\n
114115
RUBY_PLATFORM:\s.+\n
115116
East\sAsian\sAmbiguous\sWidth:\s\d\n
116117
#{@is_win ? 'Code\spage:\s\d+\n' : ''}
@@ -196,7 +197,7 @@ def test_irb_info_lang
196197
IRB\sversion:\sirb .+\n
197198
InputMethod:\sAbstract\sInputMethod\n
198199
Completion: .+\n
199-
\.irbrc\spath: .+\n
200+
\.irbrc\spaths: .+\n
200201
RUBY_PLATFORM: .+\n
201202
LANG\senv:\sja_JP\.UTF-8\n
202203
LC_ALL\senv:\sen_US\.UTF-8\n

test/irb/test_history.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ def test_history_concurrent_use_not_present
136136
io.class::HISTORY << 'line1'
137137
io.class::HISTORY << 'line2'
138138

139-
history_file = IRB.rc_file("_history")
139+
history_file = IRB.rc_files("_history").first
140140
assert_not_send [File, :file?, history_file]
141141
File.write(history_file, "line0\n")
142142
io.save_history
@@ -217,9 +217,10 @@ def assert_history(expected_history, initial_irb_history, input, input_method =
217217
backup_xdg_config_home = ENV.delete("XDG_CONFIG_HOME")
218218
IRB.conf[:LC_MESSAGES] = locale
219219
actual_history = nil
220+
history_file = IRB.rc_files("_history").first
220221
Dir.mktmpdir("test_irb_history_") do |tmpdir|
221222
ENV["HOME"] = tmpdir
222-
File.open(IRB.rc_file("_history"), "w") do |f|
223+
File.open(history_file, "w") do |f|
223224
f.write(initial_irb_history)
224225
end
225226

@@ -229,15 +230,15 @@ def assert_history(expected_history, initial_irb_history, input, input_method =
229230
if block_given?
230231
previous_history = []
231232
io.class::HISTORY.each { |line| previous_history << line }
232-
yield IRB.rc_file("_history")
233+
yield history_file
233234
io.class::HISTORY.clear
234235
previous_history.each { |line| io.class::HISTORY << line }
235236
end
236237
input.split.each { |line| io.class::HISTORY << line }
237238
io.save_history
238239

239240
io.load_history
240-
File.open(IRB.rc_file("_history"), "r") do |f|
241+
File.open(history_file, "r") do |f|
241242
actual_history = f.read
242243
end
243244
end

test/irb/test_init.rb

Lines changed: 105 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def setup
1111
@backup_env = %w[HOME XDG_CONFIG_HOME IRBRC].each_with_object({}) do |env, hash|
1212
hash[env] = ENV.delete(env)
1313
end
14-
ENV["HOME"] = @tmpdir = Dir.mktmpdir("test_irb_init_#{$$}")
14+
ENV["HOME"] = @tmpdir = File.realpath(Dir.mktmpdir("test_irb_init_#{$$}"))
1515
end
1616

1717
def teardown
@@ -35,35 +35,133 @@ def test_setup_with_minimum_argv_does_not_change_dollar0
3535
end
3636

3737
def test_rc_file
38+
verbose, $VERBOSE = $VERBOSE, nil
3839
tmpdir = @tmpdir
3940
Dir.chdir(tmpdir) do
4041
ENV["XDG_CONFIG_HOME"] = "#{tmpdir}/xdg"
4142
IRB.conf[:RC_NAME_GENERATOR] = nil
42-
assert_equal(tmpdir+"/.irb#{IRB::IRBRC_EXT}", IRB.rc_file)
43+
assert_equal(tmpdir+"/.irbrc", IRB.rc_file)
4344
assert_equal(tmpdir+"/.irb_history", IRB.rc_file("_history"))
4445
assert_file.not_exist?(tmpdir+"/xdg")
4546
IRB.conf[:RC_NAME_GENERATOR] = nil
46-
FileUtils.touch(tmpdir+"/.irb#{IRB::IRBRC_EXT}")
47-
assert_equal(tmpdir+"/.irb#{IRB::IRBRC_EXT}", IRB.rc_file)
47+
FileUtils.touch(tmpdir+"/.irbrc")
48+
assert_equal(tmpdir+"/.irbrc", IRB.rc_file)
4849
assert_equal(tmpdir+"/.irb_history", IRB.rc_file("_history"))
4950
assert_file.not_exist?(tmpdir+"/xdg")
5051
end
52+
ensure
53+
$VERBOSE = verbose
5154
end
5255

5356
def test_rc_file_in_subdir
57+
verbose, $VERBOSE = $VERBOSE, nil
5458
tmpdir = @tmpdir
5559
Dir.chdir(tmpdir) do
5660
FileUtils.mkdir_p("#{tmpdir}/mydir")
5761
Dir.chdir("#{tmpdir}/mydir") do
5862
IRB.conf[:RC_NAME_GENERATOR] = nil
59-
assert_equal(tmpdir+"/.irb#{IRB::IRBRC_EXT}", IRB.rc_file)
63+
assert_equal(tmpdir+"/.irbrc", IRB.rc_file)
6064
assert_equal(tmpdir+"/.irb_history", IRB.rc_file("_history"))
6165
IRB.conf[:RC_NAME_GENERATOR] = nil
62-
FileUtils.touch(tmpdir+"/.irb#{IRB::IRBRC_EXT}")
63-
assert_equal(tmpdir+"/.irb#{IRB::IRBRC_EXT}", IRB.rc_file)
66+
FileUtils.touch(tmpdir+"/.irbrc")
67+
assert_equal(tmpdir+"/.irbrc", IRB.rc_file)
6468
assert_equal(tmpdir+"/.irb_history", IRB.rc_file("_history"))
6569
end
6670
end
71+
ensure
72+
$VERBOSE = verbose
73+
end
74+
75+
def test_rc_files
76+
tmpdir = @tmpdir
77+
Dir.chdir(tmpdir) do
78+
ENV["XDG_CONFIG_HOME"] = "#{tmpdir}/xdg"
79+
IRB.conf[:RC_NAME_GENERATOR] = nil
80+
assert_includes IRB.rc_files, tmpdir+"/.irbrc"
81+
assert_includes IRB.rc_files("_history"), tmpdir+"/.irb_history"
82+
assert_file.not_exist?(tmpdir+"/xdg")
83+
IRB.conf[:RC_NAME_GENERATOR] = nil
84+
FileUtils.touch(tmpdir+"/.irbrc")
85+
assert_includes IRB.rc_files, tmpdir+"/.irbrc"
86+
assert_includes IRB.rc_files("_history"), tmpdir+"/.irb_history"
87+
assert_file.not_exist?(tmpdir+"/xdg")
88+
end
89+
end
90+
91+
def test_rc_files_in_subdir
92+
tmpdir = @tmpdir
93+
Dir.chdir(tmpdir) do
94+
FileUtils.mkdir_p("#{tmpdir}/mydir")
95+
Dir.chdir("#{tmpdir}/mydir") do
96+
IRB.conf[:RC_NAME_GENERATOR] = nil
97+
assert_includes IRB.rc_files, tmpdir+"/.irbrc"
98+
assert_includes IRB.rc_files("_history"), tmpdir+"/.irb_history"
99+
IRB.conf[:RC_NAME_GENERATOR] = nil
100+
FileUtils.touch(tmpdir+"/.irbrc")
101+
assert_includes IRB.rc_files, tmpdir+"/.irbrc"
102+
assert_includes IRB.rc_files("_history"), tmpdir+"/.irb_history"
103+
end
104+
end
105+
end
106+
107+
def test_rc_files_has_file_from_xdg_env
108+
tmpdir = @tmpdir
109+
ENV["XDG_CONFIG_HOME"] = "#{tmpdir}/xdg"
110+
xdg_config = ENV["XDG_CONFIG_HOME"]+"/irb/irbrc"
111+
112+
FileUtils.mkdir_p(xdg_config)
113+
114+
Dir.chdir(tmpdir) do
115+
IRB.conf[:RC_NAME_GENERATOR] = nil
116+
assert_includes IRB.rc_files, xdg_config
117+
end
118+
ensure
119+
ENV["XDG_CONFIG_HOME"] = nil
120+
end
121+
122+
def test_rc_files_has_file_from_irbrc_env
123+
tmpdir = @tmpdir
124+
ENV["IRBRC"] = "#{tmpdir}/irb"
125+
126+
FileUtils.mkdir_p(ENV["IRBRC"])
127+
128+
Dir.chdir(tmpdir) do
129+
IRB.conf[:RC_NAME_GENERATOR] = nil
130+
assert_includes IRB.rc_files, ENV["IRBRC"]
131+
end
132+
ensure
133+
ENV["IRBRC"] = nil
134+
end
135+
136+
def test_rc_files_has_file_from_home_env
137+
tmpdir = @tmpdir
138+
ENV["HOME"] = "#{tmpdir}/home"
139+
140+
FileUtils.mkdir_p(ENV["HOME"])
141+
142+
Dir.chdir(tmpdir) do
143+
IRB.conf[:RC_NAME_GENERATOR] = nil
144+
assert_includes IRB.rc_files, ENV["HOME"]+"/.irbrc"
145+
assert_includes IRB.rc_files, ENV["HOME"]+"/.config/irb/irbrc"
146+
end
147+
ensure
148+
ENV["HOME"] = nil
149+
end
150+
151+
def test_rc_files_contains_non_env_files
152+
tmpdir = @tmpdir
153+
FileUtils.mkdir_p("#{tmpdir}/.irbrc")
154+
FileUtils.mkdir_p("#{tmpdir}/_irbrc")
155+
FileUtils.mkdir_p("#{tmpdir}/irb.rc")
156+
FileUtils.mkdir_p("#{tmpdir}/$irbrc")
157+
158+
Dir.chdir(tmpdir) do
159+
IRB.conf[:RC_NAME_GENERATOR] = nil
160+
assert_includes IRB.rc_files, tmpdir+"/.irbrc"
161+
assert_includes IRB.rc_files, tmpdir+"/_irbrc"
162+
assert_includes IRB.rc_files, tmpdir+"/irb.rc"
163+
assert_includes IRB.rc_files, tmpdir+"/$irbrc"
164+
end
67165
end
68166

69167
def test_sigint_restore_default

0 commit comments

Comments
 (0)