| Class | Gem::Indexer |
| In: |
lib/rubygems/indexer.rb
|
| Parent: | Object |
Top level class for building the gem repository index.
| dest_directory | [R] | Index install location |
| directory | [R] | Index build directory |
Create an indexer that will index the gems in directory.
# File lib/rubygems/indexer.rb, line 32
32: def initialize(directory)
33: unless ''.respond_to? :to_xs then
34: fail "Gem::Indexer requires that the XML Builder library be installed:" \
35: "\n\tgem install builder"
36: end
37:
38: @dest_directory = directory
39: @directory = File.join Dir.tmpdir, "gem_generate_index_#{$$}"
40:
41: marshal_name = "Marshal.#{Gem.marshal_version}"
42:
43: @master_index = Gem::Indexer::MasterIndexBuilder.new "yaml", @directory
44: @marshal_index = Gem::Indexer::MarshalIndexBuilder.new marshal_name, @directory
45: @quick_index = Gem::Indexer::QuickIndexBuilder.new 'index', @directory
46:
47: quick_dir = File.join @directory, 'quick'
48: @latest_index = Gem::Indexer::LatestIndexBuilder.new 'latest_index', quick_dir
49: end
Abbreviate the spec for downloading. Abbreviated specs are only used for searching, downloading and related activities and do not need deployment specific information (e.g. list of files). So we abbreviate the spec, making it much smaller for quicker downloads.
# File lib/rubygems/indexer.rb, line 141
141: def abbreviate(spec)
142: spec.files = []
143: spec.test_files = []
144: spec.rdoc_options = []
145: spec.extra_rdoc_files = []
146: spec.cert_chain = []
147: spec
148: end
Build the index.
# File lib/rubygems/indexer.rb, line 54
54: def build_index
55: @master_index.build do
56: @quick_index.build do
57: @marshal_index.build do
58: @latest_index.build do
59: progress = ui.progress_reporter gem_file_list.size,
60: "Generating index for #{gem_file_list.size} gems in #{@dest_directory}",
61: "Loaded all gems"
62:
63: gem_file_list.each do |gemfile|
64: if File.size(gemfile.to_s) == 0 then
65: alert_warning "Skipping zero-length gem: #{gemfile}"
66: next
67: end
68:
69: begin
70: spec = Gem::Format.from_file_by_path(gemfile).spec
71:
72: unless gemfile =~ /\/#{Regexp.escape spec.original_name}.*\.gem\z/i then
73: alert_warning "Skipping misnamed gem: #{gemfile} => #{spec.full_name} (#{spec.original_name})"
74: next
75: end
76:
77: abbreviate spec
78: sanitize spec
79:
80: @master_index.add spec
81: @quick_index.add spec
82: @marshal_index.add spec
83: @latest_index.add spec
84:
85: progress.updated spec.original_name
86:
87: rescue SignalException => e
88: alert_error "Received signal, exiting"
89: raise
90: rescue Exception => e
91: alert_error "Unable to process #{gemfile}\n#{e.message} (#{e.class})\n\t#{e.backtrace.join "\n\t"}"
92: end
93: end
94:
95: progress.done
96:
97: say "Generating master indexes (this may take a while)"
98: end
99: end
100: end
101: end
102: end
List of gem file names to index.
# File lib/rubygems/indexer.rb, line 133
133: def gem_file_list
134: Dir.glob(File.join(@dest_directory, "gems", "*.gem"))
135: end
# File lib/rubygems/indexer.rb, line 121
121: def generate_index
122: FileUtils.rm_rf @directory
123: FileUtils.mkdir_p @directory, :mode => 0700
124:
125: build_index
126: install_index
127: rescue SignalException
128: ensure
129: FileUtils.rm_rf @directory
130: end
# File lib/rubygems/indexer.rb, line 104
104: def install_index
105: verbose = Gem.configuration.really_verbose
106:
107: say "Moving index into production dir #{@dest_directory}" if verbose
108:
109: files = @master_index.files + @quick_index.files + @marshal_index.files +
110: @latest_index.files
111:
112: files.each do |file|
113: src_name = File.join @directory, file
114: dst_name = File.join @dest_directory, file
115:
116: FileUtils.rm_rf dst_name, :verbose => verbose
117: FileUtils.mv src_name, @dest_directory, :verbose => verbose
118: end
119: end
Sanitize the descriptive fields in the spec. Sometimes non-ASCII characters will garble the site index. Non-ASCII characters will be replaced by their XML entity equivalent.
# File lib/rubygems/indexer.rb, line 153
153: def sanitize(spec)
154: spec.summary = sanitize_string(spec.summary)
155: spec.description = sanitize_string(spec.description)
156: spec.post_install_message = sanitize_string(spec.post_install_message)
157: spec.authors = spec.authors.collect { |a| sanitize_string(a) }
158: spec
159: end
Sanitize a single string.
# File lib/rubygems/indexer.rb, line 162
162: def sanitize_string(string)
163: # HACK the #to_s is in here because RSpec has an Array of Arrays of
164: # Strings for authors. Need a way to disallow bad values on gempsec
165: # generation. (Probably won't happen.)
166: string ? string.to_s.to_xs : string
167: end