diff --git a/Library/Homebrew/cmd/--cache.rb b/Library/Homebrew/cmd/--cache.rb index 050ac2a0b26d1..bfe862b635ec4 100644 --- a/Library/Homebrew/cmd/--cache.rb +++ b/Library/Homebrew/cmd/--cache.rb @@ -64,7 +64,6 @@ def self.__cache os_arch_combinations.each do |os, arch| SimulateSystem.with os: os, arch: arch do - Formulary.clear_cache formula = Formulary.factory(ref) print_formula_cache(formula, os: os, arch: arch, args: args) end diff --git a/Library/Homebrew/cmd/fetch.rb b/Library/Homebrew/cmd/fetch.rb index 7dd07fa229fec..b8efff19cd7a1 100644 --- a/Library/Homebrew/cmd/fetch.rb +++ b/Library/Homebrew/cmd/fetch.rb @@ -99,7 +99,6 @@ def self.fetch os_arch_combinations.each do |os, arch| SimulateSystem.with os: os, arch: arch do - Formulary.clear_cache formula = Formulary.factory(ref, args.HEAD? ? :head : :stable) formula.print_tap_action verb: "Fetching" diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index af5449a8e1d2e..35336cbe7b6e9 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -205,8 +205,6 @@ def self.audit spdx_license_data = SPDX.license_data spdx_exception_data = SPDX.exception_data - clear_formulary_cache = [args.os, args.arch].any? - formula_problems = audit_formulae.sort.each_with_object({}) do |f, problems| path = f.path @@ -228,8 +226,6 @@ def self.audit SimulateSystem.with os: os, arch: arch do odebug "Auditing Formula #{f} on os #{os} and arch #{arch}" - Formulary.clear_cache if clear_formulary_cache - audit_proc = proc { FormulaAuditor.new(Formulary.factory(path), **options).tap(&:audit) } # Audit requires full Ruby source so disable API. diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index 33c90ad6e5a61..9e8e313ea3b57 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -1,7 +1,7 @@ # typed: true # frozen_string_literal: true -require "digest/md5" +require "digest/sha2" require "extend/cachable" require "tab" require "utils/bottles" @@ -32,24 +32,28 @@ def self.factory_cached? !@factory_cache.nil? end + def self.platform_cache + cache["#{Homebrew::SimulateSystem.current_os}_#{Homebrew::SimulateSystem.current_arch}"] ||= {} + end + def self.formula_class_defined_from_path?(path) - cache.key?(:path) && cache[:path].key?(path) + platform_cache.key?(:path) && platform_cache[:path].key?(path) end def self.formula_class_defined_from_api?(name) - cache.key?(:api) && cache[:api].key?(name) + platform_cache.key?(:api) && platform_cache[:api].key?(name) end def self.formula_class_get_from_path(path) - cache[:path].fetch(path) + platform_cache[:path].fetch(path) end def self.formula_class_get_from_api(name) - cache[:api].fetch(name) + platform_cache[:api].fetch(name) end def self.clear_cache - cache.each do |type, cached_objects| + platform_cache.each do |type, cached_objects| next if type == :formulary_factory cached_objects.each_value do |klass| @@ -126,21 +130,28 @@ def self.load_formula(name, path, contents, namespace, flags:, ignore_errors:) end end + sig { params(identifier: String).returns(String) } + def self.namespace_key(identifier) + Digest::SHA2.hexdigest( + "#{Homebrew::SimulateSystem.current_os}_#{Homebrew::SimulateSystem.current_arch}:#{identifier}", + ) + end + sig { params(name: String, path: Pathname, flags: T::Array[String], ignore_errors: T::Boolean) .returns(T.class_of(Formula)) } def self.load_formula_from_path(name, path, flags:, ignore_errors:) contents = path.open("r") { |f| ensure_utf8_encoding(f).read } - namespace = "FormulaNamespace#{Digest::MD5.hexdigest(path.to_s)}" + namespace = "FormulaNamespace#{namespace_key(path.to_s)}" klass = load_formula(name, path, contents, namespace, flags: flags, ignore_errors: ignore_errors) - cache[:path] ||= {} - cache[:path][path] = klass + platform_cache[:path] ||= {} + platform_cache[:path][path] = klass end sig { params(name: String, flags: T::Array[String]).returns(T.class_of(Formula)) } def self.load_formula_from_api(name, flags:) - namespace = :"FormulaNamespaceAPI#{Digest::MD5.hexdigest(name)}" + namespace = :"FormulaNamespaceAPI#{namespace_key(name)}" mod = Module.new remove_const(namespace) if const_defined?(namespace) @@ -396,8 +407,8 @@ def ruby_source_checksum klass = T.cast(klass, T.class_of(Formula)) mod.const_set(class_name, klass) - cache[:api] ||= {} - cache[:api][name] = klass + platform_cache[:api] ||= {} + platform_cache[:api][name] = klass end sig { params(name: String, spec: Symbol, force_bottle: T::Boolean, flags: T::Array[String]).returns(Formula) } @@ -721,7 +732,9 @@ def self.factory( ignore_errors: T.unsafe(nil) ) cache_key = "#{ref}-#{spec}-#{alias_path}-#{from}" - return cache[:formulary_factory][cache_key] if factory_cached? && cache[:formulary_factory]&.key?(cache_key) + if factory_cached? && platform_cache[:formulary_factory]&.key?(cache_key) + return platform_cache[:formulary_factory][cache_key] + end loader_options = { from: from, warn: warn }.compact formula_options = { alias_path: alias_path, @@ -732,8 +745,8 @@ def self.factory( .get_formula(spec, **formula_options) if factory_cached? - cache[:formulary_factory] ||= {} - cache[:formulary_factory][cache_key] ||= formula + platform_cache[:formulary_factory] ||= {} + platform_cache[:formulary_factory][cache_key] ||= formula end formula diff --git a/Library/Homebrew/test_runner_formula.rb b/Library/Homebrew/test_runner_formula.rb index 83bbdc0c5ba2a..2c5c0d275520a 100644 --- a/Library/Homebrew/test_runner_formula.rb +++ b/Library/Homebrew/test_runner_formula.rb @@ -97,8 +97,6 @@ def dependents(platform:, arch:, macos_version:) end with_env(HOMEBREW_EVAL_ALL: eval_all_env) do - Formulary.clear_cache - os = macos_version || platform arch = SIMULATE_SYSTEM_SYMBOLS.fetch(arch)