Reset Bootsnap after installing gems

This commit is contained in:
Bo Anderson 2025-03-27 03:05:51 +00:00
parent 76e154fe82
commit 1168ec1feb
No known key found for this signature in database
5 changed files with 86 additions and 40 deletions

View File

@ -558,7 +558,7 @@ module Homebrew
return unless bootsnap.directory?
bootsnap.each_child do |subdir|
cleanup_path(subdir) { FileUtils.rm_r(subdir) } if subdir.basename.to_s != Homebrew.bootsnap_key
cleanup_path(subdir) { FileUtils.rm_r(subdir) } if subdir.basename.to_s != Homebrew::Bootsnap.key
end
end

View File

@ -0,0 +1,3 @@
# typed: strict
HOMEBREW_USING_PORTABLE_RUBY = T.let(false, T::Boolean)

View File

@ -1,13 +1,10 @@
# typed: true
# frozen_string_literal: true
homebrew_bootsnap_enabled = HOMEBREW_USING_PORTABLE_RUBY &&
ENV["HOMEBREW_NO_BOOTSNAP"].nil? &&
!ENV["HOMEBREW_BOOTSNAP"].nil?
module Homebrew
def self.bootsnap_key
@bootsnap_key ||= begin
module Bootsnap
def self.key
@key ||= begin
require "digest/sha2"
checksum = Digest::SHA256.new
@ -18,29 +15,53 @@ module Homebrew
checksum.hexdigest
end
end
end
if homebrew_bootsnap_enabled
require "bootsnap"
private_class_method def self.cache_dir
cache = ENV.fetch("HOMEBREW_CACHE", nil) || ENV.fetch("HOMEBREW_DEFAULT_CACHE", nil)
raise "Needs HOMEBREW_CACHE or HOMEBREW_DEFAULT_CACHE!" if cache.nil? || cache.empty?
cache = File.join(cache, "bootsnap", Homebrew.bootsnap_key)
File.join(cache, "bootsnap", key)
end
private_class_method def self.ignore_directories
# We never do `require "vendor/bundle/ruby/..."` or `require "vendor/portable-ruby/..."`,
# so let's slim the cache a bit by excluding them.
# Note that gems within `bundle/ruby` will still be cached - these are when directory walking down from above.
ignore_directories = [
[
(HOMEBREW_LIBRARY_PATH/"vendor/bundle/ruby").to_s,
(HOMEBREW_LIBRARY_PATH/"vendor/portable-ruby").to_s,
]
end
Bootsnap.setup(
cache_dir: cache,
private_class_method def self.enabled?
HOMEBREW_USING_PORTABLE_RUBY && ENV["HOMEBREW_NO_BOOTSNAP"].nil? && !ENV["HOMEBREW_BOOTSNAP"].nil?
end
def self.load!(compile_cache: true)
return unless enabled?
require "bootsnap"
::Bootsnap.setup(
cache_dir:,
ignore_directories:,
load_path_cache: true,
compile_cache_iseq: true,
compile_cache_yaml: true,
compile_cache_iseq: compile_cache,
compile_cache_yaml: compile_cache,
compile_cache_json: compile_cache,
)
end
def self.reset!
return unless enabled?
::Bootsnap.unload_cache!
@key = nil
# The compile cache doesn't get unloaded so we don't need to load it again!
load!(compile_cache: false)
end
end
end
Homebrew::Bootsnap.load!

View File

@ -1,8 +1,25 @@
# typed: strict
module Homebrew
module Bootsnap
sig { returns(String) }
def self.bootsnap_key; end
def self.key; end
sig { returns(String) }
private_class_method def self.cache_dir; end
sig { returns(T::Array[String]) }
private_class_method def self.ignore_directories; end
sig { returns(T::Boolean) }
private_class_method def self.enabled?; end
sig { params(compile_cache: T::Boolean).void }
def self.load!(compile_cache: true); end
sig { void }
def self.reset!; end
end
end
module Bootsnap
@ -29,5 +46,9 @@ module Bootsnap
compile_cache_iseq: true,
compile_cache_yaml: true,
compile_cache_json: true
); end
)
end
sig { void }
def self.unload_cache!; end
end

View File

@ -303,6 +303,7 @@ module Homebrew
exec bundle, "install", out: :err
end)
if $CHILD_STATUS.success?
Homebrew::Bootsnap.reset! if defined?(Homebrew::Bootsnap) # Gem install can run before Bootsnap loads
true
else
message = <<~EOS