From 78caffbcbca9ed96de1ee695857872d2e7dd57d4 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Sun, 17 Feb 2013 20:43:07 -0800 Subject: [PATCH] Dedup .pryrc across symlinks too --- lib/pry.rb | 1 + lib/pry/pry_class.rb | 38 +++++++++------- spec/fixtures/testlinkrc | 1 + spec/pry_spec.rb | 84 ----------------------------------- spec/pryrc_spec.rb | 94 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+), 100 deletions(-) create mode 120000 spec/fixtures/testlinkrc create mode 100644 spec/pryrc_spec.rb diff --git a/lib/pry.rb b/lib/pry.rb index 64b2db1c..ea46b774 100644 --- a/lib/pry.rb +++ b/lib/pry.rb @@ -212,6 +212,7 @@ require 'coderay' require 'slop' require 'rbconfig' require 'tempfile' +require 'pathname' begin require 'readline' diff --git a/lib/pry/pry_class.rb b/lib/pry/pry_class.rb index 9268fcbc..19af3819 100644 --- a/lib/pry/pry_class.rb +++ b/lib/pry/pry_class.rb @@ -68,26 +68,33 @@ class Pry # Load the given file in the context of `Pry.toplevel_binding` # @param [String] file_name The unexpanded file path. - def self.load_file_at_toplevel(file_name) - full_name = File.expand_path(file_name) - begin - toplevel_binding.eval(File.read(full_name), full_name) if File.exists?(full_name) - rescue RescuableException => e - puts "Error loading #{file_name}: #{e}\n#{e.backtrace.first}" - end + def self.load_file_at_toplevel(file) + toplevel_binding.eval(File.read(file), file) + rescue RescuableException => e + puts "Error loading #{file}: #{e}\n#{e.backtrace.first}" end - # Load the rc files given in the `Pry::RC_FILES` array. + # Load HOME_RC_FILE and LOCAL_RC_FILE if appropriate # This method can also be used to reload the files if they have changed. - def self.load_rc - load_file_at_toplevel(HOME_RC_FILE) + def self.load_rc_files + rc_files_to_load.each do |file| + load_file_at_toplevel(file) + end end # Load the local RC file (./.pryrc) - def self.load_local_rc - unless File.expand_path(HOME_RC_FILE) == File.expand_path(LOCAL_RC_FILE) - load_file_at_toplevel(LOCAL_RC_FILE) - end + def self.rc_files_to_load + files = [] + files << HOME_RC_FILE if Pry.config.should_load_rc + files << LOCAL_RC_FILE if Pry.config.should_load_local_rc + files.map { |file| real_path_to(file) }.compact.uniq + end + + # Expand a file to its canonical name (following symlinks as appropriate) + def self.real_path_to(file) + Pathname.new(File.expand_path(file)).realpath.to_s + rescue Errno::ENOENT + nil end # Load any Ruby files specified with the -r flag on the command line. @@ -112,8 +119,7 @@ class Pry # note these have to be loaded here rather than in pry_instance as # we only want them loaded once per entire Pry lifetime. - load_rc if Pry.config.should_load_rc - load_local_rc if Pry.config.should_load_local_rc + load_rc_files load_plugins if Pry.config.should_load_plugins load_requires if Pry.config.should_load_requires load_history if Pry.config.history.should_load diff --git a/spec/fixtures/testlinkrc b/spec/fixtures/testlinkrc new file mode 120000 index 00000000..a307d521 --- /dev/null +++ b/spec/fixtures/testlinkrc @@ -0,0 +1 @@ +testrc \ No newline at end of file diff --git a/spec/pry_spec.rb b/spec/pry_spec.rb index c21c370e..1082b8ed 100644 --- a/spec/pry_spec.rb +++ b/spec/pry_spec.rb @@ -281,90 +281,6 @@ describe Pry do end end - describe "test loading rc files" do - before do - Pry::HOME_RC_FILE.replace "spec/fixtures/testrc" - Pry::LOCAL_RC_FILE.replace "spec/fixtures/testrc/../testrc" - Pry.instance_variable_set(:@initial_session, true) - end - - after do - Pry::HOME_RC_FILE.replace "~/.pryrc" - Pry::LOCAL_RC_FILE.replace "./.pryrc" - Pry.config.should_load_rc = false - Object.remove_const(:TEST_RC) if defined?(TEST_RC) - end - - it "should never run the rc file twice" do - Pry.config.should_load_rc = true - - Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) - TEST_RC.should == [0] - - Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) - TEST_RC.should == [0] - end - - it "should not load the pryrc if it cannot expand ENV[HOME]" do - old_home = ENV['HOME'] - old_rc = Pry.config.should_load_rc - ENV['HOME'] = nil - Pry.config.should_load_rc = true - lambda { Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) }.should.not.raise - - ENV['HOME'] = old_home - Pry.config.should_load_rc = old_rc - end - - it "should not run the rc file at all if Pry.config.should_load_rc is false" do - Pry.config.should_load_rc = false - Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) - Object.const_defined?(:TEST_RC).should == false - end - - describe "that raise exceptions" do - before do - Pry::HOME_RC_FILE = "spec/fixtures/testrcbad" - Pry.config.should_load_rc = true - Pry.config.should_load_local_rc = false - - putsed = nil - - # YUCK! horrible hack to get round the fact that output is not configured - # at the point this message is printed. - (class << Pry; self; end).send(:define_method, :puts) { |str| - putsed = str - } - - @doing_it = lambda{ - Pry.start(self, :input => StringIO.new("Object::TEST_AFTER_RAISE=1\nexit-all\n"), :output => StringIO.new) - putsed - } - end - - after do - Object.remove_const(:TEST_BEFORE_RAISE) - Object.remove_const(:TEST_AFTER_RAISE) - (class << Pry; undef_method :puts; end) - end - - it "should not raise exceptions" do - @doing_it.should.not.raise - end - - it "should continue to run pry" do - @doing_it[] - Object.const_defined?(:TEST_BEFORE_RAISE).should == true - Object.const_defined?(:TEST_AFTER_RAISE).should == true - end - - it "should output an error" do - @doing_it.call.split("\n").first.should == - "Error loading spec/fixtures/testrcbad: messin with ya" - end - end - end - describe "nesting" do after do Pry.reset_defaults diff --git a/spec/pryrc_spec.rb b/spec/pryrc_spec.rb new file mode 100644 index 00000000..8f47dc38 --- /dev/null +++ b/spec/pryrc_spec.rb @@ -0,0 +1,94 @@ +require 'helper' + +describe Pry do + describe 'loading rc files' do + before do + Pry::HOME_RC_FILE.replace "spec/fixtures/testrc" + Pry::LOCAL_RC_FILE.replace "spec/fixtures/testrc/../testrc" + Pry.instance_variable_set(:@initial_session, true) + Pry.config.should_load_rc = true + Pry.config.should_load_local_rc = true + end + + after do + Pry::HOME_RC_FILE.replace "~/.pryrc" + Pry::LOCAL_RC_FILE.replace "./.pryrc" + Pry.config.should_load_rc = false + Object.remove_const(:TEST_RC) if defined?(TEST_RC) + end + + it "should never run the rc file twice" do + Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) + TEST_RC.should == [0] + + Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) + TEST_RC.should == [0] + end + + it "should not load the rc file twice if it's symlinked differently" do + Pry::HOME_RC_FILE.replace "spec/fixtures/testrc" + Pry::LOCAL_RC_FILE.replace "spec/fixtures/testlinkrc" + + Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) + + TEST_RC.should == [0] + end + + it "should not load the pryrc if it cannot expand ENV[HOME]" do + old_home = ENV['HOME'] + ENV['HOME'] = nil + Pry.config.should_load_rc = true + lambda { Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) }.should.not.raise + + ENV['HOME'] = old_home + end + + it "should not run the rc file at all if Pry.config.should_load_rc is false" do + Pry.config.should_load_rc = false + Pry.config.should_load_local_rc = false + Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) + Object.const_defined?(:TEST_RC).should == false + end + + describe "that raise exceptions" do + before do + Pry::HOME_RC_FILE = "spec/fixtures/testrcbad" + Pry.config.should_load_local_rc = false + + putsed = nil + + # YUCK! horrible hack to get round the fact that output is not configured + # at the point this message is printed. + (class << Pry; self; end).send(:define_method, :puts) { |str| + putsed = str + } + + @doing_it = lambda{ + Pry.start(self, :input => StringIO.new("Object::TEST_AFTER_RAISE=1\nexit-all\n"), :output => StringIO.new) + putsed + } + end + + after do + Object.remove_const(:TEST_BEFORE_RAISE) + Object.remove_const(:TEST_AFTER_RAISE) + (class << Pry; undef_method :puts; end) + end + + it "should not raise exceptions" do + @doing_it.should.not.raise + end + + it "should continue to run pry" do + @doing_it[] + Object.const_defined?(:TEST_BEFORE_RAISE).should == true + Object.const_defined?(:TEST_AFTER_RAISE).should == true + end + + it "should output an error" do + @doing_it.call.split("\n").first.should =~ + %r{Error loading .*spec/fixtures/testrcbad: messin with ya} + end + end + end +end