Class: Gem::Precompiler

Inherits:
Object
  • Object
show all
Includes:
FileUtils
Defined in:
lib/rubygems/precompiler.rb

Instance Method Summary collapse

Constructor Details

#initialize(gemfile, opts = {}) ⇒ Precompiler

Returns a new instance of Precompiler.



12
13
14
15
16
17
# File 'lib/rubygems/precompiler.rb', line 12

def initialize(gemfile, opts = {})
  @installer = Gem::Installer.new(gemfile, opts.dup.merge(:unpack => true))
  @target_dir = opts.fetch(:output, Dir.pwd)
  @target_dir = File.join(@target_dir, arch_string) if opts.fetch(:arch, false)
  @options = opts
end

Instance Method Details

#arch_stringObject

Private: Return a string that uniquely keys this machines ruby version and architecture

Returns string



46
47
48
# File 'lib/rubygems/precompiler.rb', line 46

def arch_string
  "ruby-#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}/#{Gem::Platform.local.to_s}"
end

#build_products(installer, path) ⇒ Object

Private: Return a list fo build-products in a given directory

Returns an array of paths



60
61
62
63
64
# File 'lib/rubygems/precompiler.rb', line 60

def build_products(installer, path)
  dlext = RbConfig::CONFIG["DLEXT"]
  lib_dirs = installer.spec.require_paths.join(',')
  Dir.glob("#{path}/{#{lib_dirs}}/**/*.#{dlext}")
end

#compileObject

Public: Compile



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/rubygems/precompiler.rb', line 69

def compile
  FileUtils.mkdir_p(@target_dir)

  tempdir do |path|
    @installer.unpack(path)
    @installer.build_extensions

    targz_file(output_path) do |tar_writer|

      build_products(@installer, path).each do |product_path|
        product_path = Pathname.new(product_path)
        relative_path = product_path.relative_path_from(Pathname.new(path))

        stat = File.stat(product_path)
        mode = stat.mode
        size = stat.size

        File.open(product_path, "r") do |source|

          tar_writer.add_file_simple(relative_path.to_s, mode, size) do |dest|
            dest.write source.read(1024*1024) until source.eof?
          end
        end

      end

    end
  end
end

#gem_nameObject

 Public: Returns the name of hte gem

Returns a string



22
23
24
# File 'lib/rubygems/precompiler.rb', line 22

def gem_name
  @installer.spec.name
end

#has_extension?Boolean

 Public: Does the gem actually have any compiled extensions?

Returns boolean - true if the gem has a c-extension that needs building

Returns:

  • (Boolean)


29
30
31
# File 'lib/rubygems/precompiler.rb', line 29

def has_extension?
  !@installer.spec.extensions.empty?
end

#output_pathObject

Public: The filename of the compiled bundle for this gem

Returns a string



53
54
55
# File 'lib/rubygems/precompiler.rb', line 53

def output_path
  File.join(*[@target_dir, "#{@installer.spec.name}-#{@installer.spec.version}.tar.gz"].compact)
end

#targz_file(path, &block) ⇒ Object

 Private: Yield a reference to a TarWriter that writes to the specified .tar.gz file



102
103
104
105
106
# File 'lib/rubygems/precompiler.rb', line 102

def targz_file(path, &block)
  Zlib::GzipWriter.open(path) do |tar_file_io|
    Gem::Package::TarWriter.new(tar_file_io, &block)
  end
end

#tempdirObject

Private: Yield the path to a temporary directory that will get deleted when the block returns



36
37
38
39
40
41
# File 'lib/rubygems/precompiler.rb', line 36

def tempdir
  temp_dir = Dir.mktmpdir
  yield temp_dir
ensure
  rm_rf temp_dir
end