[前][次][番号順一覧][スレッド一覧]

ruby-changes:72781

From: David <ko1@a...>
Date: Tue, 2 Aug 2022 16:10:44 +0900 (JST)
Subject: [ruby-changes:72781] f4f681463f (master): [rubygems/rubygems] Don't discard candidates matching ruby metadata

https://git.ruby-lang.org/ruby.git/commit/?id=f4f681463f

From f4f681463f71c2fc63e1a07f36f2665f2b9db002 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@r...>
Date: Sat, 23 Jul 2022 08:44:47 +0200
Subject: [rubygems/rubygems] Don't discard candidates matching ruby metadata

Do dependency filtering and materialization in one step. Before,
dependency filtering would not consider ruby metadata so it would
discard variants that end up not being materializable in the end.

https://github.com/rubygems/rubygems/commit/0c0d40d417

Co-authored-by: Ian Ker-Seymer <ian.kerseymer@s...>
---
 lib/bundler/gem_helpers.rb                         |  8 +++-
 lib/bundler/lazy_specification.rb                  |  6 ++-
 lib/bundler/spec_set.rb                            |  7 +---
 .../install/gemfile/specific_platform_spec.rb      | 47 ++++++++++++++++++++++
 spec/bundler/install/gems/resolving_spec.rb        | 22 ++++++++--
 5 files changed, 78 insertions(+), 12 deletions(-)

diff --git a/lib/bundler/gem_helpers.rb b/lib/bundler/gem_helpers.rb
index 6bc4fb4991..0d50d8687b 100644
--- a/lib/bundler/gem_helpers.rb
+++ b/lib/bundler/gem_helpers.rb
@@ -44,6 +44,12 @@ module Bundler https://github.com/ruby/ruby/blob/trunk/lib/bundler/gem_helpers.rb#L44
 
     def select_best_platform_match(specs, platform)
       matching = specs.select {|spec| spec.match_platform(platform) }
+
+      sort_best_platform_match(matching, platform)
+    end
+    module_function :select_best_platform_match
+
+    def sort_best_platform_match(matching, platform)
       exact = matching.select {|spec| spec.platform == platform }
       return exact if exact.any?
 
@@ -52,7 +58,7 @@ module Bundler https://github.com/ruby/ruby/blob/trunk/lib/bundler/gem_helpers.rb#L58
 
       sorted_matching.take_while {|spec| same_specificity(platform, spec, exemplary_spec) && same_deps(spec, exemplary_spec) }
     end
-    module_function :select_best_platform_match
+    module_function :sort_best_platform_match
 
     class PlatformMatch
       def self.specificity_score(spec_platform, user_platform)
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb
index 805afba51f..a88172d96b 100644
--- a/lib/bundler/lazy_specification.rb
+++ b/lib/bundler/lazy_specification.rb
@@ -88,6 +88,8 @@ module Bundler https://github.com/ruby/ruby/blob/trunk/lib/bundler/lazy_specification.rb#L88
         source.specs.search(self)
       end
 
+      return self if candidates.empty?
+
       __materialize__(candidates)
     end
 
@@ -105,8 +107,8 @@ module Bundler https://github.com/ruby/ruby/blob/trunk/lib/bundler/lazy_specification.rb#L107
           spec.is_a?(StubSpecification) ||
             (spec.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
               spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version))
-        end || candidates.last
-        search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification))
+        end
+        search.dependencies = dependencies if search && search.full_name == full_name && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification))
         search
       end
     end
diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb
index 6a3813eef8..e21a3ea6f5 100644
--- a/lib/bundler/spec_set.rb
+++ b/lib/bundler/spec_set.rb
@@ -66,10 +66,6 @@ module Bundler https://github.com/ruby/ruby/blob/trunk/lib/bundler/spec_set.rb#L66
     def materialize(deps)
       materialized = self.for(deps, true).uniq
 
-      materialized.map! do |s|
-        next s unless s.is_a?(LazySpecification)
-        s.materialize_for_installation || s
-      end
       SpecSet.new(materialized)
     end
 
@@ -180,7 +176,8 @@ module Bundler https://github.com/ruby/ruby/blob/trunk/lib/bundler/spec_set.rb#L176
     def specs_for_dependency(dep, platform)
       specs_for_name = lookup[dep.name]
       if platform.nil?
-        GemHelpers.select_best_platform_match(specs_for_name.select {|s| Gem::Platform.match_spec?(s) }, Bundler.local_platform)
+        matching_specs = specs_for_name.map {|s| s.materialize_for_installation if Gem::Platform.match_spec?(s) }.compact
+        GemHelpers.sort_best_platform_match(matching_specs, Bundler.local_platform)
       else
         GemHelpers.select_best_platform_match(specs_for_name, dep.force_ruby_platform ? Gem::Platform::RUBY : platform)
       end
diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb
index 6994cb2af1..48349aaef4 100644
--- a/spec/bundler/install/gemfile/specific_platform_spec.rb
+++ b/spec/bundler/install/gemfile/specific_platform_spec.rb
@@ -374,6 +374,41 @@ RSpec.describe "bundle install with specific platforms" do https://github.com/ruby/ruby/blob/trunk/spec/bundler/install/gemfile/specific_platform_spec.rb#L374
     ERROR
   end
 
+  it "can fallback to a source gem when platform gems are incompatible with current ruby version" do
+    setup_multiplatform_gem_with_source_gem
+
+    source = file_uri_for(gem_repo2)
+
+    gemfile <<~G
+      source "#{source}"
+
+      gem "my-precompiled-gem"
+    G
+
+    # simulate lockfile which includes both a precompiled gem with:
+    # - Gem the current platform (with imcompatible ruby version)
+    # - A source gem with compatible ruby version
+    lockfile <<-L
+      GEM
+        remote: #{source}/
+        specs:
+          my-precompiled-gem (3.0.0)
+          my-precompiled-gem (3.0.0-#{Bundler.local_platform})
+
+      PLATFORMS
+        ruby
+        #{Bundler.local_platform}
+
+      DEPENDENCIES
+        my-precompiled-gem
+
+      BUNDLED WITH
+         #{Bundler::VERSION}
+    L
+
+    bundle :install
+  end
+
   private
 
   def setup_multiplatform_gem
@@ -404,4 +439,16 @@ RSpec.describe "bundle install with specific platforms" do https://github.com/ruby/ruby/blob/trunk/spec/bundler/install/gemfile/specific_platform_spec.rb#L439
       build_gem("CFPropertyList")
     end
   end
+
+  def setup_multiplatform_gem_with_source_gem
+    build_repo2 do
+      build_gem("my-precompiled-gem", "3.0.0")
+      build_gem("my-precompiled-gem", "3.0.0") do |s|
+        s.platform = Bundler.local_platform
+
+        # purposely unresolvable
+        s.required_ruby_version = ">= 1000.0.0"
+      end
+    end
+  end
 end
diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb
index 1679ad4460..a55db83dc4 100644
--- a/spec/bundler/install/gems/resolving_spec.rb
+++ b/spec/bundler/install/gems/resolving_spec.rb
@@ -241,7 +241,7 @@ RSpec.describe "bundle install with install-time dependencies" do https://github.com/ruby/ruby/blob/trunk/spec/bundler/install/gems/resolving_spec.rb#L241
         expect(the_bundle).to include_gems("rack 1.2")
       end
 
-      it "gives a meaningful error if there's a lockfile using the newer incompatible version" do
+      it "automatically updates lockfile to use the older version" do
         build_repo2 do
           build_gem "parallel_tests", "3.7.0" do |s|
             s.required_ruby_version = ">= #{current_ruby_minor}"
@@ -273,9 +273,23 @@ RSpec.describe "bundle install with install-time dependencies" do https://github.com/ruby/ruby/blob/trunk/spec/bundler/install/gems/resolving_spec.rb#L273
              #{Bundler::VERSION}
         L
 
-        bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, :raise_on_error => false
-        expect(err).to include("parallel_tests-3.8.0 requires ruby version >= #{next_ruby_minor}")
-        expect(err).not_to include("That means the author of parallel_tests (3.8.0) has removed it.")
+        bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+
+        expect(lockfile).to eq <<~L
+          GEM
+            remote: http://localgemserver.test/
+            specs:
+              parallel_tests (3.7.0)
+
+          PLATFORMS
+            #{lockfile_platforms}
+
+          DEPENDENCIES
+            parallel_tests
+
+          BUNDLED WITH
+             #{Bundler::VERSION}
+        L
       end
 
       it "gives a meaningful error on ruby version mismatches between dependencies" do
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]