class Gem::DependencyResolver::InstallerSet ## # List of Gem::Specification objects that must always be installed. attr_reader :always_install ## # Only install gems in the always_install list attr_accessor :ignore_dependencies ## # Do not look in the installed set when finding specifications. This is # used by the --install-dir option to `gem install` attr_accessor :ignore_installed def initialize domain @domain = domain @f = Gem::SpecFetcher.fetcher @all = Hash.new { |h,k| h[k] = [] } @always_install = [] @ignore_dependencies = false @ignore_installed = false @loaded_remote_specs = [] @specs = {} end ## # Should local gems should be considered? def consider_local? @domain == :both or @domain == :local end ## # Should remote gems should be considered? def consider_remote? @domain == :both or @domain == :remote end ## # Returns an array of IndexSpecification objects matching DependencyRequest # +req+. def find_all req res = [] dep = req.dependency return res if @ignore_dependencies and @always_install.none? { |spec| dep.matches_spec? spec } name = dep.name dep.matching_specs.each do |gemspec| next if @always_install.include? gemspec res << Gem::DependencyResolver::InstalledSpecification.new(self, gemspec) end unless @ignore_installed if consider_local? then local_source = Gem::Source::Local.new if spec = local_source.find_gem(name, dep.requirement) then res << Gem::DependencyResolver::IndexSpecification.new( self, spec.name, spec.version, local_source, spec.platform) end end if consider_remote? then load_remote_specs dep @all[name].each do |remote_source, n| if dep.match? n then res << Gem::DependencyResolver::IndexSpecification.new( self, n.name, n.version, remote_source, n.platform) end end end res end def inspect # :nodoc: always_install = @always_install.map { |s| s.full_name } '#<%s domain: %s specs: %p always install: %p>' % [ self.class, @domain, @specs.keys, always_install, ] end ## # Loads remote prerelease specs if +dep+ is a prerelease dependency def load_remote_specs dep types = [:released] types << :prerelease if dep.prerelease? types.each do |type| next if @loaded_remote_specs.include? type @loaded_remote_specs << type list, = @f.available_specs type list.each do |uri, specs| specs.each do |n| @all[n.name] << [uri, n] end end end end ## # Called from IndexSpecification to get a true Specification # object. def load_spec name, ver, platform, source key = "#{name}-#{ver}-#{platform}" @specs.fetch key do tuple = Gem::NameTuple.new name, ver, platform @specs[key] = source.fetch_spec tuple end end ## # No prefetching needed since we load the whole index in initially. def prefetch(reqs) end def pretty_print q # :nodoc: q.group 2, '[InstallerSet', ']' do q.breakable q.text "domain: #{@domain}" q.breakable q.text 'specs: ' q.pp @specs.keys q.breakable q.text 'always install: ' q.pp @always_install end end end