diff options
Diffstat (limited to 'lib/rubygems/available_set.rb')
-rw-r--r-- | lib/rubygems/available_set.rb | 200 |
1 files changed, 133 insertions, 67 deletions
diff --git a/lib/rubygems/available_set.rb b/lib/rubygems/available_set.rb index cd6df1ddc7..d8655afc34 100644 --- a/lib/rubygems/available_set.rb +++ b/lib/rubygems/available_set.rb @@ -1,95 +1,161 @@ -module Gem - class AvailableSet - Tuple = Struct.new(:spec, :source) +class Gem::AvailableSet - def initialize - @set = [] - @sorted = nil - end + include Enumerable - attr_reader :set + Tuple = Struct.new(:spec, :source) - def add(spec, source) - @set << Tuple.new(spec, source) - @sorted = nil - self - end + def initialize + @set = [] + @sorted = nil + end + + attr_reader :set + + def add(spec, source) + @set << Tuple.new(spec, source) + @sorted = nil + self + end - def <<(o) - case o - when AvailableSet - s = o.set - when Array - s = o.map do |sp,so| - if !sp.kind_of?(Specification) or !so.kind_of?(Source) - raise TypeError, "Array must be in [[spec, source], ...] form" - end - - Tuple.new(sp,so) + def <<(o) + case o + when Gem::AvailableSet + s = o.set + when Array + s = o.map do |sp,so| + if !sp.kind_of?(Gem::Specification) or !so.kind_of?(Gem::Source) + raise TypeError, "Array must be in [[spec, source], ...] form" end - else - raise TypeError, "Must be an AvailableSet" + + Tuple.new(sp,so) end + else + raise TypeError, "must be a Gem::AvailableSet" + end - @set += s - @sorted = nil + @set += s + @sorted = nil - self - end + self + end + + ## + # Yields each Tuple in this AvailableSet + + def each + return enum_for __method__ unless block_given? - def empty? - @set.empty? + @set.each do |tuple| + yield tuple end + end + + ## + # Yields the Gem::Specification for each Tuple in this AvailableSet + + def each_spec + return enum_for __method__ unless block_given? - def all_specs - @set.map { |t| t.spec } + each do |tuple| + yield tuple.spec end + end + + def empty? + @set.empty? + end - def match_platform! - @set.reject! { |t| !Gem::Platform.match(t.spec.platform) } - @sorted = nil - self + def all_specs + @set.map { |t| t.spec } + end + + def match_platform! + @set.reject! { |t| !Gem::Platform.match(t.spec.platform) } + @sorted = nil + self + end + + def sorted + @sorted ||= @set.sort do |a,b| + i = b.spec <=> a.spec + i != 0 ? i : (a.source <=> b.source) end + end - def sorted - @sorted ||= @set.sort do |a,b| - i = b.spec <=> a.spec - i != 0 ? i : (a.source <=> b.source) - end + def size + @set.size + end + + def source_for(spec) + f = @set.find { |t| t.spec == spec } + f.source + end + + ## + # Converts this AvailableSet into a RequestSet that can be used to install + # gems. + # + # If +development+ is :none then no development dependencies are installed. + # Other options are :shallow for only direct development dependencies of the + # gems in this set or :all for all development dependencies. + + def to_request_set development = :none + request_set = Gem::RequestSet.new + request_set.development = :all == development + + each_spec do |spec| + request_set.always_install << spec + + request_set.gem spec.name, spec.version + request_set.import spec.development_dependencies if + :shallow == development end - def size - @set.size + request_set + end + + ## + # + # Used by the Resolver, the protocol to use a AvailableSet as a + # search Set. + + def find_all(req) + dep = req.dependency + + match = @set.find_all do |t| + dep.matches_spec? t.spec end - def source_for(spec) - f = @set.find { |t| t.spec == spec } - f.source + match.map do |t| + Gem::Resolver::LocalSpecification.new(self, t.spec, t.source) end + end - def pick_best! - return self if empty? + def prefetch(reqs) + end - @set = [sorted.first] - @sorted = nil - self - end + def pick_best! + return self if empty? - def remove_installed!(dep) - @set.reject! do |t| - # already locally installed - Gem::Specification.any? do |installed_spec| - dep.name == installed_spec.name and - dep.requirement.satisfied_by? installed_spec.version - end - end + @set = [sorted.first] + @sorted = nil + self + end - @sorted = nil - self + def remove_installed!(dep) + @set.reject! do |t| + # already locally installed + Gem::Specification.any? do |installed_spec| + dep.name == installed_spec.name and + dep.requirement.satisfied_by? installed_spec.version + end end - def inject_into_list(dep_list) - @set.each { |t| dep_list.add t.spec } - end + @sorted = nil + self + end + + def inject_into_list(dep_list) + @set.each { |t| dep_list.add t.spec } end end |