diff options
author | The Bundler Bot <bot@bundler.io> | 2017-02-18 16:46:06 +0000 |
---|---|---|
committer | The Bundler Bot <bot@bundler.io> | 2017-02-18 16:46:06 +0000 |
commit | 42215fe7279bd90d48f2d4e09227d327e007b5bc (patch) | |
tree | 0011a9f2ea7a395e33d2cb7e33aa0a615cedc327 /lib/bundler | |
parent | cc4414ca7cfe76989ecbefec8408e2c26cdaf71d (diff) | |
parent | fe0fdb108b9a72889383b99d98dd8e58ae75a557 (diff) | |
download | bundler-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.rb | 7 | ||||
-rw-r--r-- | lib/bundler/errors.rb | 1 | ||||
-rw-r--r-- | lib/bundler/installer/gem_installer.rb | 2 | ||||
-rw-r--r-- | lib/bundler/lazy_specification.rb | 9 | ||||
-rw-r--r-- | lib/bundler/remote_specification.rb | 7 | ||||
-rw-r--r-- | lib/bundler/source/rubygems/remote.rb | 4 |
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) |