diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml index 8b7eed3186..e8227c7e76 100644 --- a/Library/.rubocop.yml +++ b/Library/.rubocop.yml @@ -278,6 +278,7 @@ Sorbet/StrictSigil: - "Taps/**/*" - "/**/{Formula,Casks}/**/*.rb" - "**/{Formula,Casks}/**/*.rb" + - "Homebrew/{standalone,startup}/*.rb" # These are loaded before sorbet-runtime - "Homebrew/test/**/*.rb" Sorbet/TrueSigil: diff --git a/Library/Homebrew/cleanup.rb b/Library/Homebrew/cleanup.rb index 7b80a9f2e5..6122abaf45 100644 --- a/Library/Homebrew/cleanup.rb +++ b/Library/Homebrew/cleanup.rb @@ -295,6 +295,7 @@ module Homebrew cleanup_cache cleanup_empty_api_source_directories + cleanup_bootsnap cleanup_logs cleanup_lockfiles cleanup_python_site_packages @@ -314,7 +315,6 @@ module Homebrew return if periodic cleanup_portable_ruby - cleanup_bootsnap else args.each do |arg| formula = begin @@ -528,9 +528,11 @@ module Homebrew def cleanup_bootsnap bootsnap = cache/"bootsnap" - return unless bootsnap.exist? + return unless bootsnap.directory? - cleanup_path(bootsnap) { bootsnap.rmtree } + bootsnap.each_child do |subdir| + cleanup_path(subdir) { subdir.rmtree } if subdir.basename.to_s != Homebrew.bootsnap_key + end end def cleanup_cache_db(rack = nil) diff --git a/Library/Homebrew/cmd/vendor-install.sh b/Library/Homebrew/cmd/vendor-install.sh index 9fa5728d9d..102a09b47e 100644 --- a/Library/Homebrew/cmd/vendor-install.sh +++ b/Library/Homebrew/cmd/vendor-install.sh @@ -362,11 +362,4 @@ homebrew-vendor-install() { lock "vendor-install ${VENDOR_NAME}" fetch install - - # Bootsnap needs cleaned up on a new Ruby version. - # It's cleaned up by every `brew cleanup` run anyway so not a big deal to do it here, too. - if [[ "${VENDOR_NAME}" == "ruby" ]] - then - rm -rf "${HOMEBREW_CACHE}/bootsnap" - fi } diff --git a/Library/Homebrew/standalone/init.rb b/Library/Homebrew/standalone/init.rb index 305d8497ad..a0dd6c0fea 100644 --- a/Library/Homebrew/standalone/init.rb +++ b/Library/Homebrew/standalone/init.rb @@ -1,4 +1,4 @@ -# typed: true # rubocop:disable Sorbet/StrictSigil +# 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`. diff --git a/Library/Homebrew/standalone/sorbet.rb b/Library/Homebrew/standalone/sorbet.rb index 9dc4eaacb9..9cd7fa24a8 100644 --- a/Library/Homebrew/standalone/sorbet.rb +++ b/Library/Homebrew/standalone/sorbet.rb @@ -1,4 +1,4 @@ -# typed: true # rubocop:todo Sorbet/StrictSigil +# typed: true # frozen_string_literal: true require "sorbet-runtime" diff --git a/Library/Homebrew/startup/bootsnap.rb b/Library/Homebrew/startup/bootsnap.rb index 9bb8b139a6..6148c71272 100644 --- a/Library/Homebrew/startup/bootsnap.rb +++ b/Library/Homebrew/startup/bootsnap.rb @@ -1,16 +1,36 @@ -# typed: strict +# 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 + require "digest/sha2" + + checksum = Digest::SHA256.new + begin + checksum.file(HOMEBREW_LIBRARY_PATH/"Gemfile.lock") + rescue SystemCallError + # If it's inaccessible, let's just assume it's empty. + end + checksum << user_gem_groups.join(",") + + "#{RUBY_VERSION}-#{checksum}" + end + end +end + if homebrew_bootsnap_enabled require "bootsnap" 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) + # 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. diff --git a/Library/Homebrew/startup/bootsnap.rbi b/Library/Homebrew/startup/bootsnap.rbi index 8a35aa087b..3f42e1837d 100644 --- a/Library/Homebrew/startup/bootsnap.rbi +++ b/Library/Homebrew/startup/bootsnap.rbi @@ -1,5 +1,10 @@ # typed: strict +module Homebrew + sig { returns(String) } + def self.bootsnap_key; end +end + module Bootsnap sig { params( diff --git a/Library/Homebrew/startup/config.rb b/Library/Homebrew/startup/config.rb index 7adc85fe87..7ef65a1eaa 100644 --- a/Library/Homebrew/startup/config.rb +++ b/Library/Homebrew/startup/config.rb @@ -1,4 +1,4 @@ -# typed: true # rubocop:todo Sorbet/StrictSigil +# typed: true # frozen_string_literal: true raise "HOMEBREW_BREW_FILE was not exported! Please call bin/brew directly!" unless ENV["HOMEBREW_BREW_FILE"] diff --git a/Library/Homebrew/startup/ruby_path.rb b/Library/Homebrew/startup/ruby_path.rb index d5eb6fc6b7..35de5267a4 100644 --- a/Library/Homebrew/startup/ruby_path.rb +++ b/Library/Homebrew/startup/ruby_path.rb @@ -1,4 +1,4 @@ -# typed: true # rubocop:todo Sorbet/StrictSigil +# typed: true # frozen_string_literal: true RUBY_PATH = Pathname.new(RbConfig.ruby).freeze