123456789_123456789_123456789_123456789_123456789_

Class: Gem::Package::Old

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Instance Chain:
Inherits: Gem::Package
Defined in: lib/rubygems/package/old.rb

Overview

The format class knows the guts of the ancient #gem file format and provides the capability to read such ancient gems.

Please pretend this doesn’t exist.

Class Method Summary

::Gem::Package - Inherited

.build,
.new

Creates a new ::Gem::Package for the file at #gem.

.raw_spec

Extracts the ::Gem::Specification and raw metadata from the #gem file at Gem.path.

Instance Attribute Summary

::Gem::Package - Inherited

#checksums

Checksums for the contents of the package.

#data_mode

Permission for other files.

#dir_mode

Permission for directories.

#files

The files in this package.

#gem

Reference to the gem being packaged.

#prog_mode

Permission for program files.

#security_policy

The security policy used for verifying the contents of this package.

#spec

The spec for this gem.

#spec=

Sets the ::Gem::Specification to use to build this package.

#build_time

::Gem::DefaultUserInteraction - Included

Instance Method Summary

::Gem::Package - Inherited

#add_checksums

Adds a checksum for each entry in the gem to checksums.yaml.gz.

#build

Builds this package based on the specification set by #spec=

#contents

A list of file names contained in this gem.

#copy_to

Copies this package to Gem.path (if possible).

#extract_files

Extracts the files in this package into destination_dir

#gzip_to

Gzips content written to gz_io to io.

#initialize

Creates a new package that will read or write to the file #gem.

#normalize_path,
#read_checksums

Reads and loads checksums.yaml.gz from the tar file #gem

#setup_signer

Prepares the gem for signing and checksum generation.

#verify

Verifies that this gem:

#verify_entry

Verifies entry in a #gem file.

#verify_files

Verifies the files of the #gem

#add_contents

Adds the files listed in the packages’s ::Gem::Specification to data.tar.gz and adds this file to the tar.

#add_files

Adds files included the package’s ::Gem::Specification to the tar file.

#add_metadata

Adds the package’s ::Gem::Specification to the tar file.

#copy_stream

See additional method definition at line 719.

#digest

Creates a digest of the TarEntry entry from the digest algorithm set by the security policy.

#extract_tar_gz

Extracts all the files in the gzipped tar archive io into destination_dir.

#file_mode,
#install_location

Returns the full path for installing filename.

#load_spec

Loads a ::Gem::Specification from the TarEntry entry

#open_tar_gz

Opens io as a gzipped tar archive.

#verify_checksums

Verifies the #checksums against the digests.

#verify_gz

Verifies that entry is a valid gzipped file.

::Gem::UserInteraction - Included

#alert

Displays an alert statement.

#alert_error

Displays an error statement to the error output location.

#alert_warning

Displays a warning statement to the warning output location.

#ask

Asks a question and returns the answer.

#ask_for_password

Asks for a password with a prompt

#ask_yes_no

Asks a yes or no question.

#choose_from_list

Asks the user to answer question with an answer from the given list.

#say

Displays the given statement on the standard output (or equivalent).

#terminate_interaction

Terminates the RubyGems process with the given exit_code

#verbose

Calls say with msg or the results of the block if really_verbose is true.

::Gem::DefaultUserInteraction - Included

::Gem::Text - Included

#clean_text

Remove any non-printable characters and make the text suitable for printing.

#format_text

Wraps text to wrap characters and optionally indents by indent characters.

#levenshtein_distance

Returns a value representing the “cost” of transforming str1 into str2 Vendored version of DidYouMean::Levenshtein.distance from the ruby/did_you_mean gem @ 1.4.0 github.com/ruby/did_you_mean/blob/2ddf39b874808685965dbc47d344cf6c7651807c/lib/did_you_mean/levenshtein.rb#L7-L37.

#truncate_text, #min3

Constructor Details

.new(gem, security_policy) ⇒ Old

Creates a new old-format package reader for Gem::Package#gem. Old-format packages cannot be written.

[ GitHub ]

  
# File 'lib/rubygems/package/old.rb', line 22

def initialize(gem, security_policy)
  require "fileutils"
  require "zlib"
  Gem.load_yaml

  @contents        = nil
  @gem             = gem
  @security_policy = security_policy
  @spec            = nil
end

Instance Method Details

#contents

A list of file names contained in this gem

[ GitHub ]

  
# File 'lib/rubygems/package/old.rb', line 36

def contents
  verify

  return @contents if @contents

  @gem.with_read_io do |io|
    read_until_dashes io # spec
    header = file_list io

    @contents = header.map {|file| file["path"] }
  end
end

#extract_files(destination_dir)

Extracts the files in this package into destination_dir

[ GitHub ]

  
# File 'lib/rubygems/package/old.rb', line 52

def extract_files(destination_dir)
  verify

  errstr = "Error reading files from gem"

  @gem.with_read_io do |io|
    read_until_dashes io # spec
    header = file_list io
    raise Gem::Exception, errstr unless header

    header.each do |entry|
      full_name = entry["path"]

      destination = install_location full_name, destination_dir

      file_data = String.new

      read_until_dashes io do |line|
        file_data << line
      end

      file_data = file_data.strip.unpack1("m")
      file_data = Zlib::Inflate.inflate file_data

      raise Gem::Package::FormatError, "#{full_name} in #{@gem} is corrupt" if
        file_data.length != entry["size"].to_i

      FileUtils.rm_rf destination

      FileUtils.mkdir_p File.dirname(destination), mode: dir_mode && 0o755

      File.open destination, "wb", file_mode(entry["mode"]) do |out|
        out.write file_data
      end

      verbose destination
    end
  end
rescue Zlib::DataError
  raise Gem::Exception, errstr
end

#file_list(io)

This method is for internal use only.

Reads the file list section from the old-format gem io

[ GitHub ]

  
# File 'lib/rubygems/package/old.rb', line 97

def file_list(io) # :nodoc:
  header = String.new

  read_until_dashes io do |line|
    header << line
  end

  Gem::SafeYAML.safe_load header
end

#read_until_dashes(io)

This method is for internal use only.

Reads lines until a “—” separator is found

[ GitHub ]

  
# File 'lib/rubygems/package/old.rb', line 110

def read_until_dashes(io) # :nodoc:
  while (line = io.gets) && line.chomp.strip != "---" do
    yield line if block_given?
  end
end

#skip_ruby(io)

This method is for internal use only.

Skips the Ruby self-install header in io.

Raises:

[ GitHub ]

  
# File 'lib/rubygems/package/old.rb', line 119

def skip_ruby(io) # :nodoc:
  loop do
    line = io.gets

    return if line.chomp == "__END__"
    break unless line
  end

  raise Gem::Exception, "Failed to find end of Ruby script while reading gem"
end

#spec

The specification for this gem

[ GitHub ]

  
# File 'lib/rubygems/package/old.rb', line 133

def spec
  verify

  return @spec if @spec

  yaml = String.new

  @gem.with_read_io do |io|
    skip_ruby io
    read_until_dashes io do |line|
      yaml << line
    end
  end

  begin
    @spec = Gem::Specification.from_yaml yaml
  rescue Psych::SyntaxError
    raise Gem::Exception, "Failed to parse gem specification out of gem file"
  end
rescue ArgumentError
  raise Gem::Exception, "Failed to parse gem specification out of gem file"
end

#verify

Raises an exception if a security policy that verifies data is active. Old format gems cannot be verified as signed.

[ GitHub ]

  
# File 'lib/rubygems/package/old.rb', line 160

def verify
  return true unless @security_policy

  raise Gem::Security::Exception,
        "old format gems do not contain signatures and cannot be verified" if
    @security_policy.verify_data

  true
end