summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndré Arko <mail@arko.net>2015-01-28 19:01:21 -0800
committerTim Moore <tmoore@incrementalism.net>2015-02-07 15:01:54 +1100
commit0514a3e9ce60fc560220ff11fc972943cdc1d642 (patch)
tree3733bedb97b113548d020a830d8534bb1397dd29
parentec0c5cd89b115cf5d36aeb0fc6d9896d1346d34a (diff)
downloadbundler-0514a3e9ce60fc560220ff11fc972943cdc1d642.tar.gz
Merge pull request #3365 from keiths-osc/api_source_index_fix
Api source index fix
-rw-r--r--lib/bundler/index.rb10
-rw-r--r--lib/bundler/source/rubygems.rb12
-rw-r--r--spec/install/gems/dependency_api_spec.rb24
-rw-r--r--spec/support/artifice/endpoint.rb10
-rw-r--r--spec/support/artifice/endpoint_extra_api.rb32
-rw-r--r--spec/support/builders.rb6
-rw-r--r--spec/support/path.rb4
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