Class: Gem::Package::TarWriter
| Relationships & Source Files | |
| Namespace Children | |
| Classes: | |
| Exceptions: | |
| Inherits: | Object | 
| Defined in: | lib/rubygems/package/tar_writer.rb | 
Overview
Allows writing of tar files
Class Method Summary
- 
    
      .new(io)  ⇒ TarWriter 
    
    constructor
    Creates a new TarWriter, yielding it if a block is given.
Instance Attribute Summary
- 
    
      #closed?  ⇒ Boolean 
    
    readonly
    Is the TarWriterclosed?
Instance Method Summary
- 
    
      #add_file(name, mode) {|RestrictedStream.new(@io)| ... } 
    
    Adds file namewith permissionsmode, and yields an IO for writing the file to.
- 
    
      #add_file_digest(name, mode, digest_algorithms)  
    
    Adds namewith permissionsmodeto the tar, yieldingiofor writing the file.
- 
    
      #add_file_signed(name, mode, signer)  
    
    Adds namewith permissionsmodeto the tar, yieldingiofor writing the file.
- 
    
      #add_file_simple(name, mode, size) {|os| ... } 
    
    Add file namewith permissionsmodesizebytes long.
- 
    
      #add_symlink(name, target, mode)  
    
    Adds symlink namewith permissionsmode, linking totarget.
- 
    
      #check_closed  
    
    Raises IOError if the TarWriteris closed.
- 
    
      #close  
    
    Closes the TarWriter.
- 
    
      #flush  
    
    Flushes the TarWriter's IO. 
- 
    
      #initialize(io)  ⇒ TarWriter 
    
    constructor
    Creates a new TarWriterthat will write toio
- 
    
      #mkdir(name, mode)  
    
    Creates a new directory in the tar file namewithmode
- 
    
      #split_name(name)  
    
    Internal use only
    Splits nameinto a name and prefix that can fit in the TarHeader.
Constructor Details
    .new(io)  ⇒ TarWriter 
  
Creates a new TarWriter, yielding it if a block is given
# File 'lib/rubygems/package/tar_writer.rb', line 80
def self.new(io) writer = super return writer unless block_given? begin yield writer ensure writer.close end nil end
    #initialize(io)  ⇒ TarWriter 
  
Creates a new TarWriter that will write to io
# File 'lib/rubygems/package/tar_writer.rb', line 97
def initialize(io) @io = io @closed = false end
Instance Attribute Details
    #closed?  ⇒ Boolean  (readonly)
  
Is the TarWriter closed?
# File 'lib/rubygems/package/tar_writer.rb', line 280
def closed? @closed end
Instance Method Details
#add_file(name, mode) {|RestrictedStream.new(@io)| ... }
Adds file name with permissions mode, and yields an IO for writing the file to
# File 'lib/rubygems/package/tar_writer.rb', line 106
def add_file(name, mode) # :yields: io check_closed raise Gem::Package::NonSeekableIO unless @io.respond_to? :pos= name, prefix = split_name name init_pos = @io.pos @io.write "\0" * 512 # placeholder for the header yield RestrictedStream.new(@io) if block_given? size = @io.pos - init_pos - 512 remainder = (512 - (size % 512)) % 512 @io.write "\0" * remainder final_pos = @io.pos @io.pos = init_pos header = Gem::Package::TarHeader.new :name => name, :mode => mode, :size => size, :prefix => prefix, :mtime => Time.now @io.write header @io.pos = final_pos self end
#add_file_digest(name, mode, digest_algorithms)
Adds name with permissions mode to the tar, yielding io for writing the file.  The digest_algorithm is written to a read-only name.sum file following the given file contents containing the digest name and hexdigest separated by a tab.
The created digest object is returned.
# File 'lib/rubygems/package/tar_writer.rb', line 144
def add_file_digest name, mode, digest_algorithms # :yields: io digests = digest_algorithms.map do |digest_algorithm| digest = digest_algorithm.new digest_name = if digest.respond_to? :name then digest.name else /::([^:]+)$/ =~ digest_algorithm.name $1 end [digest_name, digest] end digests = Hash[*digests.flatten] add_file name, mode do |io| Gem::Package::DigestIO.wrap io, digests do |digest_io| yield digest_io end end digests end
#add_file_signed(name, mode, signer)
Adds name with permissions mode to the tar, yielding io for writing the file.  The signer is used to add a digest file using its digest_algorithm per add_file_digest and a cryptographic signature in name.sig.  If the signer has no key only the checksum file is added.
Returns the digest.
# File 'lib/rubygems/package/tar_writer.rb', line 177
def add_file_signed name, mode, signer digest_algorithms = [ signer.digest_algorithm, Digest::SHA512, ].compact.uniq digests = add_file_digest name, mode, digest_algorithms do |io| yield io end signature_digest = digests.values.compact.find do |digest| digest_name = if digest.respond_to? :name then digest.name else /::([^:]+)$/ =~ digest.class.name $1 end digest_name == signer.digest_name end raise "no #{signer.digest_name} in #{digests.values.compact}" unless signature_digest if signer.key then signature = signer.sign signature_digest.digest add_file_simple "#{name}.sig", 0444, signature.length do |io| io.write signature end end digests end
#add_file_simple(name, mode, size) {|os| ... }
Add file name with permissions mode size bytes long.  Yields an IO to write the file to.
# File 'lib/rubygems/package/tar_writer.rb', line 216
def add_file_simple(name, mode, size) # :yields: io check_closed name, prefix = split_name name header = Gem::Package::TarHeader.new(:name => name, :mode => mode, :size => size, :prefix => prefix, :mtime => Time.now).to_s @io.write header os = BoundedStream.new @io, size yield os if block_given? min_padding = size - os.written @io.write("\0" * min_padding) remainder = (512 - (size % 512)) % 512 @io.write("\0" * remainder) self end
#add_symlink(name, target, mode)
Adds symlink name with permissions mode, linking to target.
# File 'lib/rubygems/package/tar_writer.rb', line 242
def add_symlink(name, target, mode) check_closed name, prefix = split_name name header = Gem::Package::TarHeader.new(:name => name, :mode => mode, :size => 0, :typeflag => "2", :linkname => target, :prefix => prefix, :mtime => Time.now).to_s @io.write header self end
#check_closed
Raises IOError if the TarWriter is closed
# File 'lib/rubygems/package/tar_writer.rb', line 261
def check_closed raise IOError, "closed #{self.class}" if closed? end
#close
Closes the TarWriter
# File 'lib/rubygems/package/tar_writer.rb', line 268
def close check_closed @io.write "\0" * 1024 flush @closed = true end
#flush
Flushes the TarWriter's IO
# File 'lib/rubygems/package/tar_writer.rb', line 287
def flush check_closed @io.flush if @io.respond_to? :flush end
#mkdir(name, mode)
Creates a new directory in the tar file name with mode
# File 'lib/rubygems/package/tar_writer.rb', line 296
def mkdir(name, mode) check_closed name, prefix = split_name(name) header = Gem::Package::TarHeader.new :name => name, :mode => mode, :typeflag => "5", :size => 0, :prefix => prefix, :mtime => Time.now @io.write header self end
#split_name(name)
Splits name into a name and prefix that can fit in the TarHeader
# File 'lib/rubygems/package/tar_writer.rb', line 314
def split_name(name) # :nodoc: if name.bytesize > 256 then raise Gem::Package::TooLongFileName.new("File \"#{name}\" has a too long path (should be 256 or less)") end prefix = '' if name.bytesize > 100 then parts = name.split('/', -1) # parts are never empty here name = parts.pop # initially empty for names with a trailing slash ("foo/.../bar/") prefix = parts.join('/') # if empty, then it's impossible to split (parts is empty too) while !parts.empty? && (prefix.bytesize > 155 || name.empty?) name = parts.pop + '/' + name prefix = parts.join('/') end if name.bytesize > 100 or prefix.empty? then raise Gem::Package::TooLongFileName.new("File \"#{prefix}/#{name}\" has a too long name (should be 100 or less)") end if prefix.bytesize > 155 then raise Gem::Package::TooLongFileName.new("File \"#{prefix}/#{name}\" has a too long base path (should be 155 or less)") end end return name, prefix end