[ruby/irb] Fix irb_history saved to current directory

(https://github.com/ruby/irb/pull/901)

* Always save irb_history in HOME or XDG_CONFIG_HOME

Also split irbrc search logic from irb_history search logic as a refactor

* Remove IRB.conf[:RC_NAME_GENERATOR] because it's not configurable

This conf is used to specify which irbrc to load. Need to configure before irbrc is loaded, so it's actually not configurable.
This conf is also used for history file search, but it is configurable by conf[:HISTORY_FILE].

* remove rc_file_test because it is tested with rc_files, remove useless test setup

* Make internal irbrc searching method private

https://github.com/ruby/irb/commit/11d03a6ff7
This commit is contained in:
tomoya ishida 2024-03-17 00:19:59 +09:00 committed by git
parent aae9f5628c
commit bda5b09937
10 changed files with 148 additions and 188 deletions

View File

@ -165,9 +165,6 @@ for each entry that is pre-defined, the initial value is given:
- `:RC`: Whether a {configuration file}[rdoc-ref:IRB@Configuration+File] - `:RC`: Whether a {configuration file}[rdoc-ref:IRB@Configuration+File]
was found and interpreted; was found and interpreted;
initial value: `true` if a configuration file was found, `false` otherwise. initial value: `true` if a configuration file was found, `false` otherwise.
- `:RC_NAME_GENERATOR`: \Proc to generate paths of potential
{configuration files}[rdoc-ref:IRB@Configuration+File];
initial value: `=> #<Proc:0x000055f9bebfed80 /var/lib/gems/3.0.0/gems/irb-1.8.3/lib/irb/init.rb:401>`.
- `:SAVE_HISTORY`: Number of commands to save in - `:SAVE_HISTORY`: Number of commands to save in
{input command history}[rdoc-ref:IRB@Input+Command+History]; {input command history}[rdoc-ref:IRB@Input+Command+History];
initial value: `1000`. initial value: `1000`.

View File

@ -13,7 +13,7 @@ module IRB
str += "IRB version: #{IRB.version}\n" str += "IRB version: #{IRB.version}\n"
str += "InputMethod: #{IRB.CurrentContext.io.inspect}\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 += "Completion: #{IRB.CurrentContext.io.respond_to?(:completion_info) ? IRB.CurrentContext.io.completion_info : 'off'}\n"
rc_files = IRB.rc_files.select { |rc| File.exist?(rc) } rc_files = IRB.irbrc_files
str += ".irbrc paths: #{rc_files.join(", ")}\n" if rc_files.any? str += ".irbrc paths: #{rc_files.join(", ")}\n" if rc_files.any?
str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n" str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty? str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?

View File

@ -16,8 +16,8 @@ module IRB
if history_file = IRB.conf[:HISTORY_FILE] if history_file = IRB.conf[:HISTORY_FILE]
history_file = File.expand_path(history_file) history_file = File.expand_path(history_file)
end end
history_file = IRB.rc_files("_history").first unless history_file history_file = IRB.rc_file("_history") unless history_file
if File.exist?(history_file) if history_file && File.exist?(history_file)
File.open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f| File.open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f|
f.each { |l| f.each { |l|
l = l.chomp l = l.chomp
@ -41,7 +41,10 @@ module IRB
if history_file = IRB.conf[:HISTORY_FILE] if history_file = IRB.conf[:HISTORY_FILE]
history_file = File.expand_path(history_file) history_file = File.expand_path(history_file)
end end
history_file = IRB.rc_files("_history").first unless history_file history_file = IRB.rc_file("_history") unless history_file
# When HOME and XDG_CONFIG_HOME are not available, history_file might be nil
return unless history_file
# Change the permission of a file that already exists[BUG #7694] # Change the permission of a file that already exists[BUG #7694]
begin begin

View File

@ -395,10 +395,8 @@ module IRB # :nodoc:
# Run the config file # Run the config file
def IRB.run_config def IRB.run_config
if @CONF[:RC] if @CONF[:RC]
rc_files.each do |rc| irbrc_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. load rc
# Otherwise, it'd be very noisy.
load rc if File.exist?(rc)
rescue StandardError, ScriptError => e rescue StandardError, ScriptError => e
warn "Error loading RC file '#{rc}':\n#{e.full_message(highlight: false)}" warn "Error loading RC file '#{rc}':\n#{e.full_message(highlight: false)}"
end end
@ -406,53 +404,27 @@ module IRB # :nodoc:
end end
IRBRC_EXT = "rc" IRBRC_EXT = "rc"
def IRB.rc_file(ext = IRBRC_EXT)
warn "rc_file is deprecated, please use rc_files instead." def IRB.rc_file(ext)
rc_files(ext).first prepare_irbrc_name_generators
# When irbrc exist in default location
if (rcgen = @existing_rc_name_generators.first)
return rcgen.call(ext)
end end
def IRB.rc_files(ext = IRBRC_EXT) # When irbrc does not exist in default location
if !@CONF[:RC_NAME_GENERATOR]
@CONF[:RC_NAME_GENERATOR] ||= []
existing_rc_file_generators = []
rc_file_generators do |rcgen| rc_file_generators do |rcgen|
@CONF[:RC_NAME_GENERATOR] << rcgen return rcgen.call(ext)
existing_rc_file_generators << rcgen if File.exist?(rcgen.call(ext))
end end
if existing_rc_file_generators.any? # When HOME and XDG_CONFIG_HOME are not available
@CONF[:RC_NAME_GENERATOR] = existing_rc_file_generators nil
end
end end
@CONF[:RC_NAME_GENERATOR].map do |rc| def IRB.irbrc_files
rc_file = rc.call(ext) prepare_irbrc_name_generators
fail IllegalRCNameGenerator unless rc_file.is_a?(String) @irbrc_files
rc_file
end
end
# enumerate possible rc-file base name generators
def IRB.rc_file_generators
if irbrc = ENV["IRBRC"]
yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
end
if xdg_config_home = ENV["XDG_CONFIG_HOME"]
irb_home = File.join(xdg_config_home, "irb")
if File.directory?(irb_home)
yield proc{|rc| irb_home + "/irb#{rc}"}
end
end
if home = ENV["HOME"]
yield proc{|rc| home+"/.irb#{rc}"}
yield proc{|rc| home+"/.config/irb/irb#{rc}"}
end
current_dir = Dir.pwd
yield proc{|rc| current_dir+"/.irb#{rc}"}
yield proc{|rc| current_dir+"/irb#{rc.sub(/\A_?/, '.')}"}
yield proc{|rc| current_dir+"/_irb#{rc}"}
yield proc{|rc| current_dir+"/$irb#{rc}"}
end end
# loading modules # loading modules
@ -468,6 +440,50 @@ module IRB # :nodoc:
class << IRB class << IRB
private private
def prepare_irbrc_name_generators
return if @existing_rc_name_generators
@existing_rc_name_generators = []
@irbrc_files = []
rc_file_generators do |rcgen|
irbrc = rcgen.call(IRBRC_EXT)
if File.exist?(irbrc)
@irbrc_files << irbrc
@existing_rc_name_generators << rcgen
end
end
generate_current_dir_irbrc_files.each do |irbrc|
@irbrc_files << irbrc if File.exist?(irbrc)
end
@irbrc_files.uniq!
end
# enumerate possible rc-file base name generators
def rc_file_generators
if irbrc = ENV["IRBRC"]
yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
end
if xdg_config_home = ENV["XDG_CONFIG_HOME"]
irb_home = File.join(xdg_config_home, "irb")
if File.directory?(irb_home)
yield proc{|rc| irb_home + "/irb#{rc}"}
end
end
if home = ENV["HOME"]
yield proc{|rc| home+"/.irb#{rc}"}
if xdg_config_home.nil? || xdg_config_home.empty?
yield proc{|rc| home+"/.config/irb/irb#{rc}"}
end
end
end
# possible irbrc files in current directory
def generate_current_dir_irbrc_files
current_dir = Dir.pwd
%w[.irbrc irbrc _irbrc $irbrc].map { |file| "#{current_dir}/#{file}" }
end
def set_encoding(extern, intern = nil, override: true) def set_encoding(extern, intern = nil, override: true)
verbose, $VERBOSE = $VERBOSE, nil verbose, $VERBOSE = $VERBOSE, nil
Encoding.default_external = extern unless extern.nil? || extern.empty? Encoding.default_external = extern unless extern.nil? || extern.empty?

View File

@ -47,11 +47,6 @@ module IRB
super("Undefined prompt mode(#{val}).") super("Undefined prompt mode(#{val}).")
end end
end end
class IllegalRCGenerator < StandardError
def initialize
super("Define illegal RC_NAME_GENERATOR.")
end
end
# :startdoc: # :startdoc:
end end

View File

@ -47,11 +47,6 @@ module IRB
super("プロンプトモード(#{val})は定義されていません.") super("プロンプトモード(#{val})は定義されていません.")
end end
end end
class IllegalRCGenerator < StandardError
def initialize
super("RC_NAME_GENERATORが正しく定義されていません.")
end
end
# :startdoc: # :startdoc:
end end

View File

@ -20,6 +20,7 @@ module TestIRB
@xdg_config_home_backup = ENV.delete("XDG_CONFIG_HOME") @xdg_config_home_backup = ENV.delete("XDG_CONFIG_HOME")
save_encodings save_encodings
IRB.instance_variable_get(:@CONF).clear IRB.instance_variable_get(:@CONF).clear
IRB.instance_variable_set(:@existing_rc_name_generators, nil)
@is_win = (RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/) @is_win = (RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/)
end end

View File

@ -17,11 +17,11 @@ module TestIRB
@backup_irbrc = ENV.delete("IRBRC") @backup_irbrc = ENV.delete("IRBRC")
@backup_default_external = Encoding.default_external @backup_default_external = Encoding.default_external
ENV["HOME"] = @tmpdir ENV["HOME"] = @tmpdir
IRB.conf[:RC_NAME_GENERATOR] = nil IRB.instance_variable_set(:@existing_rc_name_generators, nil)
end end
def teardown def teardown
IRB.conf[:RC_NAME_GENERATOR] = nil IRB.instance_variable_set(:@existing_rc_name_generators, nil)
ENV["HOME"] = @backup_home ENV["HOME"] = @backup_home
ENV["XDG_CONFIG_HOME"] = @backup_xdg_config_home ENV["XDG_CONFIG_HOME"] = @backup_xdg_config_home
ENV["IRBRC"] = @backup_irbrc ENV["IRBRC"] = @backup_irbrc
@ -144,7 +144,7 @@ module TestIRB
io.class::HISTORY << 'line1' io.class::HISTORY << 'line1'
io.class::HISTORY << 'line2' io.class::HISTORY << 'line2'
history_file = IRB.rc_files("_history").first history_file = IRB.rc_file("_history")
assert_not_send [File, :file?, history_file] assert_not_send [File, :file?, history_file]
File.write(history_file, "line0\n") File.write(history_file, "line0\n")
io.save_history io.save_history
@ -183,6 +183,16 @@ module TestIRB
IRB.conf[:HISTORY_FILE] = backup_history_file IRB.conf[:HISTORY_FILE] = backup_history_file
end end
def test_no_home_no_history_file_does_not_raise_history_save
ENV['HOME'] = nil
io = TestInputMethodWithRelineHistory.new
assert_nil(IRB.rc_file('_history'))
assert_nothing_raised do
io.load_history
io.save_history
end
end
private private
def history_concurrent_use_for_input_method(input_method) def history_concurrent_use_for_input_method(input_method)
@ -217,7 +227,7 @@ module TestIRB
def assert_history(expected_history, initial_irb_history, input, input_method = TestInputMethodWithRelineHistory, locale: IRB::Locale.new) def assert_history(expected_history, initial_irb_history, input, input_method = TestInputMethodWithRelineHistory, locale: IRB::Locale.new)
IRB.conf[:LC_MESSAGES] = locale IRB.conf[:LC_MESSAGES] = locale
actual_history = nil actual_history = nil
history_file = IRB.rc_files("_history").first history_file = IRB.rc_file("_history")
ENV["HOME"] = @tmpdir ENV["HOME"] = @tmpdir
File.open(history_file, "w") do |f| File.open(history_file, "w") do |f|
f.write(initial_irb_history) f.write(initial_irb_history)

View File

@ -14,10 +14,15 @@ module TestIRB
ENV["HOME"] = @tmpdir = File.realpath(Dir.mktmpdir("test_irb_init_#{$$}")) ENV["HOME"] = @tmpdir = File.realpath(Dir.mktmpdir("test_irb_init_#{$$}"))
end end
def reset_rc_name_generators
IRB.instance_variable_set(:@existing_rc_name_generators, nil)
end
def teardown def teardown
ENV.update(@backup_env) ENV.update(@backup_env)
FileUtils.rm_rf(@tmpdir) FileUtils.rm_rf(@tmpdir)
IRB.conf.delete(:SCRIPT) IRB.conf.delete(:SCRIPT)
reset_rc_name_generators
end end
def test_setup_with_argv_preserves_global_argv def test_setup_with_argv_preserves_global_argv
@ -34,133 +39,65 @@ module TestIRB
assert_equal orig, $0 assert_equal orig, $0
end end
def test_rc_file
verbose, $VERBOSE = $VERBOSE, nil
tmpdir = @tmpdir
Dir.chdir(tmpdir) do
ENV["XDG_CONFIG_HOME"] = "#{tmpdir}/xdg"
IRB.conf[:RC_NAME_GENERATOR] = nil
assert_equal(tmpdir+"/.irbrc", IRB.rc_file)
assert_equal(tmpdir+"/.irb_history", IRB.rc_file("_history"))
assert_file.not_exist?(tmpdir+"/xdg")
IRB.conf[:RC_NAME_GENERATOR] = nil
FileUtils.touch(tmpdir+"/.irbrc")
assert_equal(tmpdir+"/.irbrc", IRB.rc_file)
assert_equal(tmpdir+"/.irb_history", IRB.rc_file("_history"))
assert_file.not_exist?(tmpdir+"/xdg")
end
ensure
$VERBOSE = verbose
end
def test_rc_file_in_subdir
verbose, $VERBOSE = $VERBOSE, nil
tmpdir = @tmpdir
Dir.chdir(tmpdir) do
FileUtils.mkdir_p("#{tmpdir}/mydir")
Dir.chdir("#{tmpdir}/mydir") do
IRB.conf[:RC_NAME_GENERATOR] = nil
assert_equal(tmpdir+"/.irbrc", IRB.rc_file)
assert_equal(tmpdir+"/.irb_history", IRB.rc_file("_history"))
IRB.conf[:RC_NAME_GENERATOR] = nil
FileUtils.touch(tmpdir+"/.irbrc")
assert_equal(tmpdir+"/.irbrc", IRB.rc_file)
assert_equal(tmpdir+"/.irb_history", IRB.rc_file("_history"))
end
end
ensure
$VERBOSE = verbose
end
def test_rc_files def test_rc_files
tmpdir = @tmpdir tmpdir = @tmpdir
Dir.chdir(tmpdir) do Dir.chdir(tmpdir) do
ENV["XDG_CONFIG_HOME"] = "#{tmpdir}/xdg" home = ENV['HOME'] = "#{tmpdir}/home"
IRB.conf[:RC_NAME_GENERATOR] = nil xdg_config_home = ENV['XDG_CONFIG_HOME'] = "#{tmpdir}/xdg"
assert_includes IRB.rc_files, tmpdir+"/.irbrc" reset_rc_name_generators
assert_includes IRB.rc_files("_history"), tmpdir+"/.irb_history" assert_empty(IRB.irbrc_files)
assert_file.not_exist?(tmpdir+"/xdg") assert_equal("#{home}/.irb_history", IRB.rc_file('_history'))
IRB.conf[:RC_NAME_GENERATOR] = nil FileUtils.mkdir_p(home)
FileUtils.touch(tmpdir+"/.irbrc") FileUtils.mkdir_p("#{xdg_config_home}/irb")
assert_includes IRB.rc_files, tmpdir+"/.irbrc" FileUtils.mkdir_p("#{home}/.config/irb")
assert_includes IRB.rc_files("_history"), tmpdir+"/.irb_history" reset_rc_name_generators
assert_file.not_exist?(tmpdir+"/xdg") assert_empty(IRB.irbrc_files)
assert_equal("#{xdg_config_home}/irb/irb_history", IRB.rc_file('_history'))
home_irbrc = "#{home}/.irbrc"
config_irbrc = "#{home}/.config/irb/irbrc"
xdg_config_irbrc = "#{xdg_config_home}/irb/irbrc"
[home_irbrc, config_irbrc, xdg_config_irbrc].each do |file|
FileUtils.touch(file)
end
current_dir_irbrcs = %w[.irbrc irbrc _irbrc $irbrc].map { |file| "#{tmpdir}/#{file}" }
current_dir_irbrcs.each { |file| FileUtils.touch(file) }
reset_rc_name_generators
assert_equal([xdg_config_irbrc, home_irbrc, *current_dir_irbrcs], IRB.irbrc_files)
assert_equal(xdg_config_irbrc.sub(/rc$/, '_history'), IRB.rc_file('_history'))
ENV['XDG_CONFIG_HOME'] = nil
reset_rc_name_generators
assert_equal([home_irbrc, config_irbrc, *current_dir_irbrcs], IRB.irbrc_files)
assert_equal(home_irbrc.sub(/rc$/, '_history'), IRB.rc_file('_history'))
ENV['XDG_CONFIG_HOME'] = ''
reset_rc_name_generators
assert_equal([home_irbrc, config_irbrc] + current_dir_irbrcs, IRB.irbrc_files)
assert_equal(home_irbrc.sub(/rc$/, '_history'), IRB.rc_file('_history'))
ENV['XDG_CONFIG_HOME'] = xdg_config_home
ENV['IRBRC'] = "#{tmpdir}/.irbrc"
reset_rc_name_generators
assert_equal([ENV['IRBRC'], xdg_config_irbrc, home_irbrc] + (current_dir_irbrcs - [ENV['IRBRC']]), IRB.irbrc_files)
assert_equal(ENV['IRBRC'] + '_history', IRB.rc_file('_history'))
ENV['IRBRC'] = ENV['HOME'] = ENV['XDG_CONFIG_HOME'] = nil
reset_rc_name_generators
assert_equal(current_dir_irbrcs, IRB.irbrc_files)
assert_nil(IRB.rc_file('_history'))
end end
end end
def test_rc_files_in_subdir def test_duplicated_rc_files
tmpdir = @tmpdir tmpdir = @tmpdir
Dir.chdir(tmpdir) do Dir.chdir(tmpdir) do
FileUtils.mkdir_p("#{tmpdir}/mydir") ENV['XDG_CONFIG_HOME'] = "#{ENV['HOME']}/.config"
Dir.chdir("#{tmpdir}/mydir") do FileUtils.mkdir_p("#{ENV['XDG_CONFIG_HOME']}/irb")
IRB.conf[:RC_NAME_GENERATOR] = nil env_irbrc = ENV['IRBRC'] = "#{tmpdir}/_irbrc"
assert_includes IRB.rc_files, tmpdir+"/.irbrc" xdg_config_irbrc = "#{ENV['XDG_CONFIG_HOME']}/irb/irbrc"
assert_includes IRB.rc_files("_history"), tmpdir+"/.irb_history" home_irbrc = "#{ENV['HOME']}/.irbrc"
IRB.conf[:RC_NAME_GENERATOR] = nil current_dir_irbrc = "#{tmpdir}/irbrc"
FileUtils.touch(tmpdir+"/.irbrc") [env_irbrc, xdg_config_irbrc, home_irbrc, current_dir_irbrc].each do |file|
assert_includes IRB.rc_files, tmpdir+"/.irbrc" FileUtils.touch(file)
assert_includes IRB.rc_files("_history"), tmpdir+"/.irb_history"
end end
end reset_rc_name_generators
end assert_equal([env_irbrc, xdg_config_irbrc, home_irbrc, current_dir_irbrc], IRB.irbrc_files)
def test_rc_files_has_file_from_xdg_env
tmpdir = @tmpdir
ENV["XDG_CONFIG_HOME"] = "#{tmpdir}/xdg"
xdg_config = ENV["XDG_CONFIG_HOME"]+"/irb/irbrc"
FileUtils.mkdir_p(xdg_config)
Dir.chdir(tmpdir) do
IRB.conf[:RC_NAME_GENERATOR] = nil
assert_includes IRB.rc_files, xdg_config
end
ensure
ENV["XDG_CONFIG_HOME"] = nil
end
def test_rc_files_has_file_from_irbrc_env
tmpdir = @tmpdir
ENV["IRBRC"] = "#{tmpdir}/irb"
FileUtils.mkdir_p(ENV["IRBRC"])
Dir.chdir(tmpdir) do
IRB.conf[:RC_NAME_GENERATOR] = nil
assert_includes IRB.rc_files, ENV["IRBRC"]
end
ensure
ENV["IRBRC"] = nil
end
def test_rc_files_has_file_from_home_env
tmpdir = @tmpdir
ENV["HOME"] = "#{tmpdir}/home"
FileUtils.mkdir_p(ENV["HOME"])
Dir.chdir(tmpdir) do
IRB.conf[:RC_NAME_GENERATOR] = nil
assert_includes IRB.rc_files, ENV["HOME"]+"/.irbrc"
assert_includes IRB.rc_files, ENV["HOME"]+"/.config/irb/irbrc"
end
ensure
ENV["HOME"] = nil
end
def test_rc_files_contains_non_env_files
tmpdir = @tmpdir
FileUtils.mkdir_p("#{tmpdir}/.irbrc")
FileUtils.mkdir_p("#{tmpdir}/_irbrc")
FileUtils.mkdir_p("#{tmpdir}/irb.rc")
FileUtils.mkdir_p("#{tmpdir}/$irbrc")
Dir.chdir(tmpdir) do
IRB.conf[:RC_NAME_GENERATOR] = nil
assert_includes IRB.rc_files, tmpdir+"/.irbrc"
assert_includes IRB.rc_files, tmpdir+"/_irbrc"
assert_includes IRB.rc_files, tmpdir+"/irb.rc"
assert_includes IRB.rc_files, tmpdir+"/$irbrc"
end end
end end

View File

@ -11,6 +11,8 @@ end
class IRB::RenderingTest < Yamatanooroti::TestCase class IRB::RenderingTest < Yamatanooroti::TestCase
def setup def setup
@original_term = ENV['TERM'] @original_term = ENV['TERM']
@home_backup = ENV['HOME']
@xdg_config_home_backup = ENV['XDG_CONFIG_HOME']
ENV['TERM'] = "xterm-256color" ENV['TERM'] = "xterm-256color"
@pwd = Dir.pwd @pwd = Dir.pwd
suffix = '%010d' % Random.rand(0..65535) suffix = '%010d' % Random.rand(0..65535)
@ -24,12 +26,16 @@ class IRB::RenderingTest < Yamatanooroti::TestCase
@irbrc_backup = ENV['IRBRC'] @irbrc_backup = ENV['IRBRC']
@irbrc_file = ENV['IRBRC'] = File.join(@tmpdir, 'temporaty_irbrc') @irbrc_file = ENV['IRBRC'] = File.join(@tmpdir, 'temporaty_irbrc')
File.unlink(@irbrc_file) if File.exist?(@irbrc_file) File.unlink(@irbrc_file) if File.exist?(@irbrc_file)
ENV['HOME'] = File.join(@tmpdir, 'home')
ENV['XDG_CONFIG_HOME'] = File.join(@tmpdir, 'xdg_config_home')
end end
def teardown def teardown
FileUtils.rm_rf(@tmpdir) FileUtils.rm_rf(@tmpdir)
ENV['IRBRC'] = @irbrc_backup ENV['IRBRC'] = @irbrc_backup
ENV['TERM'] = @original_term ENV['TERM'] = @original_term
ENV['HOME'] = @home_backup
ENV['XDG_CONFIG_HOME'] = @xdg_config_home_backup
end end
def test_launch def test_launch