aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rubygems/dependency_resolver/installer_set.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rubygems/dependency_resolver/installer_set.rb')
-rw-r--r--lib/rubygems/dependency_resolver/installer_set.rb130
1 files changed, 130 insertions, 0 deletions
diff --git a/lib/rubygems/dependency_resolver/installer_set.rb b/lib/rubygems/dependency_resolver/installer_set.rb
new file mode 100644
index 0000000000..7de052df77
--- /dev/null
+++ b/lib/rubygems/dependency_resolver/installer_set.rb
@@ -0,0 +1,130 @@
+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:
+ '#<%s domain: %s specs: %p>' % [ self.class, @domain, @specs.keys ]
+ 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, source
+ key = "#{name}-#{ver}"
+ @specs[key] ||= source.fetch_spec Gem::NameTuple.new name, ver
+ end
+
+ ##
+ # No prefetching needed since we load the whole index in initially.
+
+ def prefetch(reqs)
+ end
+
+end
+