Module: StillActive::CompactIndexClient

Extended by:
CompactIndexClient
Included in:
CompactIndexClient
Defined in:
lib/still_active/compact_index_client.rb

Overview

The RubyGems compact index (/info/<gem>), which is what Bundler itself resolves through. It is not built by merging upstream metadata, so it lists the versions actually resolvable from the source even when a member remote (a legacy private gem host) can't answer the metadata endpoint Artifactory prefers (#142).

The protocol is generic: any host that serves it (rubygems.org, Artifactory, a direct Contribsys/Gemstash/geminabox source) works here. The caller supplies the source URI and any auth headers, so this stays free of host-specific credential handling.

Instance Method Summary collapse

Instance Method Details

#versions(gem_name:, source_uri:, headers: {}) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/still_active/compact_index_client.rb', line 22

def versions(gem_name:, source_uri:, headers: {})
  base = URI(source_uri.chomp("/"))
  path = "#{base.path}/info/#{CGI.escape(gem_name)}"
  body = HttpHelper.get_text(base, path, headers: headers)
  return [] if body.nil? || body.empty?

  result = parse(body)
  # The parser never raises: a non-index 200 (an auth wall or HTML error page
  # served with status 200) yields no versions instead of an error. Since the
  # compact index is the primary source, a silent empty result would look
  # identical to a clean parse and hide a broken source, so say so and let the
  # caller fall through. A header-only index (every version yanked) is valid
  # and empty, so the "---" marker, not mere emptiness, tells them apart.
  if result.empty? && !compact_index?(body)
    warn("warning: #{base.host} answered /info/#{gem_name} with a 200 that is not a RubyGems " \
      "compact index (an auth wall or error page?); ignoring it and trying other sources")
  end
  result
end