diff options
author | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-11-10 07:48:56 +0000 |
---|---|---|
committer | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-11-10 07:48:56 +0000 |
commit | fbf59bdbea63efd34ccc144e648467d2f52e7345 (patch) | |
tree | 244f0e7ae112cc7dd135e5d1ac24e6c70ba71b4a /lib/rubygems/indexer | |
parent | 7a4aad75356496559460041a6c063bdb736c7236 (diff) | |
download | ruby-fbf59bdbea63efd34ccc144e648467d2f52e7345.tar.gz |
Import RubyGems trunk revision 1493.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13862 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rubygems/indexer')
-rw-r--r-- | lib/rubygems/indexer/abstract_index_builder.rb | 80 | ||||
-rw-r--r-- | lib/rubygems/indexer/marshal_index_builder.rb | 8 | ||||
-rw-r--r-- | lib/rubygems/indexer/master_index_builder.rb | 44 | ||||
-rw-r--r-- | lib/rubygems/indexer/quick_index_builder.rb | 48 |
4 files changed, 180 insertions, 0 deletions
diff --git a/lib/rubygems/indexer/abstract_index_builder.rb b/lib/rubygems/indexer/abstract_index_builder.rb new file mode 100644 index 0000000000..f25f21707b --- /dev/null +++ b/lib/rubygems/indexer/abstract_index_builder.rb @@ -0,0 +1,80 @@ +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 << file_path + + 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") + zipped = zip(File.open(filename, 'rb'){ |fp| fp.read }) + 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/lib/rubygems/indexer/marshal_index_builder.rb b/lib/rubygems/indexer/marshal_index_builder.rb new file mode 100644 index 0000000000..5e3ba7f5b9 --- /dev/null +++ b/lib/rubygems/indexer/marshal_index_builder.rb @@ -0,0 +1,8 @@ +require 'rubygems/indexer' + +# Construct the master Gem index file. +class Gem::Indexer::MarshalIndexBuilder < Gem::Indexer::MasterIndexBuilder + def end_index + @file.write @index.dump + end +end diff --git a/lib/rubygems/indexer/master_index_builder.rb b/lib/rubygems/indexer/master_index_builder.rb new file mode 100644 index 0000000000..f435c44e41 --- /dev/null +++ b/lib/rubygems/indexer/master_index_builder.rb @@ -0,0 +1,44 @@ +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 @index.to_yaml + end + + def cleanup + super + + index_file_name = File.join @directory, @filename + + compress index_file_name, "Z" + compressed_file_name = "#{index_file_name}.Z" + + paranoid index_file_name, compressed_file_name + + @files << compressed_file_name + end + + def add(spec) + @index.add_spec(spec) + end + + private + + def paranoid(fn, compressed_fn) + data = File.open(fn, 'rb') do |fp| fp.read end + compressed_data = File.open(compressed_fn, 'rb') do |fp| fp.read end + + if data != unzip(compressed_data) then + fail "Compressed file #{compressed_fn} does not match uncompressed file #{fn}" + end + end + +end diff --git a/lib/rubygems/indexer/quick_index_builder.rb b/lib/rubygems/indexer/quick_index_builder.rb new file mode 100644 index 0000000000..8805f3fe38 --- /dev/null +++ b/lib/rubygems/indexer/quick_index_builder.rb @@ -0,0 +1,48 @@ +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 quick_index_file + @files << @directory + end + + def add(spec) + @file.puts spec.full_name + add_yaml(spec) + add_marshal(spec) + end + + def add_yaml(spec) + fn = File.join @directory, "#{spec.full_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.full_name}.gemspec.rz" + + zipped = zip Marshal.dump(spec) + File.open fn, "wb" do |gsfile| gsfile.write zipped end + end + +end + |