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.
The singleton Gem::SourceInfoCache. If all is true, a full refresh will be performed if the singleton instance is being initialized.
# File lib/rubygems/source_info_cache.rb, line 38 38: def self.cache(all = false) 39: return @cache if @cache 40: @cache = new 41: @cache.refresh all if Gem.configuration.update_sources 42: @cache 43: end
# File lib/rubygems/source_info_cache.rb, line 45 45: def self.cache_data 46: cache.cache_data 47: end
The name of the system cache file.
# File lib/rubygems/source_info_cache.rb, line 52 52: def self.latest_system_cache_file 53: File.join File.dirname(system_cache_file), 54: "latest_#{File.basename system_cache_file}" 55: end
The name of the latest user cache file.
# File lib/rubygems/source_info_cache.rb, line 60 60: def self.latest_user_cache_file 61: File.join File.dirname(user_cache_file), 62: "latest_#{File.basename user_cache_file}" 63: end
Reset all singletons, discarding any changes.
# File lib/rubygems/source_info_cache.rb, line 68 68: def self.reset 69: @cache = nil 70: @system_cache_file = nil 71: @user_cache_file = nil 72: end
Search all source indexes. See Gem::SourceInfoCache#search.
# File lib/rubygems/source_info_cache.rb, line 77 77: def self.search(*args) 78: cache.search(*args) 79: end
Search all source indexes returning the source_uri. See Gem::SourceInfoCache#search_with_source.
# File lib/rubygems/source_info_cache.rb, line 85 85: def self.search_with_source(*args) 86: cache.search_with_source(*args) 87: end
The most recent cache data.
# File lib/rubygems/source_info_cache.rb, line 114 114: def cache_data 115: return @cache_data if @cache_data 116: cache_file # HACK writable check 117: 118: @only_latest = true 119: 120: @cache_data = read_cache_data latest_cache_file 121: 122: @cache_data 123: end
The name of the cache file.
# File lib/rubygems/source_info_cache.rb, line 128 128: def cache_file 129: return @cache_file if @cache_file 130: @cache_file = (try_file(system_cache_file) or 131: try_file(user_cache_file) or 132: raise "unable to locate a writable cache file") 133: end
Write the cache to a local file (if it is dirty).
# File lib/rubygems/source_info_cache.rb, line 138 138: def flush 139: write_cache if @dirty 140: @dirty = false 141: end
# File lib/rubygems/source_info_cache.rb, line 143 143: def latest_cache_data 144: latest_cache_data = {} 145: 146: cache_data.each do |repo, sice| 147: latest = sice.source_index.latest_specs 148: 149: new_si = Gem::SourceIndex.new 150: new_si.add_specs(*latest) 151: 152: latest_sice = Gem::SourceInfoCacheEntry.new new_si, sice.size 153: latest_cache_data[repo] = latest_sice 154: end 155: 156: latest_cache_data 157: end
The name of the latest cache file.
# File lib/rubygems/source_info_cache.rb, line 162 162: def latest_cache_file 163: File.join File.dirname(cache_file), "latest_#{File.basename cache_file}" 164: end
The name of the latest system cache file.
# File lib/rubygems/source_info_cache.rb, line 169 169: def latest_system_cache_file 170: self.class.latest_system_cache_file 171: end
The name of the latest user cache file.
# File lib/rubygems/source_info_cache.rb, line 176 176: def latest_user_cache_file 177: self.class.latest_user_cache_file 178: end
Merges the complete cache file into this Gem::SourceInfoCache.
# File lib/rubygems/source_info_cache.rb, line 183 183: def read_all_cache_data 184: if @only_latest then 185: @only_latest = false 186: all_data = read_cache_data cache_file 187: 188: cache_data.update all_data do |source_uri, latest_sice, all_sice| 189: all_sice.source_index.gems.update latest_sice.source_index.gems 190: 191: Gem::SourceInfoCacheEntry.new all_sice.source_index, latest_sice.size 192: end 193: 194: begin 195: refresh true 196: rescue Gem::RemoteFetcher::FetchError 197: end 198: end 199: end
Reads cached data from file.
# File lib/rubygems/source_info_cache.rb, line 204 204: def read_cache_data(file) 205: # Marshal loads 30-40% faster from a String, and 2MB on 20061116 is small 206: data = open file, 'rb' do |fp| fp.read end 207: cache_data = Marshal.load data 208: 209: cache_data.each do |url, sice| 210: next unless sice.is_a?(Hash) 211: update 212: 213: cache = sice['cache'] 214: size = sice['size'] 215: 216: if cache.is_a?(Gem::SourceIndex) and size.is_a?(Numeric) then 217: new_sice = Gem::SourceInfoCacheEntry.new cache, size 218: cache_data[url] = new_sice 219: else # irreperable, force refetch. 220: reset_cache_for url, cache_data 221: end 222: end 223: 224: cache_data 225: rescue Errno::ENOENT 226: {} 227: rescue => e 228: if Gem.configuration.really_verbose then 229: say "Exception during cache_data handling: #{e.class} - #{e}" 230: say "Cache file was: #{file}" 231: say "\t#{e.backtrace.join "\n\t"}" 232: end 233: 234: {} 235: end
Refreshes each source in the cache from its repository. If all is false, only latest gems are updated.
# File lib/rubygems/source_info_cache.rb, line 241 241: def refresh(all) 242: Gem.sources.each do |source_uri| 243: cache_entry = cache_data[source_uri] 244: if cache_entry.nil? then 245: cache_entry = Gem::SourceInfoCacheEntry.new nil, 0 246: cache_data[source_uri] = cache_entry 247: end 248: 249: update if cache_entry.refresh source_uri, all 250: end 251: 252: flush 253: end
# File lib/rubygems/source_info_cache.rb, line 265 265: def reset_cache_data 266: @cache_data = nil 267: @only_latest = true 268: end
Force cache file to be reset, useful for integration testing of rubygems
# File lib/rubygems/source_info_cache.rb, line 273 273: def reset_cache_file 274: @cache_file = nil 275: end
# File lib/rubygems/source_info_cache.rb, line 255 255: def reset_cache_for(url, cache_data) 256: say "Reseting cache for #{url}" if Gem.configuration.really_verbose 257: 258: sice = Gem::SourceInfoCacheEntry.new Gem::SourceIndex.new, 0 259: sice.refresh url, false # HACK may be unnecessary, see ::cache and #refresh 260: 261: cache_data[url] = sice 262: cache_data 263: end
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 lib/rubygems/source_info_cache.rb, line 282 282: def search(pattern, platform_only = false, all = false) 283: read_all_cache_data if all 284: 285: cache_data.map do |source_uri, sic_entry| 286: next unless Gem.sources.include? source_uri 287: # TODO - Remove this gunk after 2008/11 288: unless pattern.kind_of? Gem::Dependency then 289: pattern = Gem::Dependency.new pattern, Gem::Requirement.default 290: end 291: sic_entry.source_index.search pattern, platform_only 292: end.flatten.compact 293: end
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 lib/rubygems/source_info_cache.rb, line 301 301: def search_with_source(pattern, only_platform = false, all = false) 302: read_all_cache_data if all 303: 304: results = [] 305: 306: cache_data.map do |source_uri, sic_entry| 307: next unless Gem.sources.include? source_uri 308: 309: # TODO - Remove this gunk after 2008/11 310: unless pattern.kind_of?(Gem::Dependency) 311: pattern = Gem::Dependency.new(pattern, Gem::Requirement.default) 312: end 313: 314: sic_entry.source_index.search(pattern, only_platform).each do |spec| 315: results << [spec, source_uri] 316: end 317: end 318: 319: results 320: end
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 lib/rubygems/source_info_cache.rb, line 328 328: def set_cache_data(hash) 329: @cache_data = hash 330: update 331: end
The name of the system cache file.
# File lib/rubygems/source_info_cache.rb, line 336 336: def system_cache_file 337: self.class.system_cache_file 338: end
Determine if path is a candidate for a cache file. Returns path if it is, nil if not.
# File lib/rubygems/source_info_cache.rb, line 344 344: def try_file(path) 345: return path if File.writable? path 346: return nil if File.exist? path 347: 348: dir = File.dirname path 349: 350: unless File.exist? dir then 351: begin 352: FileUtils.mkdir_p dir 353: rescue RuntimeError, SystemCallError 354: return nil 355: end 356: end 357: 358: return path if File.writable? dir 359: 360: nil 361: end
Mark the cache as updated (i.e. dirty).
# File lib/rubygems/source_info_cache.rb, line 366 366: def update 367: @dirty = true 368: end
The name of the user cache file.
# File lib/rubygems/source_info_cache.rb, line 373 373: def user_cache_file 374: self.class.user_cache_file 375: end
Write data to the proper cache files.
# File lib/rubygems/source_info_cache.rb, line 380 380: def write_cache 381: if not File.exist?(cache_file) or not @only_latest then 382: open cache_file, 'wb' do |io| 383: io.write Marshal.dump(cache_data) 384: end 385: end 386: 387: open latest_cache_file, 'wb' do |io| 388: io.write Marshal.dump(latest_cache_data) 389: end 390: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.