Parent

Included Modules

Class Index [+]

Quicksearch

Gem::SpecFetcher

SpecFetcher handles metadata updates from remote gem repositories.

Constants

FILES

Public Class Methods

fetcher() click to toggle source
    # File lib/rubygems/spec_fetcher.rb, line 42
42:   def self.fetcher
43:     @fetcher ||= new
44:   end
new() click to toggle source
    # File lib/rubygems/spec_fetcher.rb, line 50
50:   def initialize
51:     require 'fileutils'
52: 
53:     @dir = File.join Gem.user_home, '.gem', 'specs'
54:     @update_cache = File.stat(Gem.user_home).uid == Process.uid
55: 
56:     @specs = {}
57:     @latest_specs = {}
58:     @prerelease_specs = {}
59: 
60:     @caches = {
61:       :latest => @latest_specs,
62:       :prerelease => @prerelease_specs,
63:       :all => @specs
64:     }
65: 
66:     @fetcher = Gem::RemoteFetcher.fetcher
67:   end

Public Instance Methods

cache_dir(uri) click to toggle source

Returns the local directory to write uri to.

    # File lib/rubygems/spec_fetcher.rb, line 72
72:   def cache_dir(uri)
73:     # Correct for windows paths
74:     escaped_path = uri.path.sub(/^\/([a-z]):\//, '/\1-/')
75:     File.join @dir, "#{uri.host}%#{uri.port}", File.dirname(escaped_path)
76:   end
fetch(*args) click to toggle source
     # File lib/rubygems/spec_fetcher.rb, line 101
101:   def fetch(*args)
102:     fetch_with_errors(*args).first
103:   end
fetch_spec(spec, source_uri) click to toggle source
     # File lib/rubygems/spec_fetcher.rb, line 105
105:   def fetch_spec(spec, source_uri)
106:     source_uri = URI.parse source_uri if String === source_uri
107:     spec = spec - [nil, 'ruby', '']
108:     spec_file_name = "#{spec.join '-'}.gemspec"
109: 
110:     uri = source_uri + "#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}"
111: 
112:     cache_dir = cache_dir uri
113: 
114:     local_spec = File.join cache_dir, spec_file_name
115: 
116:     if File.exist? local_spec then
117:       spec = Gem.read_binary local_spec
118:     else
119:       uri.path << '.rz'
120: 
121:       spec = @fetcher.fetch_path uri
122:       spec = Gem.inflate spec
123: 
124:       if @update_cache then
125:         FileUtils.mkdir_p cache_dir
126: 
127:         open local_spec, 'wb' do |io|
128:           io.write spec
129:         end
130:       end
131:     end
132: 
133:     # TODO: Investigate setting Gem::Specification#loaded_from to a URI
134:     Marshal.load spec
135:   end
fetch_with_errors(dependency, all = false, matching_platform = true, prerelease = false) click to toggle source

Fetch specs matching dependency. If all is true, all matching (released) versions are returned. If matching_platform is false, all platforms are returned. If prerelease is true, prerelease versions are included.

    # File lib/rubygems/spec_fetcher.rb, line 84
84:   def fetch_with_errors(dependency,
85:                         all               = false,
86:                         matching_platform = true,
87:                         prerelease        = false)
88: 
89:     specs_and_sources, errors = find_matching_with_errors(dependency,
90:                                                           all,
91:                                                           matching_platform,
92:                                                           prerelease)
93: 
94:     ss = specs_and_sources.map do |spec_tuple, source_uri|
95:       [fetch_spec(spec_tuple, URI.parse(source_uri)), source_uri]
96:     end
97: 
98:     return [ss, errors]
99:   end
find_matching(*args) click to toggle source
     # File lib/rubygems/spec_fetcher.rb, line 176
176:   def find_matching(*args)
177:     find_matching_with_errors(*args).first
178:   end
find_matching_with_errors(dependency, all = false, matching_platform = true, prerelease = false) click to toggle source

Find spec names that match dependency. If all is true, all matching released versions are returned. If matching_platform is false, gems for all platforms are returned.

     # File lib/rubygems/spec_fetcher.rb, line 142
142:   def find_matching_with_errors(dependency,
143:                                 all               = false,
144:                                 matching_platform = true,
145:                                 prerelease        = false)
146:     found = {}
147: 
148:     rejected_specs = {}
149: 
150:     list(all, prerelease).each do |source_uri, specs|
151:       found[source_uri] = specs.select do |spec_name, version, spec_platform|
152:         if dependency.match?(spec_name, version)
153:           if matching_platform and !Gem::Platform.match(spec_platform)
154:             pm = (rejected_specs[dependency] ||= Gem::PlatformMismatch.new(spec_name, version))
155:             pm.add_platform spec_platform
156:             false
157:           else
158:             true
159:           end
160:         end
161:       end
162:     end
163: 
164:     errors = rejected_specs.values
165: 
166:     specs_and_sources = []
167: 
168:     found.each do |source_uri, specs|
169:       uri_str = source_uri.to_s
170:       specs_and_sources.concat(specs.map { |spec| [spec, uri_str] })
171:     end
172: 
173:     [specs_and_sources, errors]
174:   end
list(all = false, prerelease = false) click to toggle source

Returns a list of gems available for each source in Gem::sources. If all is true, all released versions are returned instead of only latest versions. If prerelease is true, include prerelease versions.

     # File lib/rubygems/spec_fetcher.rb, line 213
213:   def list(all = false, prerelease = false)
214:     # TODO: make type the only argument
215:     type = if all
216:              :all
217:            elsif prerelease
218:              :prerelease
219:            else
220:              :latest
221:            end
222: 
223:     list  = {}
224:     file  = FILES[type]
225:     cache = @caches[type]
226: 
227:     Gem.sources.each do |source_uri|
228:       source_uri = URI.parse source_uri
229: 
230:       unless cache.include? source_uri
231:         cache[source_uri] = load_specs source_uri, file
232:       end
233: 
234:       list[source_uri] = cache[source_uri]
235:     end
236: 
237:     if type == :all
238:       list.values.map do |gems|
239:         gems.reject! { |g| !g[1] || g[1].prerelease? }
240:       end
241:     end
242: 
243:     list
244:   end
load_specs(source_uri, file) click to toggle source

Loads specs in file, fetching from source_uri if the on-disk cache is out of date.

     # File lib/rubygems/spec_fetcher.rb, line 250
250:   def load_specs(source_uri, file)
251:     file_name  = "#{file}.#{Gem.marshal_version}"
252:     spec_path  = source_uri + "#{file_name}.gz"
253:     cache_dir  = cache_dir spec_path
254:     local_file = File.join(cache_dir, file_name)
255:     loaded     = false
256: 
257:     if File.exist? local_file then
258:       spec_dump =
259:         @fetcher.fetch_path(spec_path, File.mtime(local_file)) rescue nil
260: 
261:       loaded = true if spec_dump
262: 
263:       spec_dump ||= Gem.read_binary local_file
264:     else
265:       spec_dump = @fetcher.fetch_path spec_path
266:       loaded = true
267:     end
268: 
269:     specs = begin
270:               Marshal.load spec_dump
271:             rescue ArgumentError
272:               spec_dump = @fetcher.fetch_path spec_path
273:               loaded = true
274: 
275:               Marshal.load spec_dump
276:             end
277: 
278:     if loaded and @update_cache then
279:       begin
280:         FileUtils.mkdir_p cache_dir
281: 
282:         open local_file, 'wb' do |io|
283:           io << spec_dump
284:         end
285:       rescue
286:       end
287:     end
288: 
289:     specs
290:   end
suggest_gems_from_name(gem_name) click to toggle source

Suggests a gem based on the supplied gem_name. Returns a string of the gem name if an approximate match can be found or nil otherwise. NOTE: for performance reasons only gems which exactly match the first character of gem_name are considered.

     # File lib/rubygems/spec_fetcher.rb, line 186
186:   def suggest_gems_from_name gem_name
187:     gem_name        = gem_name.downcase
188:     max             = gem_name.size / 2
189:     specs           = list.values.flatten 1
190: 
191:     matches = specs.map { |name, version, platform|
192:       next unless Gem::Platform.match platform
193: 
194:       distance = levenshtein_distance gem_name, name.downcase
195: 
196:       next if distance >= max
197: 
198:       return [name] if distance == 0
199: 
200:       [name, distance]
201:     }.compact
202: 
203:     matches = matches.uniq.sort_by { |name, dist| dist }
204: 
205:     matches.first(5).map { |name, dist| name }
206:   end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.