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