diff options
author | André Arko <mail@arko.net> | 2015-01-28 19:01:21 -0800 |
---|---|---|
committer | Tim Moore <tmoore@incrementalism.net> | 2015-02-07 15:01:54 +1100 |
commit | 0514a3e9ce60fc560220ff11fc972943cdc1d642 (patch) | |
tree | 3733bedb97b113548d020a830d8534bb1397dd29 | |
parent | ec0c5cd89b115cf5d36aeb0fc6d9896d1346d34a (diff) | |
download | bundler-0514a3e9ce60fc560220ff11fc972943cdc1d642.tar.gz |
Merge pull request #3365 from keiths-osc/api_source_index_fix
Api source index fix
-rw-r--r-- | lib/bundler/index.rb | 10 | ||||
-rw-r--r-- | lib/bundler/source/rubygems.rb | 12 | ||||
-rw-r--r-- | spec/install/gems/dependency_api_spec.rb | 24 | ||||
-rw-r--r-- | spec/support/artifice/endpoint.rb | 10 | ||||
-rw-r--r-- | spec/support/artifice/endpoint_extra_api.rb | 32 | ||||
-rw-r--r-- | spec/support/builders.rb | 6 | ||||
-rw-r--r-- | spec/support/path.rb | 4 |
7 files changed, 90 insertions, 8 deletions
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb index e9fc09fea5..30f1940323 100644 --- a/lib/bundler/index.rb +++ b/lib/bundler/index.rb @@ -106,13 +106,17 @@ module Bundler # returns a list of the dependencies def unmet_dependency_names - names = [] - each{|s| names.push(*s.dependencies.map{|d| d.name }) } - names.uniq! + names = dependency_names names.delete_if{|n| n == "bundler" } names.select{|n| search(n).empty? } end + def dependency_names + names = [] + each{|s| names.push(*s.dependencies.map{|d| d.name }) } + names.uniq + end + def use(other, override_dupes = false) return unless other other.each do |s| diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb index 2f1d7410cc..01d83a5773 100644 --- a/lib/bundler/source/rubygems.rb +++ b/lib/bundler/source/rubygems.rb @@ -302,6 +302,18 @@ module Bundler Bundler.ui.info "" if !Bundler.ui.debug? # new line now that the dots are over end + # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both + # sources A and B. At this point, the API request will have found all the versions of Bar in source A, + # but will not have found any versions of Bar from source B, which is a problem if the requested version + # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for + # each spec we found, we add all possible versions from all sources to the index. + begin + idxcount = idx.size + api_fetchers.each do |f| + idx.use f.specs(idx.dependency_names, self), true + end + end until idxcount == idx.size + if api_fetchers.any? && api_fetchers.all?{|f| f.use_api } # it's possible that gems from one source depend on gems from some # other source, so now we download gemspecs and iterate over those diff --git a/spec/install/gems/dependency_api_spec.rb b/spec/install/gems/dependency_api_spec.rb index 70739258a0..a29efe87cf 100644 --- a/spec/install/gems/dependency_api_spec.rb +++ b/spec/install/gems/dependency_api_spec.rb @@ -259,6 +259,30 @@ describe "gemcutter's dependency API" do should_be_installed "back_deps 1.0" end + it "considers all possible versions of dependencies from all api gem sources" do + # In this scenario, the gem "somegem" only exists in repo4. It depends on specific version of activesupport that + # exists only in repo1. There happens also be a version of activesupport in repo4, but not the one that version 1.0.0 + # of somegem wants. This test makes sure that bundler actually finds version 1.2.3 of active support in the other + # repo and installs it. + build_repo4 do + build_gem "activesupport", "1.2.0" + build_gem "somegem", "1.0.0" do |s| + s.add_dependency "activesupport", "1.2.3" #This version exists only in repo1 + end + end + + gemfile <<-G + source "#{source_uri}" + source "#{source_uri}/extra" + gem 'somegem', '1.0.0' + G + + bundle :install, :artifice => "endpoint_extra_api" + + should_be_installed "somegem 1.0.0" + should_be_installed "activesupport 1.2.3" + end + it "prints API output properly with back deps" do build_repo2 do build_gem "back_deps" do |s| diff --git a/spec/support/artifice/endpoint.rb b/spec/support/artifice/endpoint.rb index 68b41b7528..adff4a7bcd 100644 --- a/spec/support/artifice/endpoint.rb +++ b/spec/support/artifice/endpoint.rb @@ -14,14 +14,14 @@ require 'sinatra/base' class Endpoint < Sinatra::Base helpers do - def dependencies_for(gem_names, marshal = gem_repo1("specs.4.8")) + def dependencies_for(gem_names, gem_repo = gem_repo1) return [] if gem_names.nil? || gem_names.empty? require 'rubygems' require 'bundler' Bundler::Deprecate.skip_during do - Marshal.load(File.open(marshal).read).map do |name, version, platform| - spec = load_spec(name, version, platform) + Marshal.load(File.open(gem_repo.join("specs.4.8")).read).map do |name, version, platform| + spec = load_spec(name, version, platform, gem_repo) if gem_names.include?(spec.name) { :name => spec.name, @@ -36,10 +36,10 @@ class Endpoint < Sinatra::Base end end - def load_spec(name, version, platform) + def load_spec(name, version, platform, gem_repo) full_name = "#{name}-#{version}" full_name += "-#{platform}" if platform != "ruby" - Marshal.load(Gem.inflate(File.open(gem_repo1("quick/Marshal.4.8/#{full_name}.gemspec.rz")).read)) + Marshal.load(Gem.inflate(File.open(gem_repo.join("quick/Marshal.4.8/#{full_name}.gemspec.rz")).read)) end end diff --git a/spec/support/artifice/endpoint_extra_api.rb b/spec/support/artifice/endpoint_extra_api.rb new file mode 100644 index 0000000000..d6d1c5a1b4 --- /dev/null +++ b/spec/support/artifice/endpoint_extra_api.rb @@ -0,0 +1,32 @@ +require File.expand_path("../endpoint", __FILE__) + +Artifice.deactivate + +class EndpointExtraApi < Endpoint + get "/extra/api/v1/dependencies" do + deps = dependencies_for(params[:gems], gem_repo4) + Marshal.dump(deps) + end + + get "/extra/specs.4.8.gz" do + File.read("#{gem_repo4}/specs.4.8.gz") + end + + get "/extra/prerelease_specs.4.8.gz" do + File.read("#{gem_repo4}/prerelease_specs.4.8.gz") + end + + get "/extra/quick/Marshal.4.8/:id" do + redirect "/extra/fetch/actual/gem/#{params[:id]}" + end + + get "/extra/fetch/actual/gem/:id" do + File.read("#{gem_repo4}/quick/Marshal.4.8/#{params[:id]}") + end + + get "/extra/gems/:id" do + File.read("#{gem_repo4}/gems/#{params[:id]}") + end +end + +Artifice.activate_with(EndpointExtraApi) diff --git a/spec/support/builders.rb b/spec/support/builders.rb index a49cda81da..f4bb9e02ef 100644 --- a/spec/support/builders.rb +++ b/spec/support/builders.rb @@ -260,6 +260,12 @@ module Spec FileUtils.rm_rf Dir[gem_repo3("prerelease*")] end + # A repo that has no pre-installed gems included. (The caller completely determines the contents with the block) + def build_repo4(&blk) + FileUtils.rm_rf gem_repo4 + build_repo(gem_repo4, &blk) + end + def update_repo2 update_repo gem_repo2 do build_gem "rack", "1.2" do |s| diff --git a/spec/support/path.rb b/spec/support/path.rb index 74dbd891a5..56e8dd8b41 100644 --- a/spec/support/path.rb +++ b/spec/support/path.rb @@ -60,6 +60,10 @@ module Spec tmp("gems/remote3", *args) end + def gem_repo4(*args) + tmp("gems/remote4", *args) + end + def security_repo(*args) tmp("gems/security_repo", *args) end |