class Gem::CompactIndexClient

The CompactIndexClient fetches and parses the compact index files (names, versions and info/) served by a gem server, keeping a local cache so subsequent fetches only transfer what changed.

This is the single shared client: Bundler ships a copy of it and uses it underneath its own fetcher orchestration, injecting its fetcher and filesystem access hook.

Constants

DEBUG_MUTEX
INFO_DEPS
INFO_NAME

info returns an Array of INFO Arrays. Each INFO Array has the following indices:

INFO_PLATFORM
INFO_REQS
INFO_SUFFIX
INFO_VERSION
SUPPORTED_DIGESTS

Public Class Methods

# File lib/rubygems/compact_index_client.rb, line 30
def self.debug
  return unless ENV["DEBUG_COMPACT_INDEX"]
  DEBUG_MUTEX.synchronize { warn("[#{self}] #{yield}") }
end

Filesystem reads and writes funnel through this hook so that a host (e.g. Bundler) can translate low-level Errno exceptions into its own friendlier errors. The default just yields the path.

# File lib/rubygems/compact_index_client.rb, line 40
def self.filesystem_access(path, action = :write, &block)
  if @filesystem_access
    @filesystem_access.call(path, action, &block)
  else
    yield path
  end
end
# File lib/rubygems/compact_index_client.rb, line 48
def self.filesystem_access=(hook)
  @filesystem_access = hook
end

The client is instantiated with:

  • ‘directory`: the root directory where the cache files are stored.

  • ‘fetcher`: (optional) an object that responds to call(uri_path, headers) and returns a Gem::Net::HTTP response. When the fetcher is not provided, the client only reads cached files from disk.

# File lib/rubygems/compact_index_client.rb, line 63
def initialize(directory, fetcher = nil)
  @cache = Cache.new(directory, fetcher)
  @parser = Parser.new(@cache)
end

Public Instance Methods

# File lib/rubygems/compact_index_client.rb, line 102
def available?
  Gem::CompactIndexClient.debug { "available?" }
  @parser.available?
end
# File lib/rubygems/compact_index_client.rb, line 78
def dependencies(names)
  Gem::CompactIndexClient.debug { "dependencies(#{names})" }
  names.map {|name| info(name) }
end

Fetches a single gem’s info without consulting the versions index, using a conditional request to refresh the cached file. Useful when only a few gems are needed and the versions index download would dominate, as in gem install.

# File lib/rubygems/compact_index_client.rb, line 92
def fetch_info(name)
  Gem::CompactIndexClient.debug { "fetch_info(#{name})" }
  @parser.parse_info(@cache.fetch_info(name), name)
end
# File lib/rubygems/compact_index_client.rb, line 83
def info(name)
  Gem::CompactIndexClient.debug { "info(#{name})" }
  @parser.info(name)
end
# File lib/rubygems/compact_index_client.rb, line 97
def latest_version(name)
  Gem::CompactIndexClient.debug { "latest_version(#{name})" }
  @parser.info(name).map {|d| Gem::Version.new(d[INFO_VERSION]) }.max
end
# File lib/rubygems/compact_index_client.rb, line 68
def names
  Gem::CompactIndexClient.debug { "names" }
  @parser.names
end
# File lib/rubygems/compact_index_client.rb, line 107
def reset!
  Gem::CompactIndexClient.debug { "reset!" }
  @cache.reset!
end
# File lib/rubygems/compact_index_client.rb, line 73
def versions
  Gem::CompactIndexClient.debug { "versions" }
  @parser.versions
end