| Class | Gem::SourceInfoCache |
| In: |
lib/rubygems/source_info_cache.rb
|
| Parent: | Object |
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:
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
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
# 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
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
# 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)
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 299
299: def search_with_source(pattern, only_platform = false, all = false)
300: read_all_cache_data if all
301:
302: results = []
303:
304: cache_data.map do |source_uri, sic_entry|
305: next unless Gem.sources.include? source_uri
306:
307: # TODO - Remove this gunk after 2008/11
308: unless pattern.kind_of?(Gem::Dependency)
309: pattern = Gem::Dependency.new(pattern, Gem::Requirement.default)
310: end
311:
312: sic_entry.source_index.search(pattern, only_platform).each do |spec|
313: results << [spec, source_uri]
314: end
315: end
316:
317: results
318: 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 326
326: def set_cache_data(hash)
327: @cache_data = hash
328: update
329: 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 342
342: def try_file(path)
343: return path if File.writable? path
344: return nil if File.exist? path
345:
346: dir = File.dirname path
347:
348: unless File.exist? dir then
349: begin
350: FileUtils.mkdir_p dir
351: rescue RuntimeError, SystemCallError
352: return nil
353: end
354: end
355:
356: return path if File.writable? dir
357:
358: nil
359: end
Write data to the proper cache files.
# File lib/rubygems/source_info_cache.rb, line 378
378: def write_cache
379: if not File.exist?(cache_file) or not @only_latest then
380: open cache_file, 'wb' do |io|
381: io.write Marshal.dump(cache_data)
382: end
383: end
384:
385: open latest_cache_file, 'wb' do |io|
386: io.write Marshal.dump(latest_cache_data)
387: end
388: end