diff options
author | The Bundler Bot <bot@bundler.io> | 2018-07-10 06:23:41 +0000 |
---|---|---|
committer | The Bundler Bot <bot@bundler.io> | 2018-07-10 06:23:41 +0000 |
commit | 9ca3afe30272a1403782cce0d600e7411e6cf709 (patch) | |
tree | 51b0cdb5c9b3fe1b53cf96ada4c1c7b8ef4e45e9 | |
parent | 7f0b57fa54aa946ad2fbcc122dcc41ab45287acd (diff) | |
parent | 865ec52ae87c29473405ce587977dd3eaef453ae (diff) | |
download | bundler-9ca3afe30272a1403782cce0d600e7411e6cf709.tar.gz |
Auto merge of #6502 - ojab:1-16-stable, r=indirect
Use realpath in clean_load_path
see #6465, basically we're not rejecting `bundler_lib` because we have symlink there and real path in `$LOAD_PATH`
```
$ irb
2.5.1 :001 > require 'bundler/setup'
# what happens next will shock you
From: /real_path/.rvm/gems/ruby-2.5.1/gems/bundler-1.16.2/lib/bundler/shared_helpers.rb @ line 339 Bundler::SharedHelpers#clean_load_path:
330: def clean_load_path
331: # handle 1.9 where system gems are always on the load path
332: return unless defined?(::Gem)
333:
334: bundler_lib = bundler_ruby_lib
335:
336: loaded_gem_paths = Bundler.rubygems.loaded_gem_paths
337:
338: binding.pry
=> 339: $LOAD_PATH.reject! do |p|
340: path = File.expand_path(p)
341: path = File.realpath(path) if File.exist?(path)
342: next if path.start_with?(bundler_lib)
343: loaded_gem_paths.delete(p)
344: end
345: $LOAD_PATH.uniq!
346: end
[1] pry(#<Bundler::Runtime>)> bundler_lib
=> "/real_path/.rvm/gems/ruby-2.5.1/gems/bundler-1.16.2/lib"
[2] pry(#<Bundler::Runtime>)> loaded_gem_paths
=> ["/symlinked_path/.rvm/gems/ruby-2.5.1@global/gems/did_you_mean-1.2.0/lib",
"/symlinked_path/.rvm/gems/ruby-2.5.1/gems/bundler-1.16.2/lib",
"/symlinked_path/.rvm/gems/ruby-2.5.1/gems/byebug-10.0.2/lib",
"/symlinked_path/.rvm/gems/ruby-2.5.1/extensions/x86_64-linux/2.5.0/byebug-10.0.2",
"/symlinked_path/.rvm/gems/ruby-2.5.1/gems/coderay-1.1.2/lib",
"/symlinked_path/.rvm/gems/ruby-2.5.1/gems/method_source-0.9.0/lib",
"/symlinked_path/.rvm/gems/ruby-2.5.1/gems/pry-0.11.3/lib",
"/symlinked_path/.rvm/gems/ruby-2.5.1/gems/pry-byebug-3.6.0/lib",
"/real_path/.rvm/rubies/ruby-2.5.1/lib/ruby/gems/2.5.0/gems/fileutils-1.0.2/lib",
"/real_path/.rvm/rubies/ruby-2.5.1/lib/ruby/gems/2.5.0/gems/psych-3.0.2/lib",
"/real_path/.rvm/rubies/ruby-2.5.1/lib/ruby/gems/2.5.0/extensions/x86_64-linux/2.5.0/psych-3.0.2"]
```
-rw-r--r-- | lib/bundler/shared_helpers.rb | 15 | ||||
-rw-r--r-- | spec/runtime/setup_spec.rb | 44 | ||||
-rw-r--r-- | spec/spec_helper.rb | 8 |
3 files changed, 65 insertions, 2 deletions
diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb index 93e2a35b54..b85e58ac66 100644 --- a/lib/bundler/shared_helpers.rb +++ b/lib/bundler/shared_helpers.rb @@ -331,7 +331,7 @@ module Bundler end def bundler_ruby_lib - File.expand_path("../..", __FILE__) + resolve_path File.expand_path("../..", __FILE__) end def clean_load_path @@ -343,12 +343,23 @@ module Bundler loaded_gem_paths = Bundler.rubygems.loaded_gem_paths $LOAD_PATH.reject! do |p| - next if File.expand_path(p).start_with?(bundler_lib) + next if resolve_path(p).start_with?(bundler_lib) loaded_gem_paths.delete(p) end $LOAD_PATH.uniq! end + def resolve_path(path) + expanded = File.expand_path(path) + return expanded unless File.respond_to?(:realpath) + + while File.exist?(expanded) && File.realpath(expanded) != expanded + expanded = File.realpath(expanded) + end + + expanded + end + def prints_major_deprecations? require "bundler" deprecation_release = Bundler::VERSION.split(".").drop(1).include?("99") diff --git a/spec/runtime/setup_spec.rb b/spec/runtime/setup_spec.rb index fdf77f4df1..cd87971238 100644 --- a/spec/runtime/setup_spec.rb +++ b/spec/runtime/setup_spec.rb @@ -857,6 +857,50 @@ end expect(out).to eq("true\ntrue") end + context "with bundler is located in symlinked GEM_HOME" do + let(:gem_home) { Dir.mktmpdir } + let(:symlinked_gem_home) { Tempfile.new("gem_home") } + let(:bundler_dir) { File.expand_path("../../..", __FILE__) } + let(:bundler_lib) { File.join(bundler_dir, "lib") } + + before do + FileUtils.ln_sf(gem_home, symlinked_gem_home.path) + gems_dir = File.join(gem_home, "gems") + specifications_dir = File.join(gem_home, "specifications") + Dir.mkdir(gems_dir) + Dir.mkdir(specifications_dir) + + FileUtils.ln_s(bundler_dir, File.join(gems_dir, "bundler-#{Bundler::VERSION}")) + + gemspec = File.read("#{bundler_dir}/bundler.gemspec"). + sub("Bundler::VERSION", %("#{Bundler::VERSION}")) + gemspec = gemspec.lines.reject {|line| line =~ %r{lib/bundler/version} }.join + + File.open(File.join(specifications_dir, "bundler.gemspec"), "wb") do |f| + f.write(gemspec) + end + end + + it "should succesfully require 'bundler/setup'" do + install_gemfile "" + + ENV["GEM_PATH"] = symlinked_gem_home.path + + ruby <<-R + if $LOAD_PATH.include?("#{bundler_lib}") + # We should use bundler from GEM_PATH for this test, so we should + # remove path to the bundler source tree + $LOAD_PATH.delete("#{bundler_lib}") + else + raise "We don't have #{bundler_lib} in $LOAD_PATH" + end + puts (require 'bundler/setup') + R + + expect(out).to eql("true") + end + end + it "stubs out Gem.refresh so it does not reveal system gems" do system_gems "rack-1.0.0" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 228b9e5aa3..f7a6b43d4b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -28,6 +28,14 @@ require "bundler/vendored_fileutils" require "uri" require "digest" +# Delete any copies of Bundler that have been dumped into site_ruby without +# a gemspec. RubyGems cannot manage that Bundler, and so our tricks to make +# sure that the correct version of Bundler loads will stop working. +require "fileutils" +Dir.glob(File.join(RbConfig::CONFIG["sitelibdir"], "bundler*")).each do |file| + FileUtils.rm_rf(file) +end + if File.expand_path(__FILE__) =~ %r{([^\w/\.-])} abort "The bundler specs cannot be run from a path that contains special characters (particularly #{$1.inspect})" end |