@@ -84,9 +84,9 @@ def solve_versions(root:, logger:)
8484 rescue PubGrub ::SolveFailure => e
8585 incompatibility = e . incompatibility
8686
87- names_to_unlock , names_to_allow_prereleases_for , extended_explanation = find_names_to_relax ( incompatibility )
87+ names_to_unlock , names_to_allow_prereleases_for , names_to_allow_remote_specs_for , extended_explanation = find_names_to_relax ( incompatibility )
8888
89- names_to_relax = names_to_unlock + names_to_allow_prereleases_for
89+ names_to_relax = names_to_unlock + names_to_allow_prereleases_for + names_to_allow_remote_specs_for
9090
9191 if names_to_relax . any?
9292 if names_to_unlock . any?
@@ -96,11 +96,17 @@ def solve_versions(root:, logger:)
9696 end
9797
9898 if names_to_allow_prereleases_for . any?
99- Bundler . ui . debug "Found conflicts with dependencies with prereleases. Will retrying considering prereleases for #{ names_to_allow_prereleases_for . join ( ", " ) } ..." , true
99+ Bundler . ui . debug "Found conflicts with dependencies with prereleases. Will retry considering prereleases for #{ names_to_allow_prereleases_for . join ( ", " ) } ..." , true
100100
101101 @base . include_prereleases ( names_to_allow_prereleases_for )
102102 end
103103
104+ if names_to_allow_remote_specs_for . any?
105+ Bundler . ui . debug "Found conflicts with local versions of #{ names_to_allow_remote_specs_for . join ( ", " ) } . Will retry considering remote versions..." , true
106+
107+ @base . include_remote_specs ( names_to_allow_remote_specs_for )
108+ end
109+
104110 root , logger = setup_solver
105111
106112 Bundler . ui . debug "Retrying resolution..." , true
@@ -120,6 +126,7 @@ def solve_versions(root:, logger:)
120126 def find_names_to_relax ( incompatibility )
121127 names_to_unlock = [ ]
122128 names_to_allow_prereleases_for = [ ]
129+ names_to_allow_remote_specs_for = [ ]
123130 extended_explanation = nil
124131
125132 while incompatibility . conflict?
@@ -134,6 +141,8 @@ def find_names_to_relax(incompatibility)
134141 names_to_unlock << name
135142 elsif package . ignores_prereleases? && @all_specs [ name ] . any? { |s | s . version . prerelease? }
136143 names_to_allow_prereleases_for << name
144+ elsif package . prefer_local? && @all_specs [ name ] . any? { |s | !s . is_a? ( StubSpecification ) }
145+ names_to_allow_remote_specs_for << name
137146 end
138147
139148 no_versions_incompat = [ cause . incompatibility , cause . satisfier ] . find { |incompat | incompat . cause . is_a? ( PubGrub ::Incompatibility ::NoVersions ) }
@@ -143,7 +152,7 @@ def find_names_to_relax(incompatibility)
143152 end
144153 end
145154
146- [ names_to_unlock . uniq , names_to_allow_prereleases_for . uniq , extended_explanation ]
155+ [ names_to_unlock . uniq , names_to_allow_prereleases_for . uniq , names_to_allow_remote_specs_for . uniq , extended_explanation ]
147156 end
148157
149158 def parse_dependency ( package , dependency )
@@ -244,7 +253,7 @@ def incompatibilities_for(package, version)
244253
245254 def all_versions_for ( package )
246255 name = package . name
247- results = ( @base [ name ] + filter_prereleases ( @all_specs [ name ] , package ) ) . uniq { |spec | [ spec . version . hash , spec . platform ] }
256+ results = ( @base [ name ] + filter_specs ( @all_specs [ name ] , package ) ) . uniq { |spec | [ spec . version . hash , spec . platform ] }
248257
249258 if name == "bundler" && !bundler_pinned_to_current_version?
250259 bundler_spec = Gem . loaded_specs [ "bundler" ]
@@ -368,12 +377,22 @@ def filter_matching_specs(specs, requirements)
368377 end
369378 end
370379
380+ def filter_specs ( specs , package )
381+ filter_remote_specs ( filter_prereleases ( specs , package ) , package )
382+ end
383+
371384 def filter_prereleases ( specs , package )
372385 return specs unless package . ignores_prereleases? && specs . size > 1
373386
374387 specs . reject { |s | s . version . prerelease? }
375388 end
376389
390+ def filter_remote_specs ( specs , package )
391+ return specs unless package . prefer_local?
392+
393+ specs . select { |s | s . is_a? ( StubSpecification ) }
394+ end
395+
377396 # Ignore versions that depend on themselves incorrectly
378397 def filter_invalid_self_dependencies ( specs , name )
379398 specs . reject do |s |
@@ -405,10 +424,13 @@ def prepare_dependencies(requirements, packages)
405424
406425 dep_range = dep_constraint . range
407426 versions = select_sorted_versions ( dep_package , dep_range )
408- if versions . empty? && dep_package . ignores_prereleases?
409- @all_versions . delete ( dep_package )
410- @sorted_versions . delete ( dep_package )
411- dep_package . consider_prereleases!
427+ if versions . empty?
428+ if dep_package . ignores_prereleases? || dep_package . prefer_local?
429+ @all_versions . delete ( dep_package )
430+ @sorted_versions . delete ( dep_package )
431+ end
432+ dep_package . consider_prereleases! if dep_package . ignores_prereleases?
433+ dep_package . consider_remote_versions! if dep_package . prefer_local?
412434 versions = select_sorted_versions ( dep_package , dep_range )
413435 end
414436
0 commit comments