mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
248fae0ec4
We have two representations of a source. Once used for sorting, which should not depend on the source's state, but solely on its static information, like remotes. Another one used for error and informational messages, which should properly inform about the exact state of the source when the message is printed. This commit makes the latter be the default implementation of `to_s`, so that error and informational messages are more accurate by default. https://github.com/rubygems/rubygems/commit/b5f2b88957
68 lines
2.1 KiB
Ruby
68 lines
2.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Bundler
|
|
class Source
|
|
class RubygemsAggregate
|
|
attr_reader :source_map, :sources
|
|
|
|
def initialize(sources, source_map)
|
|
@sources = sources
|
|
@source_map = source_map
|
|
|
|
@index = build_index
|
|
end
|
|
|
|
def specs
|
|
@index
|
|
end
|
|
|
|
def identifier
|
|
to_s
|
|
end
|
|
|
|
def to_s
|
|
"any of the sources"
|
|
end
|
|
|
|
private
|
|
|
|
def build_index
|
|
Index.build do |idx|
|
|
dependency_names = source_map.pinned_spec_names
|
|
|
|
sources.all_sources.each do |source|
|
|
source.dependency_names = dependency_names - source_map.pinned_spec_names(source)
|
|
idx.add_source source.specs
|
|
dependency_names.concat(source.unmet_deps).uniq!
|
|
end
|
|
|
|
double_check_for_index(idx, dependency_names)
|
|
end
|
|
end
|
|
|
|
# Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
|
|
# sources A and B. At this point, the API request will have found all the versions of Bar in source A,
|
|
# but will not have found any versions of Bar from source B, which is a problem if the requested version
|
|
# of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
|
|
# each spec we found, we add all possible versions from all sources to the index.
|
|
def double_check_for_index(idx, dependency_names)
|
|
pinned_names = source_map.pinned_spec_names
|
|
|
|
names = :names # do this so we only have to traverse to get dependency_names from the index once
|
|
unmet_dependency_names = lambda do
|
|
return names unless names == :names
|
|
new_names = sources.all_sources.map(&:dependency_names_to_double_check)
|
|
return names = nil if new_names.compact!
|
|
names = new_names.flatten(1).concat(dependency_names)
|
|
names.uniq!
|
|
names -= pinned_names
|
|
names
|
|
end
|
|
|
|
sources.all_sources.each do |source|
|
|
source.double_check_for(unmet_dependency_names)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|