Enable Bootsnap by default

- do some optimisation of `require`s before Bootsnap
- remove `HOMEBREW_BOOTSTRAP` environment variable as it's set by
  default
- add fast require in `bootsnap.rb` using logic from `ruby.sh`
- cleanup `bootsnap.rb` a bit
- remove setting `HOMEBREW_BOOTSNAP` in GitHub Actions
This commit is contained in:
Mike McQuaid 2025-03-31 17:15:31 +01:00
parent faddb73204
commit 9560c01453
No known key found for this signature in database
12 changed files with 39 additions and 28 deletions

View File

@ -12,7 +12,6 @@ env:
HOMEBREW_DEVELOPER: 1
HOMEBREW_NO_AUTO_UPDATE: 1
HOMEBREW_NO_ENV_HINTS: 1
HOMEBREW_BOOTSNAP: 1
HOMEBREW_NO_INSTALL_CLEANUP: 1
defaults:

View File

@ -13,7 +13,6 @@ env:
HOMEBREW_DEVELOPER: 1
HOMEBREW_NO_AUTO_UPDATE: 1
HOMEBREW_NO_ENV_HINTS: 1
HOMEBREW_BOOTSNAP: 1
HOMEBREW_NO_INSTALL_CLEANUP: 1
defaults:

View File

@ -14,7 +14,6 @@ env:
HOMEBREW_DEVELOPER: 1
HOMEBREW_NO_AUTO_UPDATE: 1
HOMEBREW_NO_ENV_HINTS: 1
HOMEBREW_BOOTSNAP: 1
HOMEBREW_NO_INSTALL_CLEANUP: 1
HOMEBREW_VERIFY_ATTESTATIONS: 1

View File

@ -72,11 +72,6 @@ module Homebrew
description: "Use this as the `bat` theme for syntax highlighting.",
default_text: "`$BAT_THEME`.",
},
HOMEBREW_BOOTSNAP: {
description: "If set, use Bootsnap to speed up repeated `brew` calls. " \
"A no-op on Linux when not using Homebrew's vendored, relocatable Ruby.",
boolean: true,
},
HOMEBREW_BOTTLE_DOMAIN: {
description: "Use this URL as the download mirror for bottles. " \
"If bottles at that URL are temporarily unavailable, " \

View File

@ -43,9 +43,6 @@ module Homebrew::EnvConfig
sig { returns(T.nilable(::String)) }
def bat_theme; end
sig { returns(T::Boolean) }
def bootsnap?; end
sig { returns(String) }
def bottle_domain; end

View File

@ -1,7 +1,10 @@
# typed: true
# frozen_string_literal: true
# This file is included before any other files. It intentionally has typing disabled and has minimal use of `require`.
# This file is included before any other files.
# It intentionally has typing disabled and uses `Homebrew::FastBootRequire`
# or `require_relative` to load all files
# (except "rbconfig" which is needed by `Homebrew::FastBootRequire`)
required_ruby_major, required_ruby_minor, = ENV.fetch("HOMEBREW_REQUIRED_RUBY_VERSION", "").split(".").map(&:to_i)
gems_vendored = if required_ruby_minor.nil?
@ -21,12 +24,30 @@ else
vendored_versions.include?("#{ruby_major}.#{ruby_minor}")
end.freeze
# Setup Homebrew::FastBootRequire for faster boot requires.
# Inspired by https://github.com/Shopify/bootsnap/wiki/Bootlib::Require
require "rbconfig"
module Homebrew
module FastBootRequire
ARCHDIR = RbConfig::CONFIG["archdir"].freeze
RUBYLIBDIR = RbConfig::CONFIG["rubylibdir"].freeze
def self.from_archdir(feature)
require(File.join(ARCHDIR, feature.to_s))
end
def self.from_rubylibdir(feature)
require(File.join(RUBYLIBDIR, "#{feature}.rb"))
end
end
end
# We trust base Ruby to provide what we need.
# Don't look into the user-installed sitedir, which may contain older versions of RubyGems.
require "rbconfig"
$LOAD_PATH.reject! { |path| path.start_with?(RbConfig::CONFIG["sitedir"]) }
require "pathname"
Homebrew::FastBootRequire.from_rubylibdir("pathname")
dir = __dir__ || raise("__dir__ is not defined")
HOMEBREW_LIBRARY_PATH = Pathname(dir).parent.realpath.freeze
HOMEBREW_USING_PORTABLE_RUBY = RbConfig.ruby.include?("/vendor/portable-ruby/").freeze
@ -48,7 +69,7 @@ unless $LOAD_PATH.include?(HOMEBREW_LIBRARY_PATH.to_s)
$LOAD_PATH.insert(last_homebrew_path_idx + 1, HOMEBREW_LIBRARY_PATH.to_s)
end
require_relative "../vendor/bundle/bundler/setup"
require "portable_ruby_gems" if HOMEBREW_USING_PORTABLE_RUBY
Homebrew::FastBootRequire.from_archdir("portable_ruby_gems") if HOMEBREW_USING_PORTABLE_RUBY
$LOAD_PATH.unshift "#{HOMEBREW_LIBRARY_PATH}/vendor/bundle/#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/" \
"bundler-#{Homebrew::HOMEBREW_BUNDLER_VERSION}/lib"
$LOAD_PATH.uniq!

View File

@ -2,9 +2,10 @@
# frozen_string_literal: true
# This file should be the first `require` in all entrypoints of `brew`.
# Bootsnap should be loaded as early as possible.
require_relative "standalone/init"
require_relative "startup/bootsnap"
require_relative "startup/ruby_path"
require "startup/config"
require_relative "startup/bootsnap"
require_relative "standalone/sorbet"

View File

@ -34,17 +34,21 @@ module Homebrew
end
private_class_method def self.enabled?
HOMEBREW_USING_PORTABLE_RUBY && ENV["HOMEBREW_NO_BOOTSNAP"].nil? && !ENV["HOMEBREW_BOOTSNAP"].nil?
!ENV["HOMEBREW_BOOTSNAP_GEM_PATH"].to_s.empty? && ENV["HOMEBREW_NO_BOOTSNAP"].nil?
end
def self.load!(compile_cache: true)
return unless enabled?
require "bootsnap"
require ENV.fetch("HOMEBREW_BOOTSNAP_GEM_PATH")
::Bootsnap.setup(
cache_dir:,
ignore_directories:,
# In development environments the bootsnap compilation cache is
# generated on the fly when source files are loaded.
# https://github.com/Shopify/bootsnap?tab=readme-ov-file#precompilation
development_mode: true,
load_path_cache: true,
compile_cache_iseq: compile_cache,
compile_cache_yaml: compile_cache,

View File

@ -5,7 +5,7 @@
# work as the first item in `brew.rb` so we can load gems with Bundler when
# needed before anything else is loaded (e.g. `json`).
require "English"
Homebrew::FastBootRequire.from_rubylibdir("English")
module Homebrew
# Keep in sync with the `Gemfile.lock`'s BUNDLED WITH.

View File

@ -127,6 +127,10 @@ If there's no Homebrew Portable Ruby available for your processor:
if [[ -x "${vendor_ruby_path}" ]]
then
HOMEBREW_RUBY_PATH="${vendor_ruby_path}"
HOMEBREW_BOOTSNAP_GEM_PATH="$(
shopt -s nullglob
echo "${vendor_ruby_root}"/lib/ruby/gems/*/gems/bootsnap-*/lib/bootsnap 2>/dev/null
)"
TERMINFO_DIRS="${vendor_ruby_terminfo}"
if [[ "${vendor_ruby_current_version}" != "${HOMEBREW_PORTABLE_RUBY_VERSION}" ]]
then
@ -146,7 +150,7 @@ If there's no Homebrew Portable Ruby available for your processor:
fi
fi
export HOMEBREW_RUBY_PATH
export HOMEBREW_RUBY_PATH HOMEBREW_BOOTSNAP_GEM_PATH
[[ -n "${HOMEBREW_LINUX}" && -n "${TERMINFO_DIRS}" ]] && export TERMINFO_DIRS
}

View File

@ -3843,11 +3843,6 @@ command execution e.g. `$(cat file)`.
*Default:* `$BAT_THEME`.
`HOMEBREW_BOOTSNAP`
: If set, use Bootsnap to speed up repeated `brew` calls. A no-op on Linux when
not using Homebrew's vendored, relocatable Ruby.
`HOMEBREW_BOTTLE_DOMAIN`
: Use this URL as the download mirror for bottles. If bottles at that URL are

View File

@ -2473,9 +2473,6 @@ Use this as the \fBbat\fP theme for syntax highlighting\.
\fIDefault:\fP \fB$BAT_THEME\fP\&\.
.RE
.TP
\fBHOMEBREW_BOOTSNAP\fP
If set, use Bootsnap to speed up repeated \fBbrew\fP calls\. A no\-op on Linux when not using Homebrew\[u2019]s vendored, relocatable Ruby\.
.TP
\fBHOMEBREW_BOTTLE_DOMAIN\fP
Use this URL as the download mirror for bottles\. If bottles at that URL are temporarily unavailable, the default bottle domain will be used as a fallback mirror\. For example, \fBexport HOMEBREW_BOTTLE_DOMAIN=http://localhost:8080\fP will cause all bottles to download from the prefix \fBhttp://localhost:8080/\fP\&\. If bottles are not available at \fB$HOMEBREW_BOTTLE_DOMAIN\fP they will be downloaded from the default bottle domain\.
.RS