aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorTim Moore <tmoore@incrementalism.net>2014-07-06 18:35:31 +1000
committerTim Moore <tmoore@incrementalism.net>2014-07-30 14:16:35 +1000
commitab78e7449ba1c1024de22ff798c6a32fb581abca (patch)
tree30e77a8e8f10b423874e6c713f1446d803bf8037 /lib
parent9af2172e6dc6b29dc24f92a27b7a385faa952ba3 (diff)
downloadbundler-ab78e7449ba1c1024de22ff798c6a32fb581abca.tar.gz
Detect ambiguous gems.
Diffstat (limited to 'lib')
-rw-r--r--lib/bundler/cli/install.rb9
-rw-r--r--lib/bundler/index.rb18
-rw-r--r--lib/bundler/installer.rb9
-rw-r--r--lib/bundler/source/rubygems.rb12
4 files changed, 41 insertions, 7 deletions
diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb
index 2f5b490b..64f4803a 100644
--- a/lib/bundler/cli/install.rb
+++ b/lib/bundler/cli/install.rb
@@ -93,6 +93,15 @@ module Bundler
Bundler.ui.confirm "Post-install message from #{name}:"
Bundler.ui.info msg
end
+ Installer.ambiguous_gems.to_a.each do |name, installed_from_uri, *also_found_in_uris|
+ Bundler.ui.error "Warning: the gem '#{name}' was found in multiple sources."
+ Bundler.ui.error "Installed from: #{installed_from_uri}"
+ Bundler.ui.error "Also found in:"
+ also_found_in_uris.each { |uri| Bundler.ui.error " * #{uri}" }
+ Bundler.ui.error "You should add a source requirement to restrict this gem to your preferred source."
+ Bundler.ui.error "For example:"
+ Bundler.ui.error " gem '#{name}', :source => '#{installed_from_uri}'"
+ end
if Bundler.settings[:clean] && Bundler.settings[:path]
require "bundler/cli/clean"
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
index 493ac8fa..5af70668 100644
--- a/lib/bundler/index.rb
+++ b/lib/bundler/index.rb
@@ -10,13 +10,14 @@ module Bundler
i
end
- attr_reader :specs, :sources
- protected :specs
+ attr_reader :specs, :all_specs, :sources
+ protected :specs, :all_specs
def initialize
@sources = []
@cache = {}
@specs = Hash.new { |h,k| h[k] = [] }
+ @all_specs = Hash.new { |h,k| h[k] = [] }
end
def initialize_copy(o)
@@ -24,10 +25,14 @@ module Bundler
@sources = @sources.dup
@cache = {}
@specs = Hash.new { |h,k| h[k] = [] }
+ @all_specs = Hash.new { |h,k| h[k] = [] }
o.specs.each do |name, array|
@specs[name] = array.dup
end
+ o.all_specs.each do |name, array|
+ @all_specs[name] = array.dup
+ end
end
def inspect
@@ -39,6 +44,14 @@ module Bundler
true
end
+ def search_all(name)
+ all_matches = @all_specs[name] + local_search(name)
+ @sources.each do |source|
+ all_matches.concat(source.search_all(name))
+ end
+ all_matches
+ end
+
# Search this index's specs, and any source indexes that this index knows
# about, returning all of the results.
def search(query, base = nil)
@@ -105,6 +118,7 @@ module Bundler
return unless other
other.each do |s|
if (dupes = search_by_spec(s)) && dupes.any?
+ @all_specs[s.name] = [s] + dupes
next unless override_dupes
@specs[s.name] -= dupes
end
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index fe03b615..ed743d40 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -5,7 +5,10 @@ require 'bundler/parallel_workers'
module Bundler
class Installer < Environment
class << self
- attr_accessor :post_install_messages
+ attr_accessor :post_install_messages, :ambiguous_gems
+
+ Installer.post_install_messages = {}
+ Installer.ambiguous_gems = []
end
# Begins the installation process for Bundler.
@@ -75,10 +78,6 @@ module Bundler
unless local
options["local"] ? @definition.resolve_with_cache! : @definition.resolve_remotely!
end
- # Must install gems in the order that the resolver provides
- # as dependencies might actually affect the installation of
- # the gem.
- Installer.post_install_messages = {}
# the order that the resolver provides is significant, since
# dependencies might actually affect the installation of a gem.
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 5e708793..203473ed 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -72,6 +72,12 @@ module Bundler
# Download the gem to get the spec, because some specs that are returned
# by rubygems.org are broken and wrong.
if spec.source_uri
+ # Check for this spec from other sources
+ uris = [spec.source_uri]
+ uris += source_uris_for_spec(spec)
+ uris.uniq!
+ Installer.ambiguous_gems << [spec.name, *uris] if uris.length > 1
+
s = Bundler.rubygems.spec_from_gem(fetch_gem(spec), Bundler.settings["trust-policy"])
spec.__swap__(s)
end
@@ -163,6 +169,12 @@ module Bundler
true
end
+ protected
+
+ def source_uris_for_spec(spec)
+ specs.search_all(spec.name).map{|s| s.source_uri }
+ end
+
private
def cached_gem(spec)