Skip to content

Commit

Permalink
Merge pull request Homebrew#16456 from Bo98/formulary-platform-cache
Browse files Browse the repository at this point in the history
Introduce Formulary platform cache
  • Loading branch information
MikeMcQuaid authored Jan 9, 2024
2 parents 1cbd454 + 310b5ec commit 11e4b66
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 23 deletions.
1 change: 0 additions & 1 deletion Library/Homebrew/cmd/--cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion Library/Homebrew/cmd/fetch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 0 additions & 4 deletions Library/Homebrew/dev-cmd/audit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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.
Expand Down
43 changes: 28 additions & 15 deletions Library/Homebrew/formulary.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# typed: true
# frozen_string_literal: true

require "digest/md5"
require "digest/sha2"
require "extend/cachable"
require "tab"
require "utils/bottles"
Expand Down Expand Up @@ -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|
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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) }
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down
2 changes: 0 additions & 2 deletions Library/Homebrew/test_runner_formula.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit 11e4b66

Please sign in to comment.