From f96c332f5c00cd0fee0da79b6d415785bfa8d1f8 Mon Sep 17 00:00:00 2001 From: Edouard CHIN Date: Mon, 29 Sep 2025 02:20:57 +0200 Subject: [rubygems/rubygems] Fix `bundle install` when the Gemfile contains "install_if" git gems: - Fix https://github.com/rubygems/rubygems/pull/8985 - ### Problem If you have a Gemfile that contains a `install_if` git gem, it will be impossible to add other gems in the Gemfile and run `bundle install`, you'll get a "The git source [...] is not yet checked out". ### Context The change that modified this behaviour was in https://github.com/rubygems/rubygems/commit/abbea0cc94dd, and the issue is about the call to `current_dependencies`. This call filters out irrelevant dependencies such as the one that get condtionnally installed. By doing so, we skip over setting the source based of the lockfile for that dependency https://github.com/rubygems/rubygems/blob/ade324bdc8ea77b342f203cb7f3929a456d725ed/bundler/lib/bundler/definition.rb#L978 Ultimately, because of this, the dependency source doesn't have any additional information such as the `revision`. Down the line, when we end up to converge the spec, Bundler will attempt to get the revision for that spec but won't be able to because the git source isn't configured to allow running git operations. ### Solution Filter out the irrelevant only spec only after we have set its source. https://github.com/rubygems/rubygems/commit/d2af439671 --- lib/bundler/definition.rb | 12 +++++-- spec/bundler/lock/lockfile_spec.rb | 68 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 49627cc562..cc2394fda6 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -282,12 +282,17 @@ module Bundler end def filter_relevant(dependencies) - platforms_array = [Bundler.generic_local_platform].freeze dependencies.select do |d| - d.should_include? && !d.gem_platforms(platforms_array).empty? + relevant_deps?(d) end end + def relevant_deps?(dep) + platforms_array = [Bundler.generic_local_platform].freeze + + dep.should_include? && !dep.gem_platforms(platforms_array).empty? + end + def locked_dependencies @locked_deps.values end @@ -973,10 +978,11 @@ module Bundler @missing_lockfile_dep = nil @changed_dependencies = [] - current_dependencies.each do |dep| + @dependencies.each do |dep| if dep.source dep.source = sources.get(dep.source) end + next unless relevant_deps?(dep) name = dep.name diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb index 4b767c7415..02e53454d8 100644 --- a/spec/bundler/lock/lockfile_spec.rb +++ b/spec/bundler/lock/lockfile_spec.rb @@ -2111,6 +2111,74 @@ RSpec.describe "the lockfile format" do L end + it "successfully updates the lockfile when a new gem is added in the Gemfile includes a gem that shouldn't be included" do + build_repo4 do + build_gem "logger", "1.7.0" + build_gem "rack", "3.2.0" + build_gem "net-smtp", "0.5.0" + end + + gemfile <<~G + source "#{file_uri_for(gem_repo4)}" + gem "logger" + gem "net-smtp" + + install_if -> { false } do + gem 'rack', github: 'rack/rack' + end + G + + lockfile <<~L + GIT + remote: https://github.com/rack/rack.git + revision: 2fface9ac09fc582a81386becd939c987ad33f99 + specs: + rack (3.2.0) + + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + logger (1.7.0) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + logger + rack! + + BUNDLED WITH + #{Bundler::VERSION} + L + + bundle "install" + + expect(lockfile).to eq <<~L + GIT + remote: https://github.com/rack/rack.git + revision: 2fface9ac09fc582a81386becd939c987ad33f99 + specs: + rack (3.2.0) + + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + logger (1.7.0) + net-smtp (0.5.0) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + logger + net-smtp + rack! + + BUNDLED WITH + #{Bundler::VERSION} + L + end + shared_examples_for "a lockfile missing dependent specs" do it "auto-heals" do build_repo4 do -- cgit v1.2.3