Class: Archive::Gem

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/archive/gem.rb

Overview

Archive::Gem is a slice-and-dice toolkit for Ruby Gems packages.

It contains exposed functionality not included in the standard Ruby Gems system:

  • It can work with a Gem completely in memory, allowing you to avoid potential pitfalls using FileUtils and other toolkits to navigate the extracted gem

  • It can get at the specification of the file with very little effort.

  • It provides iterators for each file of the package

  • Most importantly: Ruby Gems does not need to be installed on the system for this toolkit to work.

The largest drawback is that Archive::Gem is currently read-only.

At this point you may be wondering why this was written, as Ruby Gems obviously has to have this functionality. This is true - but it’s buried in twisted, barely documented code that is not easy to access without extracting the gem.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io_or_filename = $stdin) ⇒ Gem

Creates a new Archive::Gem object from a filename or IO object. Defaults to using the standard input.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/archive/gem.rb', line 41

def initialize(io_or_filename = $stdin)
    if io_or_filename.respond_to? :read
        @io = io_or_filename
    else
        @io = File.open(io_or_filename)
    end

    Archive::Tar::Minitar::Reader.open(@io) do |r|
        r.each do |entry|
            if entry.name == "metadata.gz"
                gz = Zlib::GzipReader.new(entry)
                @metadata = gz.read
                gz.close
            elsif entry.name == "data.tar.gz"
                gz = Zlib::GzipReader.new(entry)
                @data = StringIO.new(gz.read)
                gz.close
            end
        end
    end
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



35
36
37
# File 'lib/archive/gem.rb', line 35

def data
  @data
end

#ioObject (readonly)

Returns the value of attribute io.



37
38
39
# File 'lib/archive/gem.rb', line 37

def io
  @io
end

#metadataObject (readonly)

Returns the value of attribute metadata.



36
37
38
# File 'lib/archive/gem.rb', line 36

def 
  @metadata
end

Instance Method Details

#eachObject

Iterates over each file in the tarball. Yields IO objects for each of them.



90
91
92
93
94
95
96
97
# File 'lib/archive/gem.rb', line 90

def each
    Archive::Tar::Minitar::Reader.open(@data) do |r|
        r.each do |entry|
            yield StringIO.new(entry.read || '')
        end
    end
    @data.rewind
end

#files_as_tarObject

Returns an IO object of the tarball of the actual files in the gem.



82
83
84
# File 'lib/archive/gem.rb', line 82

def files_as_tar
    @data
end

#specificationObject Also known as: spec

Extracts the YAML specification from the Gem and parses it. Returns the YAML data if that was possible, otherwise returns nil.



67
68
69
70
71
72
73
74
75
# File 'lib/archive/gem.rb', line 67

def specification
    spec = nil

    if @metadata
        spec = Gem::Specification.from_yaml 
    end

    return spec 
end