diff options
Diffstat (limited to 'lib/rubygems/resolver/api_set.rb')
-rw-r--r-- | lib/rubygems/resolver/api_set.rb | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/lib/rubygems/resolver/api_set.rb b/lib/rubygems/resolver/api_set.rb new file mode 100644 index 0000000000..60bf911063 --- /dev/null +++ b/lib/rubygems/resolver/api_set.rb @@ -0,0 +1,75 @@ +## +# The global rubygems pool, available via the rubygems.org API. +# Returns instances of APISpecification. + +class Gem::Resolver::APISet < Gem::Resolver::Set + + ## + # The URI for the dependency API this APISet uses. + + attr_reader :dep_uri # :nodoc: + + ## + # Creates a new APISet that will retrieve gems from +uri+ using the RubyGems + # API described at http://guides.rubygems.org/rubygems-org-api + + def initialize uri = 'https://rubygems.org/api/v1/dependencies' + uri = URI uri unless URI === uri # for ruby 1.8 + @data = Hash.new { |h,k| h[k] = [] } + @dep_uri = uri + end + + ## + # Return an array of APISpecification objects matching + # DependencyRequest +req+. + + def find_all req + res = [] + + versions(req.name).each do |ver| + if req.dependency.match? req.name, ver[:number] + res << Gem::Resolver::APISpecification.new(self, ver) + end + end + + res + end + + ## + # A hint run by the resolver to allow the Set to fetch + # data for DependencyRequests +reqs+. + + def prefetch reqs + names = reqs.map { |r| r.dependency.name } + needed = names.find_all { |d| !@data.key?(d) } + + return if needed.empty? + + uri = @dep_uri + "?gems=#{needed.sort.join ','}" + str = Gem::RemoteFetcher.fetcher.fetch_path uri + + Marshal.load(str).each do |ver| + @data[ver[:name]] << ver + end + end + + ## + # Return data for all versions of the gem +name+. + + def versions name # :nodoc: + if @data.key?(name) + return @data[name] + end + + uri = @dep_uri + "?gems=#{name}" + str = Gem::RemoteFetcher.fetcher.fetch_path uri + + Marshal.load(str).each do |ver| + @data[ver[:name]] << ver + end + + @data[name] + end + +end + |