diff --git a/lib/irb/cmd/irb_info.rb b/lib/irb/cmd/irb_info.rb index 5b905a09b..3abcc2435 100644 --- a/lib/irb/cmd/irb_info.rb +++ b/lib/irb/cmd/irb_info.rb @@ -15,7 +15,10 @@ def execute str += "IRB version: #{IRB.version}\n" str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n" str += "Completion: #{IRB.CurrentContext.io.respond_to?(:completion_info) ? IRB.CurrentContext.io.completion_info : 'off'}\n" - str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file) + rc_files = IRB.rc_files.each_with_object([]) do |rc, files| + files << rc if File.exist?(rc) + end + str += ".irbrc paths: #{rc_files.join(", ")}\n" if rc_files.any? str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n" str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty? str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty? diff --git a/lib/irb/history.rb b/lib/irb/history.rb index 50fe1ce22..e1520bf86 100644 --- a/lib/irb/history.rb +++ b/lib/irb/history.rb @@ -14,7 +14,7 @@ def load_history if history_file = IRB.conf[:HISTORY_FILE] history_file = File.expand_path(history_file) end - history_file = IRB.rc_file("_history") unless history_file + history_file = IRB.rc_files("_history").first unless history_file if File.exist?(history_file) File.open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f| f.each { |l| @@ -39,7 +39,7 @@ def save_history if history_file = IRB.conf[:HISTORY_FILE] history_file = File.expand_path(history_file) end - history_file = IRB.rc_file("_history") unless history_file + history_file = IRB.rc_files("_history").first unless history_file # Change the permission of a file that already exists[BUG #7694] begin diff --git a/lib/irb/init.rb b/lib/irb/init.rb index 66e7b6146..97fd12dbb 100644 --- a/lib/irb/init.rb +++ b/lib/irb/init.rb @@ -392,33 +392,41 @@ def IRB.parse_opts(argv: ::ARGV) # Run the config file def IRB.run_config if @CONF[:RC] - begin - file = rc_file + rc_files.each do |rc| # Because rc_file always returns `HOME/.irbrc` even if no rc file is present, we can't warn users about missing rc files. # Otherwise, it'd be very noisy. - load file if File.exist?(file) + load rc if File.exist?(rc) rescue StandardError, ScriptError => e - warn "Error loading RC file '#{file}':\n#{e.full_message(highlight: false)}" + warn "Error loading RC file '#{rc}':\n#{e.full_message(highlight: false)}" end end end IRBRC_EXT = "rc" def IRB.rc_file(ext = IRBRC_EXT) + warn "rc_file is deprecated, please use rc_files instead." + rc_files(ext).first + end + + def IRB.rc_files(ext = IRBRC_EXT) if !@CONF[:RC_NAME_GENERATOR] + @CONF[:RC_NAME_GENERATOR] ||= [] + existing_rc_files = [] + rc_file_generators do |rcgen| - @CONF[:RC_NAME_GENERATOR] ||= rcgen - if File.exist?(rcgen.call(IRBRC_EXT)) - @CONF[:RC_NAME_GENERATOR] = rcgen - break - end + @CONF[:RC_NAME_GENERATOR] << rcgen + existing_rc_files << rcgen if File.exist?(rcgen.call(IRBRC_EXT)) + end + + if existing_rc_files.any? + @CONF[:RC_NAME_GENERATOR] = existing_rc_files end end - case rc_file = @CONF[:RC_NAME_GENERATOR].call(ext) - when String + + @CONF[:RC_NAME_GENERATOR].map do |rc| + rc_file = rc.call(ext) + fail IllegalRCNameGenerator unless rc_file.is_a?(String) rc_file - else - fail IllegalRCNameGenerator end end diff --git a/test/irb/test_cmd.rb b/test/irb/test_cmd.rb index d99ac05c5..9270e86ec 100644 --- a/test/irb/test_cmd.rb +++ b/test/irb/test_cmd.rb @@ -77,6 +77,7 @@ def teardown def test_irb_info_multiline FileUtils.touch("#{@tmpdir}/.inputrc") FileUtils.touch("#{@tmpdir}/.irbrc") + FileUtils.touch("#{@tmpdir}/_irbrc") out, err = execute_lines( "irb_info", @@ -88,7 +89,7 @@ def test_irb_info_multiline IRB\sversion:\sirb\s.+\n InputMethod:\sAbstract\sInputMethod\n Completion: .+\n - \.irbrc\spath:\s.+\n + \.irbrc\spaths:.*\.irbrc.*_irbrc\n RUBY_PLATFORM:\s.+\n East\sAsian\sAmbiguous\sWidth:\s\d\n #{@is_win ? 'Code\spage:\s\d+\n' : ''} @@ -112,7 +113,7 @@ def test_irb_info_singleline IRB\sversion:\sirb\s.+\n InputMethod:\sAbstract\sInputMethod\n Completion: .+\n - \.irbrc\spath:\s.+\n + \.irbrc\spaths:\s.+\n RUBY_PLATFORM:\s.+\n East\sAsian\sAmbiguous\sWidth:\s\d\n #{@is_win ? 'Code\spage:\s\d+\n' : ''} @@ -198,7 +199,7 @@ def test_irb_info_lang IRB\sversion:\sirb .+\n InputMethod:\sAbstract\sInputMethod\n Completion: .+\n - \.irbrc\spath: .+\n + \.irbrc\spaths: .+\n RUBY_PLATFORM: .+\n LANG\senv:\sja_JP\.UTF-8\n LC_ALL\senv:\sen_US\.UTF-8\n diff --git a/test/irb/test_history.rb b/test/irb/test_history.rb index f7ba2b9d3..22d04762c 100644 --- a/test/irb/test_history.rb +++ b/test/irb/test_history.rb @@ -136,7 +136,7 @@ def test_history_concurrent_use_not_present io.class::HISTORY << 'line1' io.class::HISTORY << 'line2' - history_file = IRB.rc_file("_history") + history_file = IRB.rc_files("_history").first assert_not_send [File, :file?, history_file] File.write(history_file, "line0\n") io.save_history @@ -204,9 +204,10 @@ def assert_history(expected_history, initial_irb_history, input, input_method = backup_xdg_config_home = ENV.delete("XDG_CONFIG_HOME") IRB.conf[:LC_MESSAGES] = locale actual_history = nil + history_file = IRB.rc_files("_history").first Dir.mktmpdir("test_irb_history_") do |tmpdir| ENV["HOME"] = tmpdir - File.open(IRB.rc_file("_history"), "w") do |f| + File.open(history_file, "w") do |f| f.write(initial_irb_history) end @@ -216,7 +217,7 @@ def assert_history(expected_history, initial_irb_history, input, input_method = if block_given? previous_history = [] io.class::HISTORY.each { |line| previous_history << line } - yield IRB.rc_file("_history") + yield history_file io.class::HISTORY.clear previous_history.each { |line| io.class::HISTORY << line } end @@ -224,7 +225,7 @@ def assert_history(expected_history, initial_irb_history, input, input_method = io.save_history io.load_history - File.open(IRB.rc_file("_history"), "r") do |f| + File.open(history_file, "r") do |f| actual_history = f.read end end diff --git a/test/irb/test_init.rb b/test/irb/test_init.rb index 036509813..16861a7a7 100644 --- a/test/irb/test_init.rb +++ b/test/irb/test_init.rb @@ -66,6 +66,57 @@ def test_rc_file_in_subdir end end + def test_rc_files + tmpdir = @tmpdir + Dir.chdir(tmpdir) do + ENV["XDG_CONFIG_HOME"] = "#{tmpdir}/xdg" + IRB.conf[:RC_NAME_GENERATOR] = nil + assert_includes IRB.rc_files, tmpdir+"/.irb#{IRB::IRBRC_EXT}" + assert_includes IRB.rc_files("_history"), tmpdir+"/.irb_history" + assert_file.not_exist?(tmpdir+"/xdg") + IRB.conf[:RC_NAME_GENERATOR] = nil + FileUtils.touch(tmpdir+"/.irb#{IRB::IRBRC_EXT}") + assert_includes IRB.rc_files, tmpdir+"/.irb#{IRB::IRBRC_EXT}" + assert_includes IRB.rc_files("_history"), tmpdir+"/.irb_history" + assert_file.not_exist?(tmpdir+"/xdg") + end + end + + def test_rc_files_contains_multiple_files + tmpdir = @tmpdir + ENV["XDG_CONFIG_HOME"] = "#{tmpdir}/xdg" + ENV["IRBRC"] = "#{tmpdir}/irb" + xdg_config = ENV["XDG_CONFIG_HOME"]+"/irb/irb#{IRB::IRBRC_EXT}" + + FileUtils.mkdir_p(xdg_config) + FileUtils.mkdir_p(ENV["IRBRC"]) + + Dir.chdir(tmpdir) do + IRB.conf[:RC_NAME_GENERATOR] = nil + assert_includes IRB.rc_files, ENV["IRBRC"] + assert_includes IRB.rc_files, xdg_config + end + ensure + ENV["IRBRC"] = nil + ENV["XDG_CONFIG_HOME"] = nil + end + + def test_rc_files_in_subdir + tmpdir = @tmpdir + Dir.chdir(tmpdir) do + FileUtils.mkdir_p("#{tmpdir}/mydir") + Dir.chdir("#{tmpdir}/mydir") do + IRB.conf[:RC_NAME_GENERATOR] = nil + assert_includes IRB.rc_files, tmpdir+"/.irb#{IRB::IRBRC_EXT}" + assert_includes IRB.rc_files("_history"), tmpdir+"/.irb_history" + IRB.conf[:RC_NAME_GENERATOR] = nil + FileUtils.touch(tmpdir+"/.irb#{IRB::IRBRC_EXT}") + assert_includes IRB.rc_files, tmpdir+"/.irb#{IRB::IRBRC_EXT}" + assert_includes IRB.rc_files("_history"), tmpdir+"/.irb_history" + end + end + end + def test_sigint_restore_default pend "This test gets stuck on Solaris for unknown reason; contribution is welcome" if RUBY_PLATFORM =~ /solaris/ bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []