summaryrefslogtreecommitdiff
path: root/lib/bundler
diff options
context:
space:
mode:
authorThe Bundler Bot <bot@bundler.io>2017-02-18 16:46:06 +0000
committerThe Bundler Bot <bot@bundler.io>2017-02-18 16:46:06 +0000
commit42215fe7279bd90d48f2d4e09227d327e007b5bc (patch)
tree0011a9f2ea7a395e33d2cb7e33aa0a615cedc327 /lib/bundler
parentcc4414ca7cfe76989ecbefec8408e2c26cdaf71d (diff)
parentfe0fdb108b9a72889383b99d98dd8e58ae75a557 (diff)
downloadbundler-42215fe7279bd90d48f2d4e09227d327e007b5bc.tar.gz
Auto merge of #5427 - bundler:seg-api-missing-dependencies, r=indirect
Fail gracefully when installing a spec where the API is missing deps Fixes https://github.com/bundler/bundler/issues/5426 Closes https://github.com/bundler/bundler/issues/5339
Diffstat (limited to 'lib/bundler')
-rw-r--r--lib/bundler/endpoint_specification.rb7
-rw-r--r--lib/bundler/errors.rb1
-rw-r--r--lib/bundler/installer/gem_installer.rb2
-rw-r--r--lib/bundler/lazy_specification.rb9
-rw-r--r--lib/bundler/remote_specification.rb7
-rw-r--r--lib/bundler/source/rubygems/remote.rb4
6 files changed, 28 insertions, 2 deletions
diff --git a/lib/bundler/endpoint_specification.rb b/lib/bundler/endpoint_specification.rb
index 4f5377d3cc..5e14f03265 100644
--- a/lib/bundler/endpoint_specification.rb
+++ b/lib/bundler/endpoint_specification.rb
@@ -91,6 +91,13 @@ module Bundler
end
def __swap__(spec)
+ without_type = proc {|d| Gem::Dependency.new(d.name, d.requirements_list.sort) }
+ if (extra_deps = spec.runtime_dependencies.map(&without_type).-(dependencies.map(&without_type))) && extra_deps.any?
+ Bundler.ui.debug "#{full_name} from #{remote} has corrupted API dependencies (API returned #{dependencies}, real spec has (#{spec.runtime_dependencies}))"
+ raise APIResponseMismatchError,
+ "Downloading #{full_name} revealed dependencies not in the API (#{extra_deps.map(&:to_s).join(", ")})." \
+ "\nInstalling with `--full-index` should fix the problem."
+ end
@remote_specification = spec
end
diff --git a/lib/bundler/errors.rb b/lib/bundler/errors.rb
index ecd9260ea0..9ef1286936 100644
--- a/lib/bundler/errors.rb
+++ b/lib/bundler/errors.rb
@@ -54,6 +54,7 @@ module Bundler
class PluginError < BundlerError; status_code(29); end
class SudoNotPermittedError < BundlerError; status_code(30); end
class ThreadCreationError < BundlerError; status_code(33); end
+ class APIResponseMismatchError < BundlerError; status_code(34); end
class GemfileEvalError < GemfileError; end
class MarshalError < StandardError; end
diff --git a/lib/bundler/installer/gem_installer.rb b/lib/bundler/installer/gem_installer.rb
index b6eb221389..0589d14e40 100644
--- a/lib/bundler/installer/gem_installer.rb
+++ b/lib/bundler/installer/gem_installer.rb
@@ -16,7 +16,7 @@ module Bundler
Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}"
generate_executable_stubs
return true, post_install_message
- rescue Bundler::InstallHookError, Bundler::SecurityError
+ rescue Bundler::InstallHookError, Bundler::SecurityError, APIResponseMismatchError
raise
rescue Errno::ENOSPC
return false, out_of_space_message
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb
index ed21a9aad4..adafa42342 100644
--- a/lib/bundler/lazy_specification.rb
+++ b/lib/bundler/lazy_specification.rb
@@ -72,7 +72,14 @@ module Bundler
@specification = if source.is_a?(Source::Gemspec) && source.gemspec.name == name
source.gemspec.tap {|s| s.source = source }
else
- source.specs.search(search_object).last
+ search = source.specs.search(search_object).last
+ if search && search.platform != platform && !search.runtime_dependencies.-(dependencies.reject {|d| d.type == :development }).empty?
+ Bundler.ui.warn "Unable to use the platform-specific (#{search.platform}) version of #{name} (#{version}) " \
+ "because it has different dependencies from the #{platform} version. " \
+ "To use the platform-specific version of the gem, run `bundle config specific_platform true` and install again."
+ search = source.specs.search(self).last
+ end
+ search
end
end
diff --git a/lib/bundler/remote_specification.rb b/lib/bundler/remote_specification.rb
index 944ff1adbd..e5f9c78b00 100644
--- a/lib/bundler/remote_specification.rb
+++ b/lib/bundler/remote_specification.rb
@@ -49,6 +49,13 @@ module Bundler
# once the remote gem is downloaded, the backend specification will
# be swapped out.
def __swap__(spec)
+ without_type = proc {|d| Gem::Dependency.new(d.name, d.requirements_list) }
+ if (extra_deps = spec.runtime_dependencies.map(&without_type).-(dependencies.map(&without_type))) && extra_deps.any?
+ Bundler.ui.debug "#{full_name} from #{remote} has corrupted API dependencies (API returned #{dependencies}, real spec has (#{spec.runtime_dependencies}))"
+ raise APIResponseMismatchError,
+ "Downloading #{full_name} revealed dependencies not in the API (#{extra_deps.map(&without_type).map(&:to_s).join(", ")})." \
+ "\nInstalling with `--full-index` should fix the problem."
+ end
@_remote_specification = spec
end
diff --git a/lib/bundler/source/rubygems/remote.rb b/lib/bundler/source/rubygems/remote.rb
index 92f8a40588..b49e645506 100644
--- a/lib/bundler/source/rubygems/remote.rb
+++ b/lib/bundler/source/rubygems/remote.rb
@@ -30,6 +30,10 @@ module Bundler
end
end
+ def to_s
+ "rubygems remote at #{anonymized_uri}"
+ end
+
private
def apply_auth(uri, auth)