summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllen Zhao <cnallenzhao@gmail.com>2016-05-23 19:21:23 +0800
committerAllen Zhao <cnallenzhao@gmail.com>2016-05-24 09:31:53 +0800
commit5f1ec1113108428427c513299d610b844195578e (patch)
treee0b31a08063bc35f4f74d5963f871fa001a718e8
parent8268b7ca58eb868afa4bffdcc62f0a1ec72d2478 (diff)
downloadbundler-5f1ec1113108428427c513299d610b844195578e.tar.gz
Handle yanked gems
-rw-r--r--lib/bundler/definition.rb19
-rw-r--r--spec/install/yanked_spec.rb43
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