diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index 693f3a3d1c0c3..b52961042016b 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -738,6 +738,17 @@ def self.try_new(ref, from: nil, warn: false) return unless path.expand_path.exist? return unless ::Utils::Path.loadable_package_path?(path, :formula) + if Homebrew::EnvConfig.use_internal_api? + # If the path is for an installed keg, use FromKegLoader instead + begin + keg = Keg.for(path) + loader = FromKegLoader.try_new(keg.name, from:, warn:) + return T.cast(loader, T.attached_class) + rescue NotAKegError + # Not a keg path, continue + end + end + if (tap = Tap.from_path(path)) # Only treat symlinks in taps as aliases. if path.symlink? @@ -936,9 +947,15 @@ class FromKegLoader < FormulaLoader def self.try_new(ref, from: nil, warn: false) ref = ref.to_s - return unless (keg_formula = HOMEBREW_PREFIX/"opt/#{ref}/.brew/#{ref}.rb").file? + keg_directory = HOMEBREW_PREFIX/"opt/#{ref}" + return unless keg_directory.directory? - new(ref, keg_formula) + # The formula file in `.brew` will use the canonical name, whereas `ref` can be an alias. + # Use `Keg#name` to get the canonical name. + keg = Keg.new(keg_directory) + return unless (keg_formula = keg_directory/".brew/#{keg.name}.rb").file? + + new(keg.name, keg_formula, tap: keg.tab.tap) end end @@ -1054,7 +1071,12 @@ def klass(flags:, ignore_errors:) sig { overridable.params(flags: T::Array[String]).void } def load_from_api(flags:) - json_formula = Homebrew::API::Formula.all_formulae[name] + json_formula = if Homebrew::EnvConfig.use_internal_api? + Homebrew::API::Formula.formula_json(name) + else + Homebrew::API::Formula.all_formulae[name] + end + raise FormulaUnavailableError, name if json_formula.nil? Formulary.load_formula_from_json!(name, json_formula, flags:) @@ -1223,7 +1245,15 @@ def self.from_keg( flags:, }.compact - f = if tap.nil? + f = if Homebrew::EnvConfig.use_internal_api? && (loader = FromKegLoader.try_new(keg.name, warn: false)) + begin + loader.get_formula(spec, alias_path:, force_bottle:, flags:, ignore_errors: true) + rescue FormulaUnreadableError + nil + end + end + + f ||= if tap.nil? factory(formula_name, spec, **options) else begin