Module: Precompiled

Defined in:
lib/rubygems/precompiled.rb

Defined Under Namespace

Classes: BaseCache, FileCache, HttpCache

Constant Summary collapse

GemCache =
{
  'file' => FileCache,
  'http' => HttpCache
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



13
14
15
16
# File 'lib/rubygems/precompiled.rb', line 13

def self.included(base)
  base.send(:alias_method, :build_extensions_without_cache, :build_extensions)
  base.send(:alias_method, :build_extensions, :build_extensions_with_cache)
end

.precompiled_cachesObject

Private: A list of precompiled cache root URLs loaded from the rubygems configuration file

Returns Array of BaseCache subclasses



80
81
82
83
84
85
# File 'lib/rubygems/precompiled.rb', line 80

def self.precompiled_caches
  @@caches ||= [Gem.configuration['precompiled_cache']].flatten.compact.map do |cache_root|
    cache_root = URI.parse(cache_root)
    GemCache[cache_root.scheme].new(cache_root)
  end
end

Instance Method Details

#build_extensions_with_cacheObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/rubygems/precompiled.rb', line 87

def build_extensions_with_cache
  cache = Precompiled.precompiled_caches.find { |cache| cache.contains?(@spec) }

  if cache
    $stderr.puts "Loading native extension from cache"
    cache.retrieve(@spec) do |path|
      if @spec.respond_to?(:extension_dir)
        overlay_tarball(path, @spec.extension_dir)
      else
        overlay_tarball(path, @gem_dir)
      end
    end
  else
    build_extensions_without_cache
  end
end

#overlay_tarball(tarball, target_root) ⇒ Object

 Private: Extracts a .tar.gz file on-top of the gem’s installation directory



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/rubygems/precompiled.rb', line 105

def overlay_tarball(tarball, target_root)
  Zlib::GzipReader.open(tarball) do |gzip_io|
    Gem::Package::TarReader.new(gzip_io) do |tar|
      tar.each do |entry|
        target_path = File.join(target_root, entry.full_name)
        if entry.directory?
          FileUtils.mkdir_p(target_path)
        elsif entry.file?
          FileUtils.mkdir_p(File.dirname(target_path))
          File.open(target_path, "w") do |f|
            f.write entry.read(1024*1024) until entry.eof?
          end
        end
        entry.close
      end
     end
  end
end