In Files

  • rubygems/source_info_cache.rb

Class/Module Index [+]

Quicksearch

Gem::SourceInfoCache

SourceInfoCache stores a copy of the gem index for each gem source.

There are two possible cache locations, the system cache and the user cache:

  • The system cache is preferred if it is writable or can be created.

  • The user cache is used otherwise

Once a cache is selected, it will be used for all operations. SourceInfoCache will not switch between cache files dynamically.

Cache data is a Hash mapping a source URI to a SourceInfoCacheEntry.

Public Class Methods

cache(all = false) click to toggle source

The singleton Gem::SourceInfoCache. If all is true, a full refresh will be performed if the singleton instance is being initialized.

 
               # File rubygems/source_info_cache.rb, line 38
def self.cache(all = false)
  return @cache if @cache
  @cache = new
  @cache.refresh all if Gem.configuration.update_sources
  @cache
end
            
cache_data() click to toggle source
 
               # File rubygems/source_info_cache.rb, line 45
def self.cache_data
  cache.cache_data
end
            
latest_system_cache_file() click to toggle source

The name of the system cache file.

 
               # File rubygems/source_info_cache.rb, line 52
def self.latest_system_cache_file
  File.join File.dirname(system_cache_file),
            "latest_#{File.basename system_cache_file}"
end
            
latest_user_cache_file() click to toggle source

The name of the latest user cache file.

 
               # File rubygems/source_info_cache.rb, line 60
def self.latest_user_cache_file
  File.join File.dirname(user_cache_file),
            "latest_#{File.basename user_cache_file}"
end
            
reset() click to toggle source

Reset all singletons, discarding any changes.

 
               # File rubygems/source_info_cache.rb, line 68
def self.reset
  @cache = nil
  @system_cache_file = nil
  @user_cache_file = nil
end
            
search(*args) click to toggle source

Search all source indexes. See #search.

 
               # File rubygems/source_info_cache.rb, line 77
def self.search(*args)
  cache.search(*args)
end
            
search_with_source(*args) click to toggle source

Search all source indexes returning the source_uri. See #search_with_source.

 
               # File rubygems/source_info_cache.rb, line 85
def self.search_with_source(*args)
  cache.search_with_source(*args)
end
            
system_cache_file() click to toggle source

The name of the system cache file. (class method)

 
               # File rubygems/source_info_cache.rb, line 92
def self.system_cache_file
  @system_cache_file ||= Gem.default_system_source_cache_dir
end
            
user_cache_file() click to toggle source

The name of the user cache file.

 
               # File rubygems/source_info_cache.rb, line 99
def self.user_cache_file
  @user_cache_file ||=
    ENV['GEMCACHE'] || Gem.default_user_source_cache_dir
end
            

Public Instance Methods

cache_data() click to toggle source

The most recent cache data.

 
               # File rubygems/source_info_cache.rb, line 114
def cache_data
  return @cache_data if @cache_data
  cache_file # HACK writable check

  @only_latest = true

  @cache_data = read_cache_data latest_cache_file

  @cache_data
end
            
cache_file() click to toggle source

The name of the cache file.

 
               # File rubygems/source_info_cache.rb, line 128
def cache_file
  return @cache_file if @cache_file
  @cache_file = (try_file(system_cache_file) or
    try_file(user_cache_file) or
    raise "unable to locate a writable cache file")
end
            
flush() click to toggle source

Write the cache to a local file (if it is dirty).

 
               # File rubygems/source_info_cache.rb, line 138
def flush
  write_cache if @dirty
  @dirty = false
end
            
latest_cache_data() click to toggle source
 
               # File rubygems/source_info_cache.rb, line 143
def latest_cache_data
  latest_cache_data = {}

  cache_data.each do |repo, sice|
    latest = sice.source_index.latest_specs

    new_si = Gem::SourceIndex.new
    new_si.add_specs(*latest)

    latest_sice = Gem::SourceInfoCacheEntry.new new_si, sice.size
    latest_cache_data[repo] = latest_sice
  end

  latest_cache_data
end
            
latest_cache_file() click to toggle source

The name of the latest cache file.

 
               # File rubygems/source_info_cache.rb, line 162
def latest_cache_file
  File.join File.dirname(cache_file), "latest_#{File.basename cache_file}"
end
            
latest_system_cache_file() click to toggle source

The name of the latest system cache file.

 
               # File rubygems/source_info_cache.rb, line 169
def latest_system_cache_file
  self.class.latest_system_cache_file
end
            
latest_user_cache_file() click to toggle source

The name of the latest user cache file.

 
               # File rubygems/source_info_cache.rb, line 176
def latest_user_cache_file
  self.class.latest_user_cache_file
end
            
read_all_cache_data() click to toggle source

Merges the complete cache file into this Gem::SourceInfoCache.

 
               # File rubygems/source_info_cache.rb, line 183
def read_all_cache_data
  if @only_latest then
    @only_latest = false
    all_data = read_cache_data cache_file

    cache_data.update all_data do |source_uri, latest_sice, all_sice|
      all_sice.source_index.gems.update latest_sice.source_index.gems

      Gem::SourceInfoCacheEntry.new all_sice.source_index, latest_sice.size
    end

    begin
      refresh true
    rescue Gem::RemoteFetcher::FetchError
    end
  end
end
            
read_cache_data(file) click to toggle source

Reads cached data from file.

 
               # File rubygems/source_info_cache.rb, line 204
def read_cache_data(file)
  # Marshal loads 30-40% faster from a String, and 2MB on 20061116 is small
  data = open file, 'rb' do |fp| fp.read end
  cache_data = Marshal.load data

  cache_data.each do |url, sice|
    next unless sice.is_a?(Hash)
    update

    cache = sice['cache']
    size  = sice['size']

    if cache.is_a?(Gem::SourceIndex) and size.is_a?(Numeric) then
      new_sice = Gem::SourceInfoCacheEntry.new cache, size
      cache_data[url] = new_sice
    else # irreperable, force refetch.
      reset_cache_for url, cache_data
    end
  end

  cache_data
rescue Errno::ENOENT
  {}
rescue => e
  if Gem.configuration.really_verbose then
    say "Exception during cache_data handling: #{e.class} - #{e}"
    say "Cache file was: #{file}"
    say "\t#{e.backtrace.join "\n\t"}"
  end

  {}
end
            
refresh(all) click to toggle source

Refreshes each source in the cache from its repository. If all is false, only latest gems are updated.

 
               # File rubygems/source_info_cache.rb, line 241
def refresh(all)
  Gem.sources.each do |source_uri|
    cache_entry = cache_data[source_uri]
    if cache_entry.nil? then
      cache_entry = Gem::SourceInfoCacheEntry.new nil, 0
      cache_data[source_uri] = cache_entry
    end

    update if cache_entry.refresh source_uri, all
  end

  flush
end
            
reset_cache_data() click to toggle source
 
               # File rubygems/source_info_cache.rb, line 265
def reset_cache_data
  @cache_data = nil
  @only_latest = true
end
            
reset_cache_file() click to toggle source

Force cache file to be reset, useful for integration testing of rubygems

 
               # File rubygems/source_info_cache.rb, line 273
def reset_cache_file
  @cache_file = nil
end
            
reset_cache_for(url, cache_data) click to toggle source
 
               # File rubygems/source_info_cache.rb, line 255
def reset_cache_for(url, cache_data)
  say "Reseting cache for #{url}" if Gem.configuration.really_verbose

  sice = Gem::SourceInfoCacheEntry.new Gem::SourceIndex.new, 0
  sice.refresh url, false # HACK may be unnecessary, see ::cache and #refresh

  cache_data[url] = sice
  cache_data
end
            
search(pattern, platform_only = false, all = false) click to toggle source

Searches all source indexes. See Gem::SourceIndex#search for details on pattern and platform_only. If all is set to true, the full index will be loaded before searching.

 
               # File rubygems/source_info_cache.rb, line 282
def search(pattern, platform_only = false, all = false)
  read_all_cache_data if all

  cache_data.map do |source_uri, sic_entry|
    next unless Gem.sources.include? source_uri
    # TODO - Remove this gunk after 2008/11
    unless pattern.kind_of? Gem::Dependency then
      pattern = Gem::Dependency.new pattern, Gem::Requirement.default
    end
    sic_entry.source_index.search pattern, platform_only
  end.flatten.compact
end
            
search_with_source(pattern, only_platform = false, all = false) click to toggle source

Searches all source indexes for pattern. If only_platform is true, only gems matching Gem.platforms will be selected. Returns an Array of pairs containing the Gem::Specification found and the source_uri it was found at.

 
               # File rubygems/source_info_cache.rb, line 301
def search_with_source(pattern, only_platform = false, all = false)
  read_all_cache_data if all

  results = []

  cache_data.map do |source_uri, sic_entry|
    next unless Gem.sources.include? source_uri

    # TODO - Remove this gunk after 2008/11
    unless pattern.kind_of?(Gem::Dependency)
      pattern = Gem::Dependency.new(pattern, Gem::Requirement.default) 
    end

    sic_entry.source_index.search(pattern, only_platform).each do |spec|
      results << [spec, source_uri]
    end
  end

  results
end
            
set_cache_data(hash) click to toggle source

Set the source info cache data directly. This is mainly used for unit testing when we don't want to read a file system to grab the cached source index information. The hash should map a source URL into a SourceInfoCacheEntry.

 
               # File rubygems/source_info_cache.rb, line 328
def set_cache_data(hash)
  @cache_data = hash
  update
end
            
system_cache_file() click to toggle source

The name of the system cache file.

 
               # File rubygems/source_info_cache.rb, line 336
def system_cache_file
  self.class.system_cache_file
end
            
try_file(path) click to toggle source

Determine if path is a candidate for a cache file. Returns path if it is, nil if not.

 
               # File rubygems/source_info_cache.rb, line 344
def try_file(path)
  return path if File.writable? path
  return nil if File.exist? path

  dir = File.dirname path

  unless File.exist? dir then
    begin
      FileUtils.mkdir_p dir
    rescue RuntimeError, SystemCallError
      return nil
    end
  end

  return path if File.writable? dir

  nil
end
            
update() click to toggle source

Mark the cache as updated (i.e. dirty).

 
               # File rubygems/source_info_cache.rb, line 366
def update
  @dirty = true
end
            
user_cache_file() click to toggle source

The name of the user cache file.

 
               # File rubygems/source_info_cache.rb, line 373
def user_cache_file
  self.class.user_cache_file
end
            
write_cache() click to toggle source

Write data to the proper cache files.

 
               # File rubygems/source_info_cache.rb, line 380
def write_cache
  if not File.exist?(cache_file) or not @only_latest then
    open cache_file, 'wb' do |io|
      io.write Marshal.dump(cache_data)
    end
  end

  open latest_cache_file, 'wb' do |io|
    io.write Marshal.dump(latest_cache_data)
  end
end