diff options
author | yugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-08-25 15:02:05 +0000 |
---|---|---|
committer | yugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-08-25 15:02:05 +0000 |
commit | 0dc342de848a642ecce8db697b8fecd83a63e117 (patch) | |
tree | 2b7ed4724aff1f86073e4740134bda9c4aac1a39 /trunk/lib/rubygems/indexer | |
parent | ef70cf7138ab8034b5b806f466e4b484b24f0f88 (diff) |
added tag v1_9_0_4
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_9_0_4@18845 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'trunk/lib/rubygems/indexer')
-rw-r--r-- | trunk/lib/rubygems/indexer/abstract_index_builder.rb | 88 | ||||
-rw-r--r-- | trunk/lib/rubygems/indexer/latest_index_builder.rb | 35 | ||||
-rw-r--r-- | trunk/lib/rubygems/indexer/marshal_index_builder.rb | 17 | ||||
-rw-r--r-- | trunk/lib/rubygems/indexer/master_index_builder.rb | 54 | ||||
-rw-r--r-- | trunk/lib/rubygems/indexer/quick_index_builder.rb | 50 |
5 files changed, 244 insertions, 0 deletions
diff --git a/trunk/lib/rubygems/indexer/abstract_index_builder.rb b/trunk/lib/rubygems/indexer/abstract_index_builder.rb new file mode 100644 index 0000000000..5815dcda87 --- /dev/null +++ b/trunk/lib/rubygems/indexer/abstract_index_builder.rb @@ -0,0 +1,88 @@ +require 'zlib' + +require 'rubygems/indexer' + +# Abstract base class for building gem indicies. Uses the template pattern +# with subclass specialization in the +begin_index+, +end_index+ and +cleanup+ +# methods. +class Gem::Indexer::AbstractIndexBuilder + + # Directory to put index files in + attr_reader :directory + + # File name of the generated index + attr_reader :filename + + # List of written files/directories to move into production + attr_reader :files + + def initialize(filename, directory) + @filename = filename + @directory = directory + @files = [] + end + + ## + # Build a Gem index. Yields to block to handle the details of the + # actual building. Calls +begin_index+, +end_index+ and +cleanup+ at + # appropriate times to customize basic operations. + + def build + FileUtils.mkdir_p @directory unless File.exist? @directory + raise "not a directory: #{@directory}" unless File.directory? @directory + + file_path = File.join @directory, @filename + + @files << @filename + + File.open file_path, "wb" do |file| + @file = file + start_index + yield + end_index + end + + cleanup + ensure + @file = nil + end + + ## + # Compress the given file. + + def compress(filename, ext="rz") + data = open filename, 'rb' do |fp| fp.read end + + zipped = zip data + + File.open "#{filename}.#{ext}", "wb" do |file| + file.write zipped + end + end + + # Called immediately before the yield in build. The index file is open and + # available as @file. + def start_index + end + + # Called immediately after the yield in build. The index file is still open + # and available as @file. + def end_index + end + + # Called from within builder after the index file has been closed. + def cleanup + end + + # Return an uncompressed version of a compressed string. + def unzip(string) + Zlib::Inflate.inflate(string) + end + + # Return a compressed version of the given string. + def zip(string) + Zlib::Deflate.deflate(string) + end + +end + diff --git a/trunk/lib/rubygems/indexer/latest_index_builder.rb b/trunk/lib/rubygems/indexer/latest_index_builder.rb new file mode 100644 index 0000000000..a5798580a6 --- /dev/null +++ b/trunk/lib/rubygems/indexer/latest_index_builder.rb @@ -0,0 +1,35 @@ +require 'rubygems/indexer' + +## +# Construct the latest Gem index file. + +class Gem::Indexer::LatestIndexBuilder < Gem::Indexer::AbstractIndexBuilder + + def start_index + super + + @index = Gem::SourceIndex.new + end + + def end_index + super + + latest = @index.latest_specs.sort.map { |spec| spec.original_name } + + @file.write latest.join("\n") + end + + def cleanup + super + + compress @file.path + + @files.delete 'latest_index' # HACK installed via QuickIndexBuilder :/ + end + + def add(spec) + @index.add_spec(spec) + end + +end + diff --git a/trunk/lib/rubygems/indexer/marshal_index_builder.rb b/trunk/lib/rubygems/indexer/marshal_index_builder.rb new file mode 100644 index 0000000000..e1a4d9f9b8 --- /dev/null +++ b/trunk/lib/rubygems/indexer/marshal_index_builder.rb @@ -0,0 +1,17 @@ +require 'rubygems/indexer' + +# Construct the master Gem index file. +class Gem::Indexer::MarshalIndexBuilder < Gem::Indexer::MasterIndexBuilder + def end_index + gems = {} + index = Gem::SourceIndex.new + + @index.each do |name, gemspec| + gems[gemspec.original_name] = gemspec + end + + index.instance_variable_get(:@gems).replace gems + + @file.write index.dump + end +end diff --git a/trunk/lib/rubygems/indexer/master_index_builder.rb b/trunk/lib/rubygems/indexer/master_index_builder.rb new file mode 100644 index 0000000000..669ea5a1df --- /dev/null +++ b/trunk/lib/rubygems/indexer/master_index_builder.rb @@ -0,0 +1,54 @@ +require 'rubygems/indexer' + +## +# Construct the master Gem index file. + +class Gem::Indexer::MasterIndexBuilder < Gem::Indexer::AbstractIndexBuilder + + def start_index + super + @index = Gem::SourceIndex.new + end + + def end_index + super + + @file.puts "--- !ruby/object:#{@index.class}" + @file.puts "gems:" + + gems = @index.sort_by { |name, gemspec| gemspec.sort_obj } + gems.each do |name, gemspec| + yaml = gemspec.to_yaml.gsub(/^/, ' ') + yaml = yaml.sub(/\A ---/, '') # there's a needed extra ' ' here + @file.print " #{gemspec.original_name}:" + @file.puts yaml + end + end + + def cleanup + super + + index_file_name = File.join @directory, @filename + + compress index_file_name, "Z" + paranoid index_file_name, "#{index_file_name}.Z" + + @files << "#{@filename}.Z" + end + + def add(spec) + @index.add_spec(spec) + end + + private + + def paranoid(path, compressed_path) + data = Gem.read_binary path + compressed_data = Gem.read_binary compressed_path + + if data != unzip(compressed_data) then + raise "Compressed file #{compressed_path} does not match uncompressed file #{path}" + end + end + +end diff --git a/trunk/lib/rubygems/indexer/quick_index_builder.rb b/trunk/lib/rubygems/indexer/quick_index_builder.rb new file mode 100644 index 0000000000..dc36179dc5 --- /dev/null +++ b/trunk/lib/rubygems/indexer/quick_index_builder.rb @@ -0,0 +1,50 @@ +require 'rubygems/indexer' + +## +# Construct a quick index file and all of the individual specs to support +# incremental loading. + +class Gem::Indexer::QuickIndexBuilder < Gem::Indexer::AbstractIndexBuilder + + def initialize(filename, directory) + directory = File.join directory, 'quick' + + super filename, directory + end + + def cleanup + super + + quick_index_file = File.join @directory, @filename + compress quick_index_file + + # the complete quick index is in a directory, so move it as a whole + @files.delete 'index' + @files << 'quick' + end + + def add(spec) + @file.puts spec.original_name + add_yaml(spec) + add_marshal(spec) + end + + def add_yaml(spec) + fn = File.join @directory, "#{spec.original_name}.gemspec.rz" + zipped = zip spec.to_yaml + File.open fn, "wb" do |gsfile| gsfile.write zipped end + end + + def add_marshal(spec) + # HACK why does this not work in #initialize? + FileUtils.mkdir_p File.join(@directory, "Marshal.#{Gem.marshal_version}") + + fn = File.join @directory, "Marshal.#{Gem.marshal_version}", + "#{spec.original_name}.gemspec.rz" + + zipped = zip Marshal.dump(spec) + File.open fn, "wb" do |gsfile| gsfile.write zipped end + end + +end + |