1class Gem::AvailableSet 2 Tuple = Struct.new(:spec, :source) 3 4 def initialize 5 @set = [] 6 @sorted = nil 7 end 8 9 attr_reader :set 10 11 def add(spec, source) 12 @set << Tuple.new(spec, source) 13 @sorted = nil 14 self 15 end 16 17 def <<(o) 18 case o 19 when Gem::AvailableSet 20 s = o.set 21 when Array 22 s = o.map do |sp,so| 23 if !sp.kind_of?(Gem::Specification) or !so.kind_of?(Gem::Source) 24 raise TypeError, "Array must be in [[spec, source], ...] form" 25 end 26 27 Tuple.new(sp,so) 28 end 29 else 30 raise TypeError, "must be a Gem::AvailableSet" 31 end 32 33 @set += s 34 @sorted = nil 35 36 self 37 end 38 39 def empty? 40 @set.empty? 41 end 42 43 def all_specs 44 @set.map { |t| t.spec } 45 end 46 47 def match_platform! 48 @set.reject! { |t| !Gem::Platform.match(t.spec.platform) } 49 @sorted = nil 50 self 51 end 52 53 def sorted 54 @sorted ||= @set.sort do |a,b| 55 i = b.spec <=> a.spec 56 i != 0 ? i : (a.source <=> b.source) 57 end 58 end 59 60 def size 61 @set.size 62 end 63 64 def source_for(spec) 65 f = @set.find { |t| t.spec == spec } 66 f.source 67 end 68 69 def pick_best! 70 return self if empty? 71 72 @set = [sorted.first] 73 @sorted = nil 74 self 75 end 76 77 def remove_installed!(dep) 78 @set.reject! do |t| 79 # already locally installed 80 Gem::Specification.any? do |installed_spec| 81 dep.name == installed_spec.name and 82 dep.requirement.satisfied_by? installed_spec.version 83 end 84 end 85 86 @sorted = nil 87 self 88 end 89 90 def inject_into_list(dep_list) 91 @set.each { |t| dep_list.add t.spec } 92 end 93end 94