diff options
author | The Bundler Bot <bot@bundler.io> | 2017-07-05 09:00:46 +0000 |
---|---|---|
committer | The Bundler Bot <bot@bundler.io> | 2017-07-05 09:00:46 +0000 |
commit | 5c62240fea87358a2f5aad729fcd27cf71319b4b (patch) | |
tree | 6707c280a91e48d8c0072472247a6aa8ea7e1767 | |
parent | bb1bee3b0810744225ef0f4d9f6c82641569f956 (diff) | |
parent | b9add49475bbd2cf59f5e655d7399c924555f670 (diff) | |
download | bundler-5c62240fea87358a2f5aad729fcd27cf71319b4b.tar.gz |
Auto merge of #5819 - bundler:seg-full-index-invalid-deps, r=indirect
[RemoteSpecification] Fail gracefully when deps is an array of array of string
Instead of containing Gem::Dependency objects
### What was the end-user problem that led to this PR?
The problem was some gems have invalid gemspecs served by RubyGems.org. See https://github.com/bundler/bundler/issues/5797.
### Was was your diagnosis of the problem?
My diagnosis was (very old) some gemspecs can have `s.dependencies = [["name", "req"]]` instead of `s.dependencies = [Gem::Dependency.new("name", "req")]`.
### What is your fix for the problem, implemented in this PR?
My fix coerces the invalid dependencies to an array of dependency objects so we can fail more gracefully during installation, without spitting out the error template.
Closes #5797.
### Why did you choose this fix out of the possible options?
I chose this fix because it allows resolution to finish, and falls back upon existing error messages.
-rw-r--r-- | lib/bundler/remote_specification.rb | 10 | ||||
-rw-r--r-- | spec/commands/install_spec.rb | 24 |
2 files changed, 33 insertions, 1 deletions
diff --git a/lib/bundler/remote_specification.rb b/lib/bundler/remote_specification.rb index d89abd98ab..208ee1d4b7 100644 --- a/lib/bundler/remote_specification.rb +++ b/lib/bundler/remote_specification.rb @@ -73,7 +73,15 @@ module Bundler end def dependencies - @dependencies || method_missing(:dependencies) + @dependencies ||= begin + deps = method_missing(:dependencies) + + # allow us to handle when the specs dependencies are an array of array of string + # see https://github.com/bundler/bundler/issues/5797 + deps = deps.map {|d| d.is_a?(Gem::Dependency) ? d : Gem::Dependency.new(*d) } + + deps + end end def git_version diff --git a/spec/commands/install_spec.rb b/spec/commands/install_spec.rb index 23dcdd1806..0e4d291210 100644 --- a/spec/commands/install_spec.rb +++ b/spec/commands/install_spec.rb @@ -324,6 +324,30 @@ RSpec.describe "bundle install with gem sources" do expect(out).not_to include("file://") end + it "fails gracefully when downloading an invalid specification from the full index", :rubygems => "2.5" do + build_repo2 do + build_gem "ajp-rails", "0.0.0", :gemspec => false, :skip_validation => true do |s| + bad_deps = [["ruby-ajp", ">= 0.2.0"], ["rails", ">= 0.14"]] + s. + instance_variable_get(:@spec). + instance_variable_set(:@dependencies, bad_deps) + + raise "failed to set bad deps" unless s.dependencies == bad_deps + end + build_gem "ruby-ajp", "1.0.0" + end + + install_gemfile <<-G, :full_index => true + source "file://#{gem_repo2}" + + gem "ajp-rails", "0.0.0" + G + + expect(last_command.stdboth).not_to match(/Error Report/i) + expect(last_command.bundler_err).to include("An error occurred while installing ajp-rails (0.0.0), and Bundler cannot continue."). + and include("Make sure that `gem install ajp-rails -v '0.0.0'` succeeds before bundling.") + end + it "doesn't blow up when the local .bundle/config is empty" do FileUtils.mkdir_p(bundled_app(".bundle")) FileUtils.touch(bundled_app(".bundle/config")) |