summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHomu <homu@barosl.com>2016-06-29 08:17:33 +0900
committerHomu <homu@barosl.com>2016-06-29 08:17:33 +0900
commitc5e161a2ea28feef7a1314dcfd03d0d54d1e4f1c (patch)
treec52b489a8d31653b374bbec9d5debbbdfedd78d4
parentbd8982c525bd79302d4551e1ad0053722de4b0b6 (diff)
parentbaa71129d0b9db353fd95f667e050f3839ef1cdb (diff)
downloadbundler-c5e161a2ea28feef7a1314dcfd03d0d54d1e4f1c.tar.gz
Auto merge of #4714 - bundler:seg-no-aggregate, r=indirect
[2.0] Remove RubyGems Aggregate & support transitive source pinning Closes https://github.com/bundler/bundler/issues/3671. Closes https://github.com/bundler/bundler/pull/3696. Closes #4059.
-rw-r--r--lib/bundler/definition.rb45
-rw-r--r--lib/bundler/dsl.rb16
-rw-r--r--lib/bundler/fetcher/downloader.rb2
-rw-r--r--lib/bundler/index.rb1
-rw-r--r--lib/bundler/lockfile_parser.rb30
-rw-r--r--lib/bundler/resolver.rb63
-rw-r--r--lib/bundler/rubygems_ext.rb2
-rw-r--r--lib/bundler/source.rb6
-rw-r--r--lib/bundler/source/rubygems.rb88
-rw-r--r--lib/bundler/source_list.rb36
-rw-r--r--lib/bundler/stub_specification.rb4
-rw-r--r--spec/bundler/fetcher/downloader_spec.rb2
-rw-r--r--spec/bundler/source_list_spec.rb78
-rw-r--r--spec/cache/gems_spec.rb3
-rw-r--r--spec/commands/exec_spec.rb3
-rw-r--r--spec/commands/lock_spec.rb3
-rw-r--r--spec/install/gemfile/git_spec.rb6
-rw-r--r--spec/install/gemfile/path_spec.rb10
-rw-r--r--spec/install/gemfile/sources_spec.rb229
-rw-r--r--spec/install/gems/compact_index_spec.rb7
-rw-r--r--spec/install/gems/resolving_spec.rb12
-rw-r--r--spec/install/post_bundle_message_spec.rb5
-rw-r--r--spec/lock/lockfile_spec.rb130
-rw-r--r--spec/resolver/basic_spec.rb2
-rw-r--r--spec/runtime/inline_spec.rb30
-rw-r--r--spec/runtime/require_spec.rb78
-rw-r--r--spec/runtime/setup_spec.rb6
-rw-r--r--spec/support/indexes.rb5
-rw-r--r--spec/update/git_spec.rb10
29 files changed, 595 insertions, 317 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index 275f4ee8ac..ab754ae24d 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -218,6 +218,27 @@ module Bundler
dependency_names -= pinned_spec_names(source.specs)
dependency_names.push(*source.unmet_deps).uniq!
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.
+ loop do
+ idxcount = idx.size
+ sources.all_sources.each do |source|
+ names = :names # do this so we only have to traverse to get dependency_names from the index once
+ unmet_dependency_names = proc do
+ if names == :names
+ names = dependency_names.+(idx.dependency_names).uniq unless idx.size > Source::Rubygems::API_REQUEST_LIMIT
+ else
+ names
+ end
+ end
+ source.double_check_for(unmet_dependency_names, :override_dupes)
+ end
+ break if idxcount == idx.size
+ end
end
end
@@ -225,8 +246,8 @@ module Bundler
# spec, even if (say) a git gem is not checked out.
def rubygems_index
@rubygems_index ||= Index.build do |idx|
- sources.rubygems_sources.each do |rubygems|
- idx.add_source rubygems.specs
+ sources.rubygems_sources.each do |s|
+ idx.add_source s.specs
end
end
end
@@ -496,19 +517,6 @@ module Bundler
def converge_sources
changes = false
- # Get the Rubygems sources from the gems.locked
- locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
- # Get the Rubygems remotes from the gems.rb
- actual_remotes = sources.rubygems_remotes
-
- # If there is a Rubygems source in both
- if !locked_gem_sources.empty? && !actual_remotes.empty?
- locked_gem_sources.each do |locked_gem|
- # Merge the remotes from the gems.rb into the gems.locked
- changes |= locked_gem.replace_remotes(actual_remotes)
- end
- end
-
# Replace the sources from the gems.rb with the sources from the gems.locked,
# if they exist in the gems.locked and are `==`. If you can't find an equivalent
# source in the gems.locked, use the one from the gems.rb.
@@ -654,10 +662,11 @@ module Bundler
# Record the specs available in each gem's source, so that those
# specs will be available later when the resolver knows where to
# look for that gemspec (or its dependencies)
- source_requirements = {}
+ default = sources.default_source
+ source_requirements = { :default => default }
dependencies.each do |dep|
- next unless dep.source
- source_requirements[dep.name] = dep.source.specs
+ next unless source = dep.source || default
+ source_requirements[dep.name] = source
end
source_requirements
end
diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb
index aaa0eab06d..abfa1337ab 100644
--- a/lib/bundler/dsl.rb
+++ b/lib/bundler/dsl.rb
@@ -132,7 +132,7 @@ module Bundler
with_source(@sources.add_rubygems_source("remotes" => source), &blk)
else
check_primary_source_safety(@sources)
- @sources.add_rubygems_remote(source)
+ @sources.global_rubygems_remote = source
end
end
@@ -150,6 +150,16 @@ module Bundler
end
def path(path, options = {}, &blk)
+ unless block_given?
+ msg = "You can no longer specify a path source by itself. Instead, \n" \
+ "either use the :path option on a gem, or specify the gems that \n" \
+ "bundler should find in the path source by passing a block to \n" \
+ "the path method, like: \n\n" \
+ " path 'dir/containing/rails' do\n" \
+ " gem 'rails'\n" \
+ " end"
+ raise DeprecatedError, msg
+ end
source_options = normalize_hash(options).merge("path" => Pathname.new(path), "root_path" => gemfile_root)
source = @sources.add_path_source(source_options)
with_source(source, &blk)
@@ -384,8 +394,8 @@ module Bundler
end
end
- def check_primary_source_safety(source)
- return unless source.rubygems_primary_remotes.any?
+ def check_primary_source_safety(source_list)
+ return if source_list.global_rubygems_source.nil?
raise GemspecError, "This #{SharedHelpers.gemfile_name} contains multiple primary sources. " \
"Each source after the first must include a block to indicate which gems " \
diff --git a/lib/bundler/fetcher/downloader.rb b/lib/bundler/fetcher/downloader.rb
index 204e33387e..5a638a4b27 100644
--- a/lib/bundler/fetcher/downloader.rb
+++ b/lib/bundler/fetcher/downloader.rb
@@ -31,7 +31,7 @@ module Bundler
when Net::HTTPUnauthorized
raise AuthenticationRequiredError, uri.host
when Net::HTTPNotFound
- raise FallbackError, "Net::HTTPNotFound"
+ raise FallbackError, "Net::HTTPNotFound (#{uri})"
else
raise HTTPError, "#{response.class}#{": #{response.body}" unless response.body.empty?}"
end
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
index f2defe1cff..833276b251 100644
--- a/lib/bundler/index.rb
+++ b/lib/bundler/index.rb
@@ -98,6 +98,7 @@ module Bundler
specs.values.each do |spec_sets|
spec_sets.values.each(&blk)
end
+ sources.each {|s| s.each(&blk) }
end
# returns a list of the dependencies
diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb
index 5d450fcefc..57e6372f02 100644
--- a/lib/bundler/lockfile_parser.rb
+++ b/lib/bundler/lockfile_parser.rb
@@ -62,8 +62,6 @@ module Bundler
@state = nil
@specs = {}
- @rubygems_aggregate = Source::Rubygems.new
-
if lockfile.match(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/)
raise LockfileError, "Your #{SharedHelpers.lockfile_name} contains merge conflicts.\n" \
"Run `git checkout HEAD -- #{SharedHelpers.lockfile_name}` first to get a clean lock."
@@ -87,7 +85,6 @@ module Bundler
send("parse_#{@state}", line)
end
end
- @sources << @rubygems_aggregate
@specs = @specs.values
warn_for_outdated_bundler_version
rescue ArgumentError => e
@@ -129,23 +126,10 @@ module Bundler
@type = line
when SPECS
case @type
- when PATH
- @current_source = TYPES[@type].from_lock(@opts)
- @sources << @current_source
- when GIT
- @current_source = TYPES[@type].from_lock(@opts)
- # Strip out duplicate GIT sections
- if @sources.include?(@current_source)
- @current_source = @sources.find {|s| s == @current_source }
- else
- @sources << @current_source
- end
when GEM
- Array(@opts["remote"]).each do |url|
- @rubygems_aggregate.add_remote(url)
- end
- @current_source = @rubygems_aggregate
+ @opts["remotes"] = @opts.delete("remote")
end
+ add_source(TYPES[@type].from_lock(@opts))
when OPTIONS
value = $2
value = true if value == "true"
@@ -164,6 +148,16 @@ module Bundler
end
end
+ def add_source(source)
+ # Strip out duplicate sections
+ if @sources.include?(source) && !source.instance_of?(Bundler::Source::Path)
+ @current_source = @sources.find {|s| s == @current_source }
+ else
+ @current_source = source
+ @sources << @current_source
+ end
+ end
+
NAME_VERSION = '(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?'.freeze
NAME_VERSION_2 = /^ {2}#{NAME_VERSION}(!)?$/
NAME_VERSION_4 = /^ {4}#{NAME_VERSION}$/
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index 742087b206..3c5d2bc462 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -54,11 +54,20 @@ module Bundler
o << %(the gems in your #{SharedHelpers.gemfile_name}, which may resolve the conflict.\n)
elsif !conflict.existing
o << "\n"
+
+ relevant_sources = if conflict.requirement.source
+ [conflict.requirement.source]
+ elsif conflict.requirement.all_sources
+ conflict.requirement.all_sources
+ else
+ raise "no source set for #{conflict}"
+ end.compact.uniq
+
if conflict.requirement_trees.first.size > 1
- o << "Could not find gem '#{conflict.requirement}', which is required by "
- o << "gem '#{conflict.requirement_trees.first[-2]}', in any of the sources."
+ o << "Could not find gem '#{printable_dep(conflict.requirement)}', which is required by "
+ o << "gem '#{printable_dep(conflict.requirement_trees.first[-2])}', in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
else
- o << "Could not find gem '#{conflict.requirement}' in any of the sources\n"
+ o << "Could not find gem '#{printable_dep(conflict.requirement)}' in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
end
end
o
@@ -259,7 +268,17 @@ module Bundler
platform = dependency.__platform
dependency = dependency.dep unless dependency.is_a? Gem::Dependency
search = @search_for[dependency] ||= begin
- index = @source_requirements[dependency.name] || @index
+ index = Index.build do |idx|
+ if source = @source_requirements[dependency.name]
+ idx.add_source source.specs
+ elsif dependency.all_sources
+ dependency.all_sources.each {|s| idx.add_source(s.specs) if s }
+ else
+ idx.add_source @source_requirements[:default].specs
+ end
+ end
+ # source = @source_requirements[dependency.name]
+ # index = (source && source.specs) || @index
results = index.search(dependency, @base[dependency.name])
if vertex = @base_dg.vertex_named(dependency.name)
locked_requirement = vertex.payload.requirement
@@ -303,8 +322,19 @@ module Bundler
requirement.matches_spec?(spec)
end
+ def relevant_sources_for_vertex(vertex)
+ if vertex.root?
+ [@source_requirements[vertex.name]]
+ else
+ vertex.recursive_predecessors.map do |v|
+ @source_requirements[v.name]
+ end << @source_requirements[:default]
+ end
+ end
+
def sort_dependencies(dependencies, activated, conflicts)
dependencies.sort_by do |dependency|
+ dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
name = name_for(dependency)
[
activated.vertex_named(name).payload ? 0 : 1,
@@ -336,26 +366,26 @@ module Bundler
def verify_gemfile_dependencies_are_found!(requirements)
requirements.each do |requirement|
- next if requirement.name == "bundler"
+ name = requirement.name
+ next if name == "bundler"
next unless search_for(requirement).empty?
- if (base = @base[requirement.name]) && !base.empty?
+ if (base = @base[name]) && !base.empty?
version = base.first.version
message = "You have requested:\n" \
- " #{requirement.name} #{requirement.requirement}\n\n" \
- "The bundle currently has #{requirement.name} locked at #{version}.\n" \
- "Try running `bundle update #{requirement.name}`\n\n" \
+ " #{name} #{requirement.requirement}\n\n" \
+ "The bundle currently has #{name} locked at #{version}.\n" \
+ "Try running `bundle update #{name}`\n\n" \
"If you are updating multiple gems in your Gemfile at once,\n" \
"try passing them all to `bundle update`"
- elsif requirement.source
- name = requirement.name
- specs = @source_requirements[name][name]
+ elsif source = @source_requirements[name]
+ specs = source.specs[name]
versions_with_platforms = specs.map {|s| [s.version, s.platform] }
- message = String.new("Could not find gem '#{requirement}' in #{requirement.source}.\n")
+ message = String.new("Could not find gem '#{requirement}' in #{source}.\n")
message << if versions_with_platforms.any?
- "Source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
+ "The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
else
- "Source does not contain any versions of '#{requirement}'"
+ "The source does not contain any versions of '#{requirement}'."
end
else
message = "Could not find gem '#{requirement}' in any of the gem sources " \
@@ -370,7 +400,8 @@ module Bundler
version = vwp.first
platform = vwp.last
version_platform_str = String.new(version.to_s)
- version_platform_str << " #{platform}" unless platform.nil?
+ version_platform_str << " #{platform}" unless platform.nil? || platform == Gem::Platform::RUBY
+ version_platform_str
end
version_platform_strs.join(", ")
end
diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb
index 2f36c29cd9..94f502ad51 100644
--- a/lib/bundler/rubygems_ext.rb
+++ b/lib/bundler/rubygems_ext.rb
@@ -112,7 +112,7 @@ module Gem
end
class Dependency
- attr_accessor :source, :groups
+ attr_accessor :source, :groups, :all_sources
alias_method :eql?, :==
diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb
index eee4ade45b..56ce30af10 100644
--- a/lib/bundler/source.rb
+++ b/lib/bundler/source.rb
@@ -29,6 +29,12 @@ module Bundler
spec.source == self
end
+ # it's possible that gems from one source depend on gems from some
+ # other source, so now we download gemspecs and iterate over those
+ # dependencies, looking for gems we don't have info on yet.
+ def double_check_for(*)
+ end
+
def include?(other)
other == self
end
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 6b09173130..602b4386a3 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -48,10 +48,6 @@ module Bundler
o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty?
end
- def can_lock?(spec)
- spec.source.is_a?(Rubygems)
- end
-
def options
{ "remotes" => @remotes.map(&:to_s) }
end
@@ -69,8 +65,12 @@ module Bundler
end
def to_s
- remote_names = remotes.map(&:to_s).join(", ")
- "rubygems repository #{remote_names}"
+ if remotes.empty?
+ "locally installed gems"
+ else
+ remote_names = remotes.map(&:to_s).join(", ")
+ "rubygems repository #{remote_names} or installed locally"
+ end
end
alias_method :name, :to_s
@@ -234,6 +234,20 @@ module Bundler
end
end
+ def double_check_for(unmet_dependency_names, override_dupes = false, index = specs)
+ return unless @allow_remote
+ raise ArgumentError, "missing index" unless index
+
+ return unless api_fetchers.any?
+
+ unmet_dependency_names = unmet_dependency_names.call
+ Bundler.ui.debug "#{self}: 2x check for #{unmet_dependency_names}"
+
+ return if unmet_dependency_names && unmet_dependency_names.empty?
+
+ fetch_names(api_fetchers, unmet_dependency_names, index, override_dupes)
+ end
+
protected
def credless_remotes
@@ -337,62 +351,28 @@ module Bundler
index_fetchers = fetchers - api_fetchers
# gather lists from non-api sites
- index_fetchers.each do |f|
- Bundler.ui.info "Fetching source index from #{f.uri}"
- idx.use f.specs_with_retry(nil, self)
- end
+ fetch_names(index_fetchers, nil, idx, false)
# because ensuring we have all the gems we need involves downloading
# the gemspecs of those gems, if the non-api sites contain more than
- # about 100 gems, we treat all sites as non-api for speed.
+ # about 500 gems, we treat all sites as non-api for speed.
allow_api = idx.size < API_REQUEST_LIMIT && dependency_names.size < API_REQUEST_LIMIT
Bundler.ui.debug "Need to query more than #{API_REQUEST_LIMIT} gems." \
" Downloading full index instead..." unless allow_api
- if allow_api
- api_fetchers.each do |f|
- Bundler.ui.info "Fetching gem metadata from #{f.uri}", Bundler.ui.debug?
- idx.use f.specs_with_retry(dependency_names, self)
- Bundler.ui.info "" unless 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.
- loop do
- idxcount = idx.size
- api_fetchers.each do |f|
- Bundler.ui.info "Fetching version metadata from #{f.uri}", Bundler.ui.debug?
- idx.use f.specs_with_retry(idx.dependency_names, self), true
- Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
- end
- break if idxcount == idx.size
- end
-
- if api_fetchers.any?
- # it's possible that gems from one source depend on gems from some
- # other source, so now we download gemspecs and iterate over those
- # dependencies, looking for gems we don't have info on yet.
- unmet = idx.unmet_dependency_names
-
- # if there are any cross-site gems we missed, get them now
- api_fetchers.each do |f|
- Bundler.ui.info "Fetching dependency metadata from #{f.uri}", Bundler.ui.debug?
- idx.use f.specs_with_retry(unmet, self)
- Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
- end if unmet.any?
- else
- allow_api = false
- end
- end
+ fetch_names(api_fetchers, allow_api && dependency_names, idx, false)
+ end
+ end
- unless allow_api
- api_fetchers.each do |f|
- Bundler.ui.info "Fetching source index from #{f.uri}"
- idx.use f.specs_with_retry(nil, self)
- end
+ def fetch_names(fetchers, dependency_names, index, override_dupes)
+ fetchers.each do |f|
+ if dependency_names
+ Bundler.ui.info "Fetching gem metadata from #{f.uri}", Bundler.ui.debug?
+ index.use f.specs_with_retry(dependency_names, self), override_dupes
+ Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
+ else
+ Bundler.ui.info "Fetching source index from #{f.uri}"
+ index.use f.specs_with_retry(nil, self), override_dupes
end
end
end
diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb
index d1c3c8c170..d63c8129d1 100644
--- a/lib/bundler/source_list.rb
+++ b/lib/bundler/source_list.rb
@@ -4,13 +4,15 @@ require "set"
module Bundler
class SourceList
attr_reader :path_sources,
- :git_sources
+ :git_sources,
+ :global_rubygems_source
def initialize
- @path_sources = []
- @git_sources = []
- @rubygems_aggregate = Source::Rubygems.new
- @rubygems_sources = []
+ @path_sources = []
+ @git_sources = []
+ @global_rubygems_source = nil
+ @rubygems_local = Source::Rubygems.new
+ @rubygems_sources = []
end
def add_path_source(options = {})
@@ -27,13 +29,16 @@ module Bundler
add_source_to_list Source::Rubygems.new(options), @rubygems_sources
end
- def add_rubygems_remote(uri)
- @rubygems_aggregate.add_remote(uri)
- @rubygems_aggregate
+ def global_rubygems_remote=(uri)
+ @global_rubygems_source = Source::Rubygems.new("remotes" => uri)
+ end
+
+ def default_source
+ @global_rubygems_source || @rubygems_local
end
def rubygems_sources
- @rubygems_sources + [@rubygems_aggregate]
+ @rubygems_sources + [default_source]
end
def rubygems_remotes
@@ -44,13 +49,12 @@ module Bundler
path_sources + git_sources + rubygems_sources
end
- def get(source)
- source_list_for(source).find {|s| source == s }
+ def lock_sources
+ rubygems_sources.sort_by(&:to_s) + git_sources.sort_by(&:to_s) + path_sources.sort_by(&:to_s)
end
- def lock_sources
- lock_sources = (path_sources + git_sources).sort_by(&:to_s)
- lock_sources << combine_rubygems_sources
+ def get(source)
+ source_list_for(source).find {|s| source == s }
end
def replace_sources!(replacement_sources)
@@ -79,10 +83,6 @@ module Bundler
all_sources.each(&:remote!)
end
- def rubygems_primary_remotes
- @rubygems_aggregate.remotes
- end
-
private
def add_source_to_list(source, list)
diff --git a/lib/bundler/stub_specification.rb b/lib/bundler/stub_specification.rb
index f4ee7d0644..557852bdec 100644
--- a/lib/bundler/stub_specification.rb
+++ b/lib/bundler/stub_specification.rb
@@ -11,8 +11,8 @@ module Bundler
attr_accessor :stub
- def to_yaml
- _remote_specification.to_yaml
+ def encode_with(*args)
+ _remote_specification.encode_with(*args)
end
private
diff --git a/spec/bundler/fetcher/downloader_spec.rb b/spec/bundler/fetcher/downloader_spec.rb
index 04793d2a9c..f7631ef408 100644
--- a/spec/bundler/fetcher/downloader_spec.rb
+++ b/spec/bundler/fetcher/downloader_spec.rb
@@ -89,7 +89,7 @@ describe Bundler::Fetcher::Downloader do
let(:http_response) { Net::HTTPNotFound.new("1.1", 404, "Not Found") }
it "should raise a Bundler::Fetcher::FallbackError with Net::HTTPNotFound" do
- expect { subject.fetch(uri, options, counter) }.to raise_error(Bundler::Fetcher::FallbackError, "Net::HTTPNotFound")
+ expect { subject.fetch(uri, options, counter) }.to raise_error(Bundler::Fetcher::FallbackError, "Net::HTTPNotFound (#{uri})")
end
end
diff --git a/spec/bundler/source_list_spec.rb b/spec/bundler/source_list_spec.rb
index d724141bfa..d2395b30e4 100644
--- a/spec/bundler/source_list_spec.rb
+++ b/spec/bundler/source_list_spec.rb
@@ -8,8 +8,6 @@ describe Bundler::SourceList do
subject(:source_list) { Bundler::SourceList.new }
- let(:rubygems_aggregate) { Bundler::Source::Rubygems.new }
-
describe "adding sources" do
before do
source_list.add_path_source("path" => "/existing/path/to/gem")
@@ -108,36 +106,41 @@ describe Bundler::SourceList do
end
end
- describe "#add_rubygems_remote" do
+ describe "#global_rubygems_remote=" do
before do
- @returned_source = source_list.add_rubygems_remote("https://rubygems.org/")
+ source_list.global_rubygems_remote = "https://rubygems.org/"
+ @returned_source = source_list.global_rubygems_source
end
it "returns the aggregate rubygems source" do
expect(@returned_source).to be_instance_of(Bundler::Source::Rubygems)
+ expect(source_list.rubygems_sources).to end_with @returned_source
end
- it "adds the provided remote to the beginning of the aggregate source" do
- source_list.add_rubygems_remote("https://othersource.org")
- expect(@returned_source.remotes.first).to eq(URI("https://othersource.org/"))
+ it "resets the global source" do
+ source_list.global_rubygems_remote = "https://othersource.org"
+ new_global = source_list.global_rubygems_source
+ expect(new_global.remotes.first).to eq(URI("https://othersource.org/"))
+ expect(source_list.global_rubygems_source).to eq(new_global)
+ expect(source_list.rubygems_sources).not_to include(@returned_source)
end
end
end
describe "#all_sources" do
it "includes the aggregate rubygems source when rubygems sources have been added" do
- source_list.add_git_source("uri" => "git://host/path.git")
- source_list.add_rubygems_source("remotes" => ["https://rubygems.org"])
- source_list.add_path_source("path" => "/path/to/gem")
+ git = source_list.add_git_source("uri" => "git://host/path.git")
+ rubygems = source_list.add_rubygems_source("remotes" => ["https://rubygems.org"])
+ path = source_list.add_path_source("path" => "/path/to/gem")
- expect(source_list.all_sources).to include rubygems_aggregate
+ expect(source_list.all_sources).to include(git, rubygems, path)
end
it "includes the aggregate rubygems source when no rubygems sources have been added" do
source_list.add_git_source("uri" => "git://host/path.git")
source_list.add_path_source("path" => "/path/to/gem")
- expect(source_list.all_sources).to include rubygems_aggregate
+ expect(source_list.all_sources).to include source_list.default_source
end
it "returns sources of the same type in the reverse order that they were added" do
@@ -165,29 +168,29 @@ describe Bundler::SourceList do
Bundler::Source::Rubygems.new("remotes" => ["https://third-rubygems.org"]),
Bundler::Source::Rubygems.new("remotes" => ["https://fourth-rubygems.org"]),
Bundler::Source::Rubygems.new("remotes" => ["https://fifth-rubygems.org"]),
- rubygems_aggregate,
+ source_list.default_source,
]
end
end
describe "#path_sources" do
it "returns an empty array when no path sources have been added" do
- source_list.add_rubygems_remote("https://rubygems.org")
+ source_list.add_rubygems_source("remotes" => "https://rubygems.org")
source_list.add_git_source("uri" => "git://host/path.git")
expect(source_list.path_sources).to be_empty
end
it "returns path sources in the reverse order that they were added" do
source_list.add_git_source("uri" => "git://third-git.org/path.git")
- source_list.add_rubygems_remote("https://fifth-rubygems.org")
+ source_list.add_rubygems_source("remotes" => "https://fifth-rubygems.org")
source_list.add_path_source("path" => "/third/path/to/gem")
- source_list.add_rubygems_remote("https://fourth-rubygems.org")
+ source_list.add_rubygems_source("remotes" => "https://fourth-rubygems.org")
source_list.add_path_source("path" => "/second/path/to/gem")
- source_list.add_rubygems_remote("https://third-rubygems.org")
+ source_list.add_rubygems_source("remotes" => "https://third-rubygems.org")
source_list.add_git_source("uri" => "git://second-git.org/path.git")
- source_list.add_rubygems_remote("https://second-rubygems.org")
+ source_list.add_rubygems_source("remotes" => "https://second-rubygems.org")
source_list.add_path_source("path" => "/first/path/to/gem")
- source_list.add_rubygems_remote("https://first-rubygems.org")
+ source_list.add_rubygems_source("remotes" => "https://first-rubygems.org")
source_list.add_git_source("uri" => "git://first-git.org/path.git")
expect(source_list.path_sources).to eq [
@@ -200,7 +203,7 @@ describe Bundler::SourceList do
describe "#git_sources" do
it "returns an empty array when no git sources have been added" do
- source_list.add_rubygems_remote("https://rubygems.org")
+ source_list.add_rubygems_source("remotes" => "https://rubygems.org")
source_list.add_path_source("path" => "/path/to/gem")
expect(source_list.git_sources).to be_empty
@@ -208,15 +211,15 @@ describe Bundler::SourceList do
it "returns git sources in the reverse order that they were added" do
source_list.add_git_source("uri" => "git://third-git.org/path.git")
- source_list.add_rubygems_remote("https://fifth-rubygems.org")
+ source_list.add_rubygems_source("remotes" => "https://fifth-rubygems.org")
source_list.add_path_source("path" => "/third/path/to/gem")
- source_list.add_rubygems_remote("https://fourth-rubygems.org")
+ source_list.add_rubygems_source("remotes" => "https://fourth-rubygems.org")
source_list.add_path_source("path" => "/second/path/to/gem")
- source_list.add_rubygems_remote("https://third-rubygems.org")
+ source_list.add_rubygems_source("remotes" => "https://third-rubygems.org")
source_list.add_git_source("uri" => "git://second-git.org/path.git")
- source_list.add_rubygems_remote("https://second-rubygems.org")
+ source_list.add_rubygems_source("remotes" => "https://second-rubygems.org")
source_list.add_path_source("path" => "/first/path/to/gem")
- source_list.add_rubygems_remote("https://first-rubygems.org")
+ source_list.add_rubygems_source("remotes" => "https://first-rubygems.org")
source_list.add_git_source("uri" => "git://first-git.org/path.git")
expect(source_list.git_sources).to eq [
@@ -230,17 +233,17 @@ describe Bundler::SourceList do
describe "#rubygems_sources" do
it "includes the aggregate rubygems source when rubygems sources have been added" do
source_list.add_git_source("uri" => "git://host/path.git")
- source_list.add_rubygems_source("remotes" => ["https://rubygems.org"])
+ rg = source_list.add_rubygems_source("remotes" => ["https://rubygems.org"])
source_list.add_path_source("path" => "/path/to/gem")
- expect(source_list.rubygems_sources).to include rubygems_aggregate
+ expect(source_list.rubygems_sources).to end_with(rg, source_list.default_source)
end
it "returns only the aggregate rubygems source when no rubygems sources have been added" do
source_list.add_git_source("uri" => "git://host/path.git")
source_list.add_path_source("path" => "/path/to/gem")
- expect(source_list.rubygems_sources).to eq [rubygems_aggregate]
+ expect(source_list.rubygems_sources).to eq [source_list.default_source]
end
it "returns rubygems sources in the reverse order that they were added" do
@@ -262,7 +265,7 @@ describe Bundler::SourceList do
Bundler::Source::Rubygems.new("remotes" => ["https://third-rubygems.org"]),
Bundler::Source::Rubygems.new("remotes" => ["https://fourth-rubygems.org"]),
Bundler::Source::Rubygems.new("remotes" => ["https://fifth-rubygems.org"]),
- rubygems_aggregate,
+ source_list.default_source,
]
end
end
@@ -270,7 +273,7 @@ describe Bundler::SourceList do
describe "#get" do
context "when it includes an equal source" do
let(:rubygems_source) { Bundler::Source::Rubygems.new("remotes" => ["https://rubygems.org"]) }
- before { @equal_source = source_list.add_rubygems_remote("https://rubygems.org") }
+ before { @equal_source = source_list.add_rubygems_source("remotes" => "https://rubygems.org") }
it "returns the equal source" do
expect(source_list.get(rubygems_source)).to be @equal_source
@@ -301,18 +304,17 @@ describe Bundler::SourceList do
source_list.add_git_source("uri" => "git://first-git.org/path.git")
expect(source_list.lock_sources).to eq [
+ Bundler::Source::Rubygems.new,
+ Bundler::Source::Rubygems.new("remotes" => "https://duplicate-rubygems.org"),
+ Bundler::Source::Rubygems.new("remotes" => "https://first-rubygems.org"),
+ Bundler::Source::Rubygems.new("remotes" => "https://second-rubygems.org"),
+ Bundler::Source::Rubygems.new("remotes" => "https://third-rubygems.org"),
Bundler::Source::Git.new("uri" => "git://first-git.org/path.git"),
Bundler::Source::Git.new("uri" => "git://second-git.org/path.git"),
Bundler::Source::Git.new("uri" => "git://third-git.org/path.git"),
Bundler::Source::Path.new("path" => "/first/path/to/gem"),
Bundler::Source::Path.new("path" => "/second/path/to/gem"),
Bundler::Source::Path.new("path" => "/third/path/to/gem"),
- Bundler::Source::Rubygems.new("remotes" => [
- "https://duplicate-rubygems.org",
- "https://first-rubygems.org",
- "https://second-rubygems.org",
- "https://third-rubygems.org",
- ]),
]
end
end
@@ -343,7 +345,7 @@ describe Bundler::SourceList do
end
describe "#cached!" do
- let(:rubygems_source) { source_list.add_rubygems_remote("https://rubygems.org") }
+ let(:rubygems_source) { source_list.add_rubygems_source("remotes" => "https://rubygems.org") }
let(:git_source) { source_list.add_git_source("uri" => "git://host/path.git") }
let(:path_source) { source_list.add_path_source("path" => "/path/to/gem") }
@@ -356,7 +358,7 @@ describe Bundler::SourceList do
end
describe "#remote!" do
- let(:rubygems_source) { source_list.add_rubygems_remote("https://rubygems.org") }
+ let(:rubygems_source) { source_list.add_rubygems_source("remotes" => "https://rubygems.org") }
let(:git_source) { source_list.add_git_source("uri" => "git://host/path.git") }
let(:path_source) { source_list.add_path_source("path" => "/path/to/gem") }
diff --git a/spec/cache/gems_spec.rb b/spec/cache/gems_spec.rb
index 7f0a914947..ed9c3440a8 100644
--- a/spec/cache/gems_spec.rb
+++ b/spec/cache/gems_spec.rb
@@ -9,6 +9,7 @@ describe "bundle cache" do
G
system_gems "rack-1.0.0"
+ should_be_installed "rack 1.0.0"
bundle :cache
end
@@ -29,7 +30,7 @@ describe "bundle cache" do
it "uses the cache as a source when installing gems with --local" do
system_gems []
- bundle "install --local"
+ bundle! "install --local"
should_be_installed("rack 1.0.0")
end
diff --git a/spec/commands/exec_spec.rb b/spec/commands/exec_spec.rb
index 051644ed60..3e4d55c42f 100644
--- a/spec/commands/exec_spec.rb
+++ b/spec/commands/exec_spec.rb
@@ -451,7 +451,8 @@ describe "bundle exec" do
let(:exit_code) { Bundler::GemNotFound.new.status_code }
let(:expected) { "" }
let(:expected_err) { <<-EOS.strip }
-\e[31mCould not find gem 'rack (= 2)' in any of the gem sources listed in your gems.rb or available on this machine.\e[0m
+\e[31mCould not find gem 'rack (= 2)' in locally installed gems.
+The source contains 'rack' at: 0.9.1, 1.0.0\e[0m
\e[33mRun `bundle install` to install missing gems.\e[0m
EOS
diff --git a/spec/commands/lock_spec.rb b/spec/commands/lock_spec.rb
index 5b2b465192..ea6f3219bb 100644
--- a/spec/commands/lock_spec.rb
+++ b/spec/commands/lock_spec.rb
@@ -85,7 +85,8 @@ describe "bundle lock" do
it "does not fetch remote specs when using the --local option" do
bundle "lock --update --local", :expect_err => true
- expect(err).to include("sources listed in your gems.rb or available on this machine")
+ expect(err).to include("or installed locally.").
+ and include("The source does not contain any versions of 'rails'.")
end
it "writes to a custom location using --lockfile" do
diff --git a/spec/install/gemfile/git_spec.rb b/spec/install/gemfile/git_spec.rb
index b7abba63bb..52f939ebc2 100644
--- a/spec/install/gemfile/git_spec.rb
+++ b/spec/install/gemfile/git_spec.rb
@@ -82,7 +82,7 @@ describe "bundle install with git sources" do
gem "foo", "1.1", :git => "#{lib_path("foo-1.0")}"
G
- expect(err).to include("Source contains 'foo' at: 1.0 ruby")
+ expect(err).to include("The source contains 'foo' at: 1.0")
end
it "complains with version and platform if pinned specs don't exist in the git repo" do
@@ -98,7 +98,7 @@ describe "bundle install with git sources" do
end
G
- expect(err).to include("Source contains 'only_java' at: 1.0 java")
+ expect(err).to include("The source contains 'only_java' at: 1.0 java")
end
it "complains with multiple versions and platforms if pinned specs don't exist in the git repo" do
@@ -119,7 +119,7 @@ describe "bundle install with git sources" do
end
G
- expect(err).to include("Source contains 'only_java' at: 1.0 java, 1.1 java")
+ expect(err).to include("The source contains 'only_java' at: 1.0 java, 1.1 java")
end
it "still works after moving the application directory" do
diff --git a/spec/install/gemfile/path_spec.rb b/spec/install/gemfile/path_spec.rb
index fd5e799048..2adacf4dca 100644
--- a/spec/install/gemfile/path_spec.rb
+++ b/spec/install/gemfile/path_spec.rb
@@ -6,8 +6,9 @@ describe "bundle install with explicit source paths" do
build_lib "foo"
install_gemfile <<-G
- path "#{lib_path("foo-1.0")}"
- gem 'foo'
+ path "#{lib_path("foo-1.0")}" do
+ gem 'foo'
+ end
G
should_be_installed("foo 1.0")
@@ -273,8 +274,9 @@ describe "bundle install with explicit source paths" do
end
install_gemfile <<-G
- path "#{lib_path("foo-1.0")}"
- gem 'foo'
+ path "#{lib_path("foo-1.0")}" do
+ gem 'foo'
+ end
G
bundle "exec foobar"
diff --git a/spec/install/gemfile/sources_spec.rb b/spec/install/gemfile/sources_spec.rb
index 206dfa44be..0697974fbe 100644
--- a/spec/install/gemfile/sources_spec.rb
+++ b/spec/install/gemfile/sources_spec.rb
@@ -30,7 +30,7 @@ describe "bundle install with gems on multiple sources" do
it "errors when disable_multisource is set" do
bundle "config disable_multisource true"
- bundle :install
+ bundle :install, :expect_err => true
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(14) if exitstatus
end
@@ -59,6 +59,10 @@ describe "bundle install with gems on multiple sources" do
build_gem "rack", "1.0.0" do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
+
+ build_gem "rack-obama" do |s|
+ s.add_dependency "rack"
+ end
end
gemfile <<-G
@@ -72,7 +76,7 @@ describe "bundle install with gems on multiple sources" do
end
it "installs the gems without any warning" do
- bundle :install
+ bundle! :install
expect(out).not_to include("Warning")
should_be_installed("rack-obama 1.0.0", "rack 1.0.0")
end
@@ -86,6 +90,10 @@ describe "bundle install with gems on multiple sources" do
build_gem "rack", "1.0.0" do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
+
+ build_gem "rack-obama" do |s|
+ s.add_dependency "rack"
+ end
end
gemfile <<-G
@@ -96,13 +104,13 @@ describe "bundle install with gems on multiple sources" do
end
it "installs the gems without any warning" do
- bundle :install
+ bundle! :install
expect(out).not_to include("Warning")
should_be_installed("rack-obama 1.0.0", "rack 1.0.0")
end
end
- context "with an indirect dependency" do
+ context "when a pinned gem has an indirect dependency" do
before do
build_repo gem_repo3 do
build_gem "depends_on_rack", "1.0.1" do |s|
@@ -150,7 +158,17 @@ describe "bundle install with gems on multiple sources" do
it "installs from the same source without any warning" do
bundle :install
- expect(out).not_to include("Warning")
+
+ expect(out).not_to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
+ should_be_installed("depends_on_rack 1.0.1", "rack 1.0.0")
+
+ # when there is already a lock file, and the gems are missing, so try again
+ system_gems []
+ bundle :install
+
+ expect(out).not_to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
should_be_installed("depends_on_rack 1.0.1", "rack 1.0.0")
end
end
@@ -218,6 +236,207 @@ describe "bundle install with gems on multiple sources" do
end
end
+ context "installing with dependencies from a monorepo" do
+ def should_be_installed_from_source(names_and_sources)
+ names_and_sources.each do |full_name, source|
+ name, version = full_name.split(" ", 2)
+ constant_name = Spec::Builders.constantize(name)
+ run! <<-RUBY
+ begin
+ require '#{name}'
+ puts begin
+ #{constant_name}
+ rescue NameError
+ #{name[0].upcase + name[1..-1]}::VERSION
+ end
+ rescue LoadError, NameError
+ puts '-'
+ end
+
+ begin
+ require '#{name}/source'
+ puts #{constant_name}_SOURCE
+ rescue LoadError, NameError
+ puts '-'
+ end
+ RUBY
+ actual_version, actual_source = out.split("\n")
+ expect(actual_version).to eq(version), "Expected #{name} to be at version #{version}, instead was at #{actual_version}"
+ expect(actual_source).to eq(source || "-"), "#{full_name} came from #{actual_source.inspect} instead of #{source.inspect}"
+ end
+ end
+
+ before do
+ build_lib "actionpack", "2.3.2", :path => lib_path("rails-2.3.2/actionpack") do |s|
+ s.write "lib/#{s.name}/source.rb", "#{Spec::Builders.constantize(s.name)}_SOURCE = 'rails-git'"
+ s.add_dependency "activesupport", "2.3.2"
+ end
+ build_lib "activerecord", "2.3.2", :path => lib_path("rails-2.3.2/activerecord") do |s|
+ s.write "lib/#{s.name}/source.rb", "#{Spec::Builders.constantize(s.name)}_SOURCE = 'rails-git'"
+ s.add_dependency "activesupport", "2.3.2"
+ end
+ build_lib "actionmailer", "2.3.2", :path => lib_path("rails-2.3.2/actionmailer") do |s|
+ s.write "lib/#{s.name}/source.rb", "#{Spec::Builders.constantize(s.name)}_SOURCE = 'rails-git'"
+ s.add_dependency "activesupport", "2.3.2"
+ end
+ build_lib "activeresource", "2.3.2", :path => lib_path("rails-2.3.2/activeresource") do |s|
+ s.write "lib/#{s.name}/source.rb", "#{Spec::Builders.constantize(s.name)}_SOURCE = 'rails-git'"
+ s.add_dependency "activesupport", "2.3.2"
+ end
+ build_lib "activesupport", "2.3.2", :path => lib_path("rails-2.3.2/activesupport") do |s|
+ s.write "lib/#{s.name}/source.rb", "#{Spec::Builders.constantize(s.name)}_SOURCE = 'rails-git'"
+ end
+ build_git "rails", "2.3.2" do |s|
+ s.write "lib/#{s.name}/source.rb", "#{Spec::Builders.constantize(s.name)}_SOURCE = 'rails-git'"
+ s.executables = "rails"
+ s.add_dependency "rake", "10.0.2"
+ s.add_dependency "actionpack", s.version
+ s.add_dependency "activerecord", s.version
+ s.add_dependency "actionmailer", s.version
+ s.add_dependency "activeresource", s.version
+ end
+ end
+
+ context "when depending on rails via git without a rubygems source" do
+ before do
+ build_lib "rake", "10.0.2" do |s|
+ s.write "lib/rake/source.rb", "RAKE_SOURCE = 'rake-git'"
+ end
+ install_gemfile <<-G
+ gem "rake", :path => #{lib_path("rake-10.0.2").to_s.dump}
+ gem "rails", :git => #{lib_path("rails-2.3.2").to_s.dump}
+ G
+ end
+
+ it "pulls all dependencies from the rails repo" do
+ should_be_installed_from_source("actionmailer 2.3.2" => "rails-git",
+ "actionpack 2.3.2" => "rails-git",
+ "activerecord 2.3.2" => "rails-git",
+ "activeresource 2.3.2" => "rails-git",
+ "activesupport 2.3.2" => "rails-git",
+ "rails 2.3.2" => "rails-git",
+ "rake 10.0.2" => "rake-git")
+ end
+ end
+
+ context "when depending on rails via git with a rubygems source" do
+ before do
+ install_gemfile <<-G
+ source "file://#{gem_repo1}/"
+ gem "rails", :git => #{lib_path("rails-2.3.2").to_s.dump}
+ G
+ end
+
+ it "pulls all dependencies from the rails repo" do
+ should_be_installed_from_source("actionmailer 2.3.2" => "rails-git",
+ "actionpack 2.3.2" => "rails-git",
+ "activerecord 2.3.2" => "rails-git",
+ "activeresource 2.3.2" => "rails-git",
+ "activesupport 2.3.2" => "rails-git",
+ "rails 2.3.2" => "rails-git",
+ "rake 10.0.2" => nil)
+ end
+ end
+
+ context "when depending on rails via git with a rubygems source and a transitive dep is made explicit" do
+ before do
+ install_gemfile <<-G
+ source "file://#{gem_repo1}/"
+ gem "rails", :git => #{lib_path("rails-2.3.2").to_s.dump}
+ gem "actionmailer"
+ G
+ end
+
+ it "pulls all dependencies from the rails repo" do
+ should_be_installed_from_source("actionmailer 2.3.2" => nil,
+ "actionpack 2.3.2" => "rails-git",
+ "activerecord 2.3.2" => "rails-git",
+ "activeresource 2.3.2" => "rails-git",
+ "activesupport 2.3.2" => nil,
+ "rails 2.3.2" => "rails-git",
+ "rake 10.0.2" => nil)
+ end
+ end
+ end
+
+ context "when a top-level gem has an indirect dependency" do
+ before do
+ build_repo gem_repo2 do
+ build_gem "depends_on_rack", "1.0.1" do |s|
+ s.add_dependency "rack"
+ end
+ end
+
+ build_repo gem_repo3 do
+ build_gem "unrelated_gem", "1.0.0"
+ end
+
+ gemfile <<-G
+ source "file://#{gem_repo2}"
+
+ gem "depends_on_rack"
+
+ source "file://#{gem_repo3}" do
+ gem "unrelated_gem"
+ end
+ G
+ end
+
+ context "and the dependency is only in the top-level source" do
+ before do
+ update_repo gem_repo2 do
+ build_gem "rack", "1.0.0"
+ end
+ end
+
+ it "installs all gems without warning" do
+ bundle :install
+ expect(out).not_to include("Warning")
+ expect(err).not_to include("Warning")
+ should_be_installed("depends_on_rack 1.0.1", "rack 1.0.0", "unrelated_gem 1.0.0")
+ end
+ end
+
+ context "and the dependency is only in a pinned source" do
+ before do
+ update_repo gem_repo3 do
+ build_gem "rack", "1.0.0" do |s|
+ s.write "lib/rack.rb", "RACK = 'FAIL'"
+ end
+ end
+ end
+
+ it "does not find the dependency" do
+ bundle :install, :expect_err => true
+ expect(err).to include strip_whitespace(<<-E).strip
+ Could not find gem 'rack', which is required by gem 'depends_on_rack', in any of the relevant sources:
+ rubygems repository file:#{gem_repo2}/ or installed locally
+ E
+ end
+ end
+
+ context "and the dependency is in both the top-level and a pinned source" do
+ before do
+ update_repo gem_repo2 do
+ build_gem "rack", "1.0.0"
+ end
+
+ update_repo gem_repo3 do
+ build_gem "rack", "1.0.0" do |s|
+ s.write "lib/rack.rb", "RACK = 'FAIL'"
+ end
+ end
+ end
+
+ it "installs the dependency from the top-level source without warning" do
+ bundle :install, :expect_err => true
+ expect(out).not_to include("Warning")
+ expect(err).not_to include("Warning")
+ should_be_installed("depends_on_rack 1.0.1", "rack 1.0.0", "unrelated_gem 1.0.0")
+ end
+ end
+ end
+
context "with a gem that is only found in the wrong source" do
before do
build_repo gem_repo3 do
diff --git a/spec/install/gems/compact_index_spec.rb b/spec/install/gems/compact_index_spec.rb
index f2a9042cb8..1cd0f370ab 100644
--- a/spec/install/gems/compact_index_spec.rb
+++ b/spec/install/gems/compact_index_spec.rb
@@ -222,8 +222,6 @@ The checksum of /versions does not match the checksum provided by the server! So
end
it "fetches again when more dependencies are found in subsequent sources" do
- pending "This test only passed with multiple primary sources. We need to " \
- "fix it to work with pinned sources, too."
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@@ -256,7 +254,6 @@ The checksum of /versions does not match the checksum provided by the server! So
end
end
- pending "this should not be ambiguous. rack 1.2 should come from the extra source."
gemfile <<-G
source "#{source_uri}" do; end
source "#{source_uri}/extra"
@@ -267,7 +264,6 @@ The checksum of /versions does not match the checksum provided by the server! So
end
it "considers all possible versions of dependencies from all api gem sources" do
- pending "this is currently broken with a pinned source. we need to fix it."
# 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
@@ -293,7 +289,6 @@ The checksum of /versions does not match the checksum provided by the server! So
end
it "prints API output properly with back deps" do
- pending "back deps are currently broken with pinned sources :'("
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@@ -315,7 +310,6 @@ The checksum of /versions does not match the checksum provided by the server! So
end
it "does not fetch every spec if the index of gems is large when doing back deps" do
- pending "back deps: still broken"
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@@ -352,7 +346,6 @@ The checksum of /versions does not match the checksum provided by the server! So
end
it "fetches again when more dependencies are found in subsequent sources using --deployment" do
- pending "back deps also broken in deployment mode"
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
diff --git a/spec/install/gems/resolving_spec.rb b/spec/install/gems/resolving_spec.rb
index 49d160063d..d6f83a20d9 100644
--- a/spec/install/gems/resolving_spec.rb
+++ b/spec/install/gems/resolving_spec.rb
@@ -4,14 +4,14 @@ require "spec_helper"
describe "bundle install with gem sources" do
describe "install time dependencies" do
it "installs gems with implicit rake dependencies" do
- install_gemfile <<-G
+ install_gemfile! <<-G
source "file://#{gem_repo1}"
gem "with_implicit_rake_dep"
gem "another_implicit_rake_dep"
gem "rake"
G
- run <<-R
+ run! <<-R
require 'implicit_rake_dep'
require 'another_implicit_rake_dep'
puts IMPLICIT_RAKE_DEP
@@ -32,7 +32,7 @@ describe "bundle install with gem sources" do
f.write Gem.deflate(Marshal.dump(spec))
end
- install_gemfile <<-G
+ install_gemfile! <<-G
source "file://#{gem_repo2}"
gem "actionpack", "2.3.2"
G
@@ -42,7 +42,7 @@ describe "bundle install with gem sources" do
describe "with crazy rubygem plugin stuff" do
it "installs plugins" do
- install_gemfile <<-G
+ install_gemfile! <<-G
source "file://#{gem_repo1}"
gem "net_b"
G
@@ -51,7 +51,7 @@ describe "bundle install with gem sources" do
end
it "installs plugins depended on by other plugins" do
- install_gemfile <<-G
+ install_gemfile! <<-G
source "file://#{gem_repo1}"
gem "net_a"
G
@@ -60,7 +60,7 @@ describe "bundle install with gem sources" do
end
it "installs multiple levels of dependencies" do
- install_gemfile <<-G
+ install_gemfile! <<-G
source "file://#{gem_repo1}"
gem "net_c"
gem "net_e"
diff --git a/spec/install/post_bundle_message_spec.rb b/spec/install/post_bundle_message_spec.rb
index 4e89d32432..6be21f35a8 100644
--- a/spec/install/post_bundle_message_spec.rb
+++ b/spec/install/post_bundle_message_spec.rb
@@ -95,12 +95,13 @@ describe "post bundle message" do
describe "with misspelled or non-existent gem name" do
it "should report a helpful error message" do
- install_gemfile <<-G
+ install_gemfile <<-G, :expect_err => true
source "file://#{gem_repo1}"
gem "rack"
gem "not-a-gem", :group => :development
G
- expect(err).to include("Could not find gem 'not-a-gem' in any of the gem sources listed in your gems.rb or available on this machine.")
+ expect(err).to include("Could not find gem 'not-a-gem' in rubygems repository").
+ and include("or installed locally.\nThe source does not contain any versions of 'not-a-gem'.")
end
end
end
diff --git a/spec/lock/lockfile_spec.rb b/spec/lock/lockfile_spec.rb
index e6b4ba34d1..4b961bc371 100644
--- a/spec/lock/lockfile_spec.rb
+++ b/spec/lock/lockfile_spec.rb
@@ -30,16 +30,16 @@ describe "the lockfile format" do
it "updates the lockfile's bundler version if current ver. is newer" do
lockfile <<-L
- GIT
- remote: git://github.com/nex3/haml.git
- revision: 8a2271f
- specs:
-
GEM
remote: file://#{gem_repo1}/
specs:
rack (1.0.0)
+ GIT
+ remote: git://github.com/nex3/haml.git
+ revision: 8a2271f
+ specs:
+
PLATFORMS
#{generic_local_platform}
@@ -359,18 +359,21 @@ describe "the lockfile format" do
G
end
- it "generates a lockfile wihout credentials for a configured source" do
+ it "generates a lockfile without credentials for a configured source" do
bundle "config http://localgemserver.test/ user:pass"
install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
- source "http://localgemserver.test/"
+ source "http://user:pass@othergemserver.test/"
gem "rack-obama", ">= 1.0"
- source "http://user:pass@othergemserver.test/" do; end
+ source "http://localgemserver.test/" do; end
G
lockfile_should_be <<-G
GEM
remote: http://localgemserver.test/
+ specs:
+
+ GEM
remote: http://user:pass@othergemserver.test/
specs:
rack (1.0.0)
@@ -423,15 +426,15 @@ describe "the lockfile format" do
G
lockfile_should_be <<-G
+ GEM
+ specs:
+
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("master")}
specs:
foo (1.0)
- GEM
- specs:
-
PLATFORMS
#{generic_local_platform}
@@ -457,16 +460,16 @@ describe "the lockfile format" do
G
lockfile <<-L
- GIT
- remote: git://github.com/nex3/haml.git
- revision: 8a2271f
- specs:
-
GEM
remote: file://#{gem_repo1}/
specs:
rack (1.0.0)
+ GIT
+ remote: git://github.com/nex3/haml.git
+ revision: 8a2271f
+ specs:
+
PLATFORMS
#{not_local}
@@ -492,15 +495,15 @@ describe "the lockfile format" do
G
lockfile_should_be <<-G
+ GEM
+ specs:
+
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("master")}
specs:
foo (1.0)
- GEM
- specs:
-
PLATFORMS
#{generic_local_platform}
@@ -521,6 +524,9 @@ describe "the lockfile format" do
G
lockfile_should_be <<-G
+ GEM
+ specs:
+
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("omg")}
@@ -528,9 +534,6 @@ describe "the lockfile format" do
specs:
foo (1.0)
- GEM
- specs:
-
PLATFORMS
#{generic_local_platform}
@@ -551,6 +554,9 @@ describe "the lockfile format" do
G
lockfile_should_be <<-G
+ GEM
+ specs:
+
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("omg")}
@@ -558,9 +564,6 @@ describe "the lockfile format" do
specs:
foo (1.0)
- GEM
- specs:
-
PLATFORMS
#{generic_local_platform}
@@ -580,14 +583,14 @@ describe "the lockfile format" do
G
lockfile_should_be <<-G
+ GEM
+ specs:
+
PATH
remote: #{lib_path("foo-1.0")}
specs:
foo (1.0)
- GEM
- specs:
-
PLATFORMS
#{generic_local_platform}
@@ -612,6 +615,11 @@ describe "the lockfile format" do
G
lockfile_should_be <<-G
+ GEM
+ remote: file:#{gem_repo1}/
+ specs:
+ rack (1.0.0)
+
GIT
remote: #{lib_path("bar-1.0")}
revision: #{bar.ref_for("master")}
@@ -623,11 +631,6 @@ describe "the lockfile format" do
specs:
foo (1.0)
- GEM
- remote: file:#{gem_repo1}/
- specs:
- rack (1.0.0)
-
PLATFORMS
#{generic_local_platform}
@@ -797,24 +800,25 @@ describe "the lockfile format" do
build_lib "foo", :path => bundled_app("foo")
install_gemfile <<-G
- path "foo"
- gem "foo"
+ path "foo" do
+ gem "foo"
+ end
G
lockfile_should_be <<-G
+ GEM
+ specs:
+
PATH
remote: foo
specs:
foo (1.0)
- GEM
- specs:
-
PLATFORMS
#{generic_local_platform}
DEPENDENCIES
- foo
+ foo!
BUNDLED WITH
#{Bundler::VERSION}
@@ -825,24 +829,25 @@ describe "the lockfile format" do
build_lib "foo", :path => bundled_app(File.join("..", "foo"))
install_gemfile <<-G
- path "../foo"
- gem "foo"
+ path "../foo" do
+ gem "foo"
+ end
G
lockfile_should_be <<-G
+ GEM
+ specs:
+
PATH
remote: ../foo
specs:
foo (1.0)
- GEM
- specs:
-
PLATFORMS
#{generic_local_platform}
DEPENDENCIES
- foo
+ foo!
BUNDLED WITH
#{Bundler::VERSION}
@@ -853,24 +858,25 @@ describe "the lockfile format" do
build_lib "foo", :path => bundled_app("foo")
install_gemfile <<-G
- path File.expand_path("../foo", __FILE__)
- gem "foo"
+ path File.expand_path("../foo", __FILE__) do
+ gem "foo"
+ end
G
lockfile_should_be <<-G
+ GEM
+ specs:
+
PATH
remote: foo
specs:
foo (1.0)
- GEM
- specs:
-
PLATFORMS
#{generic_local_platform}
DEPENDENCIES
- foo
+ foo!
BUNDLED WITH
#{Bundler::VERSION}
@@ -885,14 +891,14 @@ describe "the lockfile format" do
G
lockfile_should_be <<-G
+ GEM
+ specs:
+
PATH
remote: ../foo
specs:
foo (1.0)
- GEM
- specs:
-
PLATFORMS
#{generic_local_platform}
@@ -1172,6 +1178,10 @@ describe "the lockfile format" do
# Create a gems.locked that has duplicate GIT sections
lockfile <<-L
+ GEM
+ remote: file:#{gem_repo1}/
+ specs:
+
GIT
remote: #{lib_path("omg")}
revision: #{revision}
@@ -1186,10 +1196,6 @@ describe "the lockfile format" do
specs:
omg (1.0)
- GEM
- remote: file:#{gem_repo1}/
- specs:
-
PLATFORMS
#{local}
@@ -1206,6 +1212,10 @@ describe "the lockfile format" do
# Confirm that duplicate specs do not appear
expect(File.read(bundled_app("gems.locked"))).to eq(strip_whitespace(<<-L))
+ GEM
+ remote: file:#{gem_repo1}/
+ specs:
+
GIT
remote: #{lib_path("omg")}
revision: #{revision}
@@ -1213,10 +1223,6 @@ describe "the lockfile format" do
specs:
omg (1.0)
- GEM
- remote: file:#{gem_repo1}/
- specs:
-
PLATFORMS
#{local}
diff --git a/spec/resolver/basic_spec.rb b/spec/resolver/basic_spec.rb
index cb5bc45597..861fa6e35a 100644
--- a/spec/resolver/basic_spec.rb
+++ b/spec/resolver/basic_spec.rb
@@ -100,7 +100,7 @@ describe "Resolving" do
deps << Bundler::DepProxy.new(d, "ruby")
end
- got = Bundler::Resolver.resolve(deps, @index, {}, [], Bundler::RubyVersion.new("1.8.7", nil, nil, nil))
+ got = Bundler::Resolver.resolve(deps, @index, { :default => double(:specs => @index) }, [], Bundler::RubyVersion.new("1.8.7", nil, nil, nil))
got = got.map(&:full_name).sort
expect(got).to eq(%w(foo-1.0.0 bar-1.0.0).sort)
end
diff --git a/spec/runtime/inline_spec.rb b/spec/runtime/inline_spec.rb
index dc429bf5c0..32686efa45 100644
--- a/spec/runtime/inline_spec.rb
+++ b/spec/runtime/inline_spec.rb
@@ -53,8 +53,9 @@ describe "bundler/inline#gemfile" do
it "requires the gems" do
script <<-RUBY
gemfile do
- path "#{lib_path}"
- gem "two"
+ path "#{lib_path}" do
+ gem "two"
+ end
end
RUBY
@@ -63,8 +64,9 @@ describe "bundler/inline#gemfile" do
script <<-RUBY, :expect_err => true
gemfile do
- path "#{lib_path}"
- gem "eleven"
+ path "#{lib_path}" do
+ gem "eleven"
+ end
end
puts "success"
@@ -116,8 +118,9 @@ describe "bundler/inline#gemfile" do
it "raises an exception if passed unknown arguments" do
script <<-RUBY, :expect_err => true
gemfile(true, :arglebargle => true) do
- path "#{lib_path}"
- gem "two"
+ path "#{lib_path}" do
+ gem "two"
+ end
end
puts "success"
@@ -131,8 +134,9 @@ describe "bundler/inline#gemfile" do
require 'bundler'
options = { :ui => Bundler::UI::Shell.new }
gemfile(false, options) do
- path "#{lib_path}"
- gem "two"
+ path "#{lib_path}" do
+ gem "two"
+ end
end
puts "OKAY" if options.key?(:ui)
RUBY
@@ -162,8 +166,9 @@ describe "bundler/inline#gemfile" do
it "raises an exception if passed unknown arguments" do
script <<-RUBY, :expect_err => true
gemfile(true, :arglebargle => true) do
- path "#{lib_path}"
- gem "two"
+ path "#{lib_path}" do
+ gem "two"
+ end
end
puts "success"
@@ -177,8 +182,9 @@ describe "bundler/inline#gemfile" do
require 'bundler'
options = { :ui => Bundler::UI::Shell.new }
gemfile(false, options) do
- path "#{lib_path}"
- gem "two"
+ path "#{lib_path}" do
+ gem "two"
+ end
end
puts "OKAY" if options.key?(:ui)
RUBY
diff --git a/spec/runtime/require_spec.rb b/spec/runtime/require_spec.rb
index c9cb10eedf..676a2a9cea 100644
--- a/spec/runtime/require_spec.rb
+++ b/spec/runtime/require_spec.rb
@@ -39,15 +39,16 @@ describe "Bundler.require" do
end
gemfile <<-G
- path "#{lib_path}"
- gem "one", :group => :bar, :require => %w[baz qux]
- gem "two"
- gem "three", :group => :not
- gem "four", :require => false
- gem "five"
- gem "six", :group => "string"
- gem "seven", :group => :not
- gem "eight", :require => true, :group => :require_true
+ path "#{lib_path}" do
+ gem "one", :group => :bar, :require => %w[baz qux]
+ gem "two"
+ gem "three", :group => :not
+ gem "four", :require => false
+ gem "five"
+ gem "six", :group => "string"
+ gem "seven", :group => :not
+ gem "eight", :require => true, :group => :require_true
+ end
G
end
@@ -88,8 +89,9 @@ describe "Bundler.require" do
it "raises an exception if a require is specified but the file does not exist" do
gemfile <<-G
- path "#{lib_path}"
- gem "two", :require => 'fail'
+ path "#{lib_path}" do
+ gem "two", :require => 'fail'
+ end
G
load_error_run <<-R, "fail"
@@ -105,8 +107,9 @@ describe "Bundler.require" do
end
gemfile <<-G
- path "#{lib_path}"
- gem "faulty"
+ path "#{lib_path}" do
+ gem "faulty"
+ end
G
run "Bundler.require", :expect_err => true
@@ -120,8 +123,9 @@ describe "Bundler.require" do
end
gemfile <<-G
- path "#{lib_path}"
- gem "faulty"
+ path "#{lib_path}" do
+ gem "faulty"
+ end
G
run "Bundler.require", :expect_err => true
@@ -135,8 +139,9 @@ describe "Bundler.require" do
end
gemfile <<-G
- path "#{lib_path}"
- gem "loadfuuu"
+ path "#{lib_path}" do
+ gem "loadfuuu"
+ end
G
cmd = <<-RUBY
@@ -161,8 +166,9 @@ describe "Bundler.require" do
it "requires gem names that are namespaced" do
gemfile <<-G
- path '#{lib_path}'
- gem 'jquery-rails'
+ path "#{lib_path}" do
+ gem "jquery-rails"
+ end
G
run "Bundler.require"
@@ -174,8 +180,9 @@ describe "Bundler.require" do
s.write "lib/brcrypt.rb", "BCrypt = '1.0.0'"
end
gemfile <<-G
- path "#{lib_path}"
- gem "bcrypt-ruby"
+ path "#{lib_path}" do
+ gem "bcrypt-ruby"
+ end
G
cmd = <<-RUBY
@@ -189,8 +196,9 @@ describe "Bundler.require" do
it "does not mangle explictly given requires" do
gemfile <<-G
- path "#{lib_path}"
- gem 'jquery-rails', :require => 'jquery-rails'
+ path "#{lib_path}" do
+ gem 'jquery-rails', :require => 'jquery-rails'
+ end
G
load_error_run <<-R, "jquery-rails"
@@ -205,8 +213,9 @@ describe "Bundler.require" do
end
gemfile <<-G
- path "#{lib_path}"
- gem "load-fuuu"
+ path "#{lib_path}" do
+ gem "load-fuuu"
+ end
G
cmd = <<-RUBY
@@ -228,8 +237,9 @@ describe "Bundler.require" do
lib_path("load-fuuu-1.0.0/lib/load-fuuu.rb").rmtree
gemfile <<-G
- path "#{lib_path}"
- gem "load-fuuu"
+ path "#{lib_path}" do
+ gem "load-fuuu"
+ end
G
cmd = <<-RUBY
@@ -285,9 +295,10 @@ describe "Bundler.require" do
it "works when the gems are in the Gemfile in the correct order" do
gemfile <<-G
- path "#{lib_path}"
- gem "two"
- gem "one"
+ path "#{lib_path}" do
+ gem "two"
+ gem "one"
+ end
G
run "Bundler.require"
@@ -325,9 +336,10 @@ describe "Bundler.require" do
it "fails when the gems are in the Gemfile in the wrong order" do
gemfile <<-G
- path "#{lib_path}"
- gem "one"
- gem "two"
+ path "#{lib_path}" do
+ gem "one"
+ gem "two"
+ end
G
run "Bundler.require"
diff --git a/spec/runtime/setup_spec.rb b/spec/runtime/setup_spec.rb
index e89d5b3a0e..319f752be2 100644
--- a/spec/runtime/setup_spec.rb
+++ b/spec/runtime/setup_spec.rb
@@ -367,9 +367,9 @@ describe "Bundler.setup" do
end
gemfile <<-G
- path "#{lib_path("rack-1.0.0")}"
- source "file://#{gem_repo1}"
- gem "rack"
+ path "#{lib_path("rack-1.0.0")}" do
+ gem "rack"
+ end
G
run "require 'rack'"
diff --git a/spec/support/indexes.rb b/spec/support/indexes.rb
index acace96886..2fdc1f23f4 100644
--- a/spec/support/indexes.rb
+++ b/spec/support/indexes.rb
@@ -16,12 +16,15 @@ module Spec
def resolve
@platforms ||= ["ruby"]
deps = []
+ default_source = instance_double("Bundler::Source::Rubygems", :specs => @index)
+ source_requirements = { :default => default_source }
@deps.each do |d|
@platforms.each do |p|
+ source_requirements[d.name] = d.source = default_source
deps << Bundler::DepProxy.new(d, p)
end
end
- Bundler::Resolver.resolve(deps, @index)
+ Bundler::Resolver.resolve(deps, @index, source_requirements)
end
def should_resolve_as(specs)
diff --git a/spec/update/git_spec.rb b/spec/update/git_spec.rb
index 8c68b56010..8424161a7f 100644
--- a/spec/update/git_spec.rb
+++ b/spec/update/git_spec.rb
@@ -334,17 +334,17 @@ describe "bundle update" do
bundle "update --source bar"
lockfile_should_be <<-G
+ GEM
+ remote: file:#{gem_repo2}/
+ specs:
+ rack (1.0.0)
+
GIT
remote: #{@git.path}
revision: #{ref}
specs:
foo (2.0)
- GEM
- remote: file:#{gem_repo2}/
- specs:
- rack (1.0.0)
-
PLATFORMS
ruby