@@ -91,7 +91,8 @@ def search_for_dependency(dependency, matching_platform = true, type: nil)
9191
9292 rejected_specs = { }
9393
94- list , errors = available_specs ( type || dependency . identity )
94+ specs_type = type || dependency . identity
95+ list , errors = available_specs ( specs_type )
9596
9697 list . each do |source , specs |
9798 if dependency . name . is_a? ( String ) && specs . respond_to? ( :bsearch )
@@ -100,17 +101,20 @@ def search_for_dependency(dependency, matching_platform = true, type: nil)
100101 specs = specs [ start_index ...end_index ] if start_index && end_index
101102 end
102103
104+ specs = specs . select { |tup | dependency . match? ( tup ) }
105+ specs = decode_source_content_addressable_tuples ( source , specs , latest : specs_type == :latest )
106+
103107 found [ source ] = specs . select do |tup |
104- if dependency . match ?( tup )
105- if matching_platform && ! Gem :: Platform . match_gem? ( tup . platform , tup . name )
106- pm = (
107- rejected_specs [ dependency ] ||= \
108- Gem :: PlatformMismatch . new ( tup . name , tup . version ) )
109- pm . add_platform tup . platform
110- false
111- else
112- true
113- end
108+ if matching_platform && ! Gem :: Platform . match_gem ?( tup . platform , tup . name )
109+ pm = (
110+ rejected_specs [ dependency ] ||= \
111+ Gem :: PlatformMismatch . new ( tup . name , tup . version ) )
112+ pm . add_platform tup . platform
113+ false
114+ elsif matching_platform && ! ruby_abi_match? ( tup )
115+ false
116+ else
117+ true
114118 end
115119 end
116120 end
@@ -159,6 +163,7 @@ def spec_for_dependency(dependency, matching_platform = true)
159163 specs = [ ]
160164 tuples . each do |tup , source |
161165 spec = source . fetch_spec ( tup )
166+ spec . content_address = tup . content_address if tup . content_address
162167 rescue Gem ::RemoteFetcher ::FetchError => e
163168 errors << Gem ::SourceFetchProblem . new ( source , e )
164169 else
@@ -168,6 +173,17 @@ def spec_for_dependency(dependency, matching_platform = true)
168173 [ specs , errors ]
169174 end
170175
176+ ##
177+ # Decodes the content-addressable tuples in +spec_tuples+ ([tuple, source]
178+ # pairs) to carry their real platform and Ruby ABI via each source.
179+
180+ def decode_content_addressable_tuples ( spec_tuples , latest : false )
181+ spec_tuples . group_by { |_ , source | source } . flat_map do |source , source_tuples |
182+ tuples = source_tuples . map ( &:first )
183+ decode_source_content_addressable_tuples ( source , tuples , latest : latest ) . map { |tuple | [ tuple , source ] }
184+ end
185+ end
186+
171187 ##
172188 # Suggests gems based on the supplied +gem_name+. Returns an array of
173189 # alternative gem names.
@@ -290,4 +306,20 @@ def tuples_for(source, type, gracefully_ignore = false) # :nodoc:
290306 raise unless gracefully_ignore
291307 [ ]
292308 end
309+
310+ private
311+
312+ def decode_source_content_addressable_tuples ( source , tuples , latest : false ) # :nodoc:
313+ return tuples unless source . respond_to? ( :decode_content_addressable_tuples )
314+
315+ source . decode_content_addressable_tuples ( tuples , latest : latest )
316+ end
317+
318+ def ruby_abi_match? ( tuple ) # :nodoc:
319+ !tuple . ruby_abi || tuple . ruby_abi == current_ruby_abi
320+ end
321+
322+ def current_ruby_abi # :nodoc:
323+ @current_ruby_abi ||= Gem . ruby_version . segments . first ( 2 ) . join ( "." )
324+ end
293325end
0 commit comments