From d34bcd693c550459180639843d015a73da359fd0 Mon Sep 17 00:00:00 2001 From: Cody Cutrer Date: Fri, 17 May 2024 17:09:09 -0600 Subject: [PATCH] fix syncing transitive dependencies when the root dependency is in conflict just take the output of the check command, and force any downstreams of those conflicts to update to the parent --- lib/bundler/multilock.rb | 15 ++++++++++----- lib/bundler/multilock/check.rb | 3 ++- spec/bundler/multilock_spec.rb | 4 ---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/bundler/multilock.rb b/lib/bundler/multilock.rb index 1b5ce8e..53660e7 100644 --- a/lib/bundler/multilock.rb +++ b/lib/bundler/multilock.rb @@ -175,10 +175,11 @@ def after_install_all(install: true) # already up to date? up_to_date = false + conflicts = Set.new Bundler.settings.temporary(frozen: true) do Bundler.ui.silence do up_to_date = checker.base_check(lockfile_definition, check_missing_deps: true) && - checker.deep_check(lockfile_definition) + checker.deep_check(lockfile_definition, conflicts: conflicts) end end if up_to_date @@ -247,10 +248,14 @@ def after_install_all(install: true) next :self if parent_spec.nil? next spec_precedences[spec.name] if spec_precedences.key?(spec.name) - precedence = :self if cache.conflicting_requirements?(lockfile_name, - parent_lockfile_name, - spec, - parent_spec) + precedence = if !(cache.reverse_dependencies(lockfile_name)[spec.name] & conflicts).empty? + :parent + elsif cache.conflicting_requirements?(lockfile_name, + parent_lockfile_name, + spec, + parent_spec) + :self + end spec_precedences[spec.name] = precedence || :parent end diff --git a/lib/bundler/multilock/check.rb b/lib/bundler/multilock/check.rb index 0180556..20b9d1d 100644 --- a/lib/bundler/multilock/check.rb +++ b/lib/bundler/multilock/check.rb @@ -88,7 +88,7 @@ def base_check(lockfile_definition, check_missing_deps: false) # this checks for mismatches between the parent lockfile and the given lockfile, # and for pinned dependencies in lockfiles requiring them - def deep_check(lockfile_definition) + def deep_check(lockfile_definition, conflicts: nil) lockfile_name = lockfile_definition[:lockfile] @cache.deep_check(lockfile_name) do success = true @@ -156,6 +156,7 @@ def deep_check(lockfile_definition) "does not match the parent lockfile's version " \ "(@#{parent_spec.version}#{parent_spec.git_version}); " \ "this may be due to a conflicting requirement, which would require manual resolution.") + conflicts&.add(spec.name) success = false end diff --git a/spec/bundler/multilock_spec.rb b/spec/bundler/multilock_spec.rb index e60bfe4..be2c413 100644 --- a/spec/bundler/multilock_spec.rb +++ b/spec/bundler/multilock_spec.rb @@ -815,10 +815,6 @@ end it "keeps transitive dependencies in sync, even when the intermediate deps are conflicting" do - pending "this spec was broken when improving _not_ unlocking all gems when syncing to alternate lockfiles. " \ - "it was determined that until such a problem arises again, it's not worth the effort to fix at " \ - "the moment" - orig_gemfile = <<~RUBY gem "ddtrace", "~> 1.13"