diff options
author | Allen Zhao <cnallenzhao@gmail.com> | 2016-05-23 19:21:23 +0800 |
---|---|---|
committer | Allen Zhao <cnallenzhao@gmail.com> | 2016-05-24 09:31:53 +0800 |
commit | 5f1ec1113108428427c513299d610b844195578e (patch) | |
tree | e0b31a08063bc35f4f74d5963f871fa001a718e8 | |
parent | 8268b7ca58eb868afa4bffdcc62f0a1ec72d2478 (diff) | |
download | bundler-5f1ec1113108428427c513299d610b844195578e.tar.gz |
Handle yanked gems
-rw-r--r-- | lib/bundler/definition.rb | 19 | ||||
-rw-r--r-- | spec/install/yanked_spec.rb | 43 |
2 files changed, 60 insertions, 2 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 294d6567c6..a46f805378 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -137,8 +137,17 @@ module Bundler # @return [Bundler::SpecSet] def specs @specs ||= begin - specs = resolve.materialize(Bundler.settings[:cache_all_platforms] ? dependencies : requested_dependencies) - + begin + specs = resolve.materialize(Bundler.settings[:cache_all_platforms] ? dependencies : requested_dependencies) + rescue GemNotFound => e # Handle yanked gem + gem_name, gem_version = extract_gem_info(e) + locked_gem = @locked_specs[gem_name].last + raise if locked_gem.nil? || locked_gem.version.to_s != gem_version + raise GemNotFound, "Your bundle is locked to #{locked_gem}, but that version could not " \ + "be found in any of the sources listed in your Gemfile. If you haven't changed sources, " \ + "that means the author of #{locked_gem} has removed it. You'll need to update your bundle " \ + "to a different version of foo that hasn't been removed in order to install." + end unless specs["bundler"].any? local = Bundler.settings[:frozen] ? rubygems_index : index bundler = local.search(Gem::Dependency.new("bundler", VERSION)).last @@ -690,5 +699,11 @@ module Bundler end current == proposed end + + def extract_gem_info(error) + # This method will extract the error message like "Could not find foo-1.2.3 in any of the sources" + # to an array. The first element will be the gem name (e.g. foo), the second will be the version number. + error.message.scan(/Could not find (\w+)-(\d+(?:\.\d+)+)/).flatten + end end end diff --git a/spec/install/yanked_spec.rb b/spec/install/yanked_spec.rb new file mode 100644 index 0000000000..2f8af3fe5a --- /dev/null +++ b/spec/install/yanked_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true +require "spec_helper" + +describe "handle yanked" do + before(:each) do + build_repo4 do + build_gem "foo", "9.0.0" + end + end + + it "throws and error when there is gem yanked" do + lockfile <<-L + GEM + remote: file://#{gem_repo4} + specs: + foo (10.0.0) + + PLATFORMS + ruby + + DEPENDENCIES + foo (= 10.0.0) + + L + + install_gemfile <<-G + source "file://#{gem_repo4}" + gem "foo", "10.0.0" + G + + expect(out).to include("Your bundle is locked to foo (10.0.0)") + end + + it "throws the original error when manually enter a version number that doesn't exist" do + install_gemfile <<-G + source "file://#{gem_repo4}" + gem "foo", "10.0.0" + G + + expect(out).not_to include("Your bundle is locked to foo (10.0.0)") + expect(out).to include("Could not find gem 'foo (= 10.0.0)' in any of the gem sources") + end +end
\ No newline at end of file |