Patch by MSP-Greg Aligns two ruby/ruby files with the same rubygems/rubygems files diff --git a/lib/rubygems/resolver.rb b/lib/rubygems/resolver.rb index 8f0db512a2..13ee035e4c 100644 --- a/lib/rubygems/resolver.rb +++ b/lib/rubygems/resolver.rb @@ -230,8 +230,28 @@ def search_for(dependency) exc.errors = @set.errors raise exc end - possibles.sort_by { |s| [s.source, s.version, Gem::Platform.local =~ s.platform ? 1 : 0] }. - map { |s| ActivationRequest.new s, dependency, [] } + + sources = [] + + groups = Hash.new { |hash, key| hash[key] = [] } + + # create groups & sources in the same loop + sources = possibles.map { |spec| + source = spec.source + groups[source] << spec + source + }.uniq.reverse + + activation_requests = [] + + sources.each do |source| + groups[source]. + sort_by { |spec| [spec.version, Gem::Platform.local =~ spec.platform ? 1 : 0] }. + map { |spec| ActivationRequest.new spec, dependency, [] }. + each { |activation_request| activation_requests << activation_request } + end + + activation_requests end def dependencies_for(specification) diff --git a/test/rubygems/test_gem_resolver.rb b/test/rubygems/test_gem_resolver.rb index e95a37162d..417f0580f7 100644 --- a/test/rubygems/test_gem_resolver.rb +++ b/test/rubygems/test_gem_resolver.rb @@ -683,6 +683,32 @@ def test_second_level_backout assert_resolves_to [b1, c1, d2], r end + def test_sorts_by_source_then_version + sourceA = Gem::Source.new 'http://example.com/a' + sourceB = Gem::Source.new 'http://example.com/b' + sourceC = Gem::Source.new 'http://example.com/c' + + spec_A_1 = new_spec 'some-dep', '0.0.1' + spec_A_2 = new_spec 'some-dep', '1.0.0' + spec_B_1 = new_spec 'some-dep', '0.0.1' + spec_B_2 = new_spec 'some-dep', '0.0.2' + spec_C_1 = new_spec 'some-dep', '0.1.0' + + set = StaticSet.new [ + Gem::Resolver::SpecSpecification.new(nil, spec_B_1, sourceB), + Gem::Resolver::SpecSpecification.new(nil, spec_B_2, sourceB), + Gem::Resolver::SpecSpecification.new(nil, spec_C_1, sourceC), + Gem::Resolver::SpecSpecification.new(nil, spec_A_2, sourceA), + Gem::Resolver::SpecSpecification.new(nil, spec_A_1, sourceA), + ] + + dependency = make_dep 'some-dep', '> 0' + + resolver = Gem::Resolver.new [dependency], set + + assert_resolves_to [spec_B_2], resolver + end + def test_select_local_platforms r = Gem::Resolver.new nil, nil