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

ruby-changes:68430

From: David <ko1@a...>
Date: Wed, 13 Oct 2021 21:16:55 +0900 (JST)
Subject: [ruby-changes:68430] 853004e04d (master): [rubygems/rubygems] Fix `bundle install` crash due to an incorrectly incomplete resolve

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

From 853004e04d86502e1df509302a4c5dce03d9d40e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@r...>
Date: Wed, 29 Sep 2021 21:11:23 +0200
Subject: [rubygems/rubygems] Fix `bundle install` crash due to an incorrectly
 incomplete resolve

In case we have a corrupted lockfile that claims to support a platform, but
it's missing platform specific gems for it, bundler has a check that
detects the situation and forces a re-resolve. The result of this check
is kept under the `@locked_specs_incomplete_for_platformn` instance
variable in `Definition`.

The installer, however, calls `Definition#nothing_changed?` before this
instance variable has been filled, so the result of it is actually
incorrect here since it will claim that nothing has changed, but
something has changed (locked specs are incomplete for the current
platform).

The consequence of this incorrect result is that the installer thinks it
can go on without re-resolving, resulting in the incomplete resolution
from the lockfile being used, and in a crash being triggered due to
that.

The solution is to make sure the `@locked_specs_incomplete_for_platform`
instance variable is filled before `nothing_changed?` gets called.
Moving it to `initialize` makes the most sense, not because it's the
best place for it (we can refactor this later), but because all of the
other "outdated definition" checks are already set there.

https://github.com/rubygems/rubygems/commit/708afdd789
---
 lib/bundler/definition.rb             |  4 +-
 spec/bundler/commands/install_spec.rb | 95 +++++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index e50266f5a2..da180ce255 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -78,7 +78,6 @@ module Bundler https://github.com/ruby/ruby/blob/trunk/lib/bundler/definition.rb#L78
       @lockfile_contents      = String.new
       @locked_bundler_version = nil
       @locked_ruby_version    = nil
-      @locked_specs_incomplete_for_platform = false
       @new_platform = nil
 
       if lockfile && File.exist?(lockfile)
@@ -144,6 +143,8 @@ module Bundler https://github.com/ruby/ruby/blob/trunk/lib/bundler/definition.rb#L143
       @dependency_changes = converge_dependencies
       @local_changes = converge_locals
 
+      @locked_specs_incomplete_for_platform = !@locked_specs.for(expand_dependencies(requested_dependencies & locked_dependencies), true, true)
+
       @requires = compute_requires
     end
 
@@ -762,7 +763,6 @@ module Bundler https://github.com/ruby/ruby/blob/trunk/lib/bundler/definition.rb#L763
       end
 
       resolve = SpecSet.new(converged)
-      @locked_specs_incomplete_for_platform = !@locked_specs.for(expand_dependencies(requested_dependencies & locked_dependencies), true, true)
       resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false).reject{|s| @unlock[:gems].include?(s.name) })
       diff    = nil
 
diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb
index 1e8d2295ba..97257f689c 100644
--- a/spec/bundler/commands/install_spec.rb
+++ b/spec/bundler/commands/install_spec.rb
@@ -775,6 +775,101 @@ RSpec.describe "bundle install with gem sources" do https://github.com/ruby/ruby/blob/trunk/spec/bundler/commands/install_spec.rb#L775
     end
   end
 
+  context "with missing platform specific gems in lockfile" do
+    before do
+      build_repo4 do
+        build_gem "racc", "1.5.2"
+
+        build_gem "nokogiri", "1.12.4" do |s|
+          s.platform = "x86_64-darwin"
+          s.add_runtime_dependency "racc", "~> 1.4"
+        end
+
+        build_gem "nokogiri", "1.12.4" do |s|
+          s.platform = "x86_64-linux"
+          s.add_runtime_dependency "racc", "~> 1.4"
+        end
+
+        build_gem "crass", "1.0.6"
+
+        build_gem "loofah", "2.12.0" do |s|
+          s.add_runtime_dependency "crass", "~> 1.0.2"
+          s.add_runtime_dependency "nokogiri", ">= 1.5.9"
+        end
+      end
+
+      gemfile <<-G
+        source "https://gem.repo4"
+
+        ruby "#{RUBY_VERSION}"
+
+        gem "loofah", "~> 2.12.0"
+      G
+
+      lockfile <<-L
+        GEM
+          remote: https://gem.repo4/
+          specs:
+            crass (1.0.6)
+            loofah (2.12.0)
+              crass (~> 1.0.2)
+              nokogiri (>= 1.5.9)
+            nokogiri (1.12.4-x86_64-darwin)
+              racc (~> 1.4)
+            racc (1.5.2)
+
+        PLATFORMS
+          x86_64-darwin-20
+          x86_64-linux
+
+        DEPENDENCIES
+          loofah (~> 2.12.0)
+
+        RUBY VERSION
+           #{Bundler::RubyVersion.system}
+
+        BUNDLED WITH
+           #{Bundler::VERSION}
+      L
+    end
+
+    it "automatically fixes the lockfile" do
+      bundle "config set --local path vendor/bundle"
+
+      simulate_platform "x86_64-linux" do
+        bundle "install", :artifice => "compact_index"
+      end
+
+      expect(lockfile).to eq <<~L
+        GEM
+          remote: https://gem.repo4/
+          specs:
+            crass (1.0.6)
+            loofah (2.12.0)
+              crass (~> 1.0.2)
+              nokogiri (>= 1.5.9)
+            nokogiri (1.12.4-x86_64-darwin)
+              racc (~> 1.4)
+            nokogiri (1.12.4-x86_64-linux)
+              racc (~> 1.4)
+            racc (1.5.2)
+
+        PLATFORMS
+          x86_64-darwin-20
+          x86_64-linux
+
+        DEPENDENCIES
+          loofah (~> 2.12.0)
+
+        RUBY VERSION
+           #{Bundler::RubyVersion.system}
+
+        BUNDLED WITH
+           #{Bundler::VERSION}
+      L
+    end
+  end
+
   context "with --local flag" do
     before do
       system_gems "rack-1.0.0", :path => default_bundle_path
-- 
cgit v1.2.1


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

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