diff options
Diffstat (limited to 'lib/rubygems/resolver/api_set.rb')
| -rw-r--r-- | lib/rubygems/resolver/api_set.rb | 87 |
1 files changed, 50 insertions, 37 deletions
diff --git a/lib/rubygems/resolver/api_set.rb b/lib/rubygems/resolver/api_set.rb index ee3046af63..3f443519d8 100644 --- a/lib/rubygems/resolver/api_set.rb +++ b/lib/rubygems/resolver/api_set.rb @@ -1,12 +1,14 @@ # frozen_string_literal: true + ## -# The global rubygems pool, available via the rubygems.org API. +# The global rubygems pool, available via the Compact Index API. # Returns instances of APISpecification. class Gem::Resolver::APISet < Gem::Resolver::Set + autoload :GemParser, File.expand_path("api_set/gem_parser", __dir__) ## - # The URI for the dependency API this APISet uses. + # The URI for the Compact Index API this APISet uses. attr_reader :dep_uri # :nodoc: @@ -21,19 +23,19 @@ class Gem::Resolver::APISet < Gem::Resolver::Set attr_reader :uri ## - # Creates a new APISet that will retrieve gems from +uri+ using the RubyGems - # API URL +dep_uri+ which is described at - # http://guides.rubygems.org/rubygems-org-api + # Creates a new APISet that will retrieve gems from +uri+ using the Compact + # Index API URL +dep_uri+ which is described at + # https://guides.rubygems.org/rubygems-org-compact-index-api - def initialize dep_uri = 'https://rubygems.org/api/v1/dependencies' + def initialize(dep_uri = "https://index.rubygems.org/info/") super() - dep_uri = URI dep_uri unless URI === dep_uri # for ruby 1.8 + dep_uri = Gem::URI dep_uri unless Gem::URI === dep_uri @dep_uri = dep_uri - @uri = dep_uri + '../..' + @uri = dep_uri + ".." - @data = Hash.new { |h,k| h[k] = [] } + @data = Hash.new {|h,k| h[k] = [] } @source = Gem::Source.new @uri @to_fetch = [] @@ -43,7 +45,7 @@ class Gem::Resolver::APISet < Gem::Resolver::Set # Return an array of APISpecification objects matching # DependencyRequest +req+. - def find_all req + def find_all(req) res = [] return res unless @remote @@ -53,7 +55,7 @@ class Gem::Resolver::APISet < Gem::Resolver::Set end versions(req.name).each do |ver| - if req.dependency.match? req.name, ver[:number] + if req.dependency.match? req.name, ver[:number], @prerelease res << Gem::Resolver::APISpecification.new(self, ver) end end @@ -65,41 +67,30 @@ class Gem::Resolver::APISet < Gem::Resolver::Set # A hint run by the resolver to allow the Set to fetch # data for DependencyRequests +reqs+. - def prefetch reqs + def prefetch(reqs) return unless @remote - names = reqs.map { |r| r.dependency.name } + names = reqs.map {|r| r.dependency.name } needed = names - @data.keys - @to_fetch @to_fetch += needed end def prefetch_now # :nodoc: - needed, @to_fetch = @to_fetch, [] - - uri = @dep_uri + "?gems=#{needed.sort.join ','}" - str = Gem::RemoteFetcher.fetcher.fetch_path uri - - loaded = [] - - Marshal.load(str).each do |ver| - name = ver[:name] - - @data[name] << ver - loaded << name - end + needed = @to_fetch + @to_fetch = [] - (needed - loaded).each do |missing| - @data[missing] = [] + needed.sort.each do |name| + versions(name) end end - def pretty_print q # :nodoc: - q.group 2, '[APISet', ']' do + def pretty_print(q) # :nodoc: + q.group 2, "[APISet", "]" do q.breakable q.text "URI: #{@dep_uri}" q.breakable - q.text 'gem names:' + q.text "gem names:" q.pp @data.keys end end @@ -107,20 +98,42 @@ class Gem::Resolver::APISet < Gem::Resolver::Set ## # Return data for all versions of the gem +name+. - def versions name # :nodoc: + def versions(name) # :nodoc: if @data.key?(name) return @data[name] end - uri = @dep_uri + "?gems=#{name}" - str = Gem::RemoteFetcher.fetcher.fetch_path uri + uri = @dep_uri + name + + begin + str = Gem::RemoteFetcher.fetcher.fetch_path uri + rescue Gem::RemoteFetcher::FetchError + @data[name] = [] + else + lines(str).each do |ver| + number, platform, dependencies, requirements = parse_gem(ver) - Marshal.load(str).each do |ver| - @data[ver[:name]] << ver + platform ||= "ruby" + dependencies = dependencies.map {|dep_name, reqs| [dep_name, reqs.join(", ")] } + requirements = requirements.map {|req_name, reqs| [req_name.to_sym, reqs] }.to_h + + @data[name] << { name: name, number: number, platform: platform, dependencies: dependencies, requirements: requirements } + end end @data[name] end -end + private + def lines(str) + lines = str.split("\n") + header = lines.index("---") + header ? lines[header + 1..-1] : lines + end + + def parse_gem(string) + @gem_parser ||= GemParser.new + @gem_parser.parse(string) + end +end |
