Skip to content

Commit

Permalink
Merge pull request #16684 from Homebrew/revert-16623-formulary-loader…
Browse files Browse the repository at this point in the history
…-for

Revert "Refactor `Formulary::loader_for`."
  • Loading branch information
MikeMcQuaid committed Feb 16, 2024
2 parents a953982 + 2468352 commit a4ffd67
Show file tree
Hide file tree
Showing 10 changed files with 229 additions and 377 deletions.
4 changes: 2 additions & 2 deletions Library/Homebrew/api/formula.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def download_and_cache_data!
end
private :download_and_cache_data!

sig { returns(T::Hash[String, Hash]) }
sig { returns(Hash) }
def all_formulae
unless cache.key?("formulae")
json_updated = download_and_cache_data!
Expand All @@ -69,7 +69,7 @@ def all_formulae
cache["formulae"]
end

sig { returns(T::Hash[String, String]) }
sig { returns(Hash) }
def all_aliases
unless cache.key?("aliases")
json_updated = download_and_cache_data!
Expand Down
4 changes: 2 additions & 2 deletions Library/Homebrew/cleanup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def stale_formula?(pathname, scrub)

formula = begin
Formulary.from_rack(HOMEBREW_CELLAR/formula_name)
rescue FormulaUnavailableError, TapFormulaAmbiguityError
rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
nil
end

Expand Down Expand Up @@ -300,7 +300,7 @@ def clean!(quiet: false, periodic: false)
args.each do |arg|
formula = begin
Formulary.resolve(arg)
rescue FormulaUnavailableError, TapFormulaAmbiguityError
rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
nil
end

Expand Down
33 changes: 10 additions & 23 deletions Library/Homebrew/diagnostic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,8 @@ def check_for_unreadable_installed_formula
rescue FormulaUnreadableError, FormulaClassUnavailableError,
TapFormulaUnreadableError, TapFormulaClassUnavailableError => e
formula_unavailable_exceptions << e
rescue FormulaUnavailableError, TapFormulaAmbiguityError
rescue FormulaUnavailableError,
TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
nil
end
return if formula_unavailable_exceptions.empty?
Expand All @@ -751,7 +752,7 @@ def check_for_unlinked_but_not_keg_only
else
begin
Formulary.from_rack(rack).keg_only?
rescue FormulaUnavailableError, TapFormulaAmbiguityError
rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
false
end
end
Expand Down Expand Up @@ -834,30 +835,16 @@ def check_deleted_formula
kegs = Keg.all

deleted_formulae = kegs.map do |keg|
tap = Tab.for_keg(keg).tap

loadable = [
Formulary::FromAPILoader,
Formulary::FromDefaultNameLoader,
Formulary::FromNameLoader,
].any? do |loader_class|
loader = begin
loader_class.try_new(keg.name, warn: false)
rescue TapFormulaAmbiguityError => e
e.loaders.first
end

if loader
# If we know the tap, ignore all other taps.
next false if tap && loader.tap != tap

next true
end
next if Formulary.tap_paths(keg.name).any?

false
unless EnvConfig.no_install_from_api?
# Formulae installed from the API should not count as deleted formulae
# but may not have a tap listed in their tab
tap = Tab.for_keg(keg).tap
next if (tap.blank? || tap.core_tap?) && Homebrew::API::Formula.all_formulae.key?(keg.name)
end

keg.name unless loadable
keg.name
end.compact.uniq

return if deleted_formulae.blank?
Expand Down
36 changes: 28 additions & 8 deletions Library/Homebrew/exceptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -259,20 +259,40 @@ def initialize(tap, name, error)

# Raised when a formula with the same name is found in multiple taps.
class TapFormulaAmbiguityError < RuntimeError
attr_reader :name, :taps, :loaders
attr_reader :name, :paths, :formulae

def initialize(name, loaders)
def initialize(name, paths)
@name = name
@loaders = loaders
@taps = loaders.map(&:tap)
@paths = paths
@formulae = paths.map do |path|
"#{Tap.from_path(path).name}/#{path.basename(".rb")}"
end

super <<~EOS
Formulae found in multiple taps: #{formulae.map { |f| "\n * #{f}" }.join}
formulae = taps.map { |tap| "#{tap}/#{name}" }
formula_list = formulae.map { |f| "\n * #{f}" }.join
Please use the fully-qualified name (e.g. #{formulae.first}) to refer to the formula.
EOS
end
end

# Raised when a formula's old name in a specific tap is found in multiple taps.
class TapFormulaWithOldnameAmbiguityError < RuntimeError
attr_reader :name, :possible_tap_newname_formulae, :taps

def initialize(name, possible_tap_newname_formulae)
@name = name
@possible_tap_newname_formulae = possible_tap_newname_formulae

@taps = possible_tap_newname_formulae.map do |newname|
newname =~ HOMEBREW_TAP_FORMULA_REGEX
"#{Regexp.last_match(1)}/#{Regexp.last_match(2)}"
end

super <<~EOS
Formulae found in multiple taps:#{formula_list}
Formulae with '#{name}' old name found in multiple taps: #{taps.map { |t| "\n * #{t}" }.join}
Please use the fully-qualified name (e.g. #{formulae.first}) to refer to a specific formula.
Please use the fully-qualified name (e.g. #{taps.first}/#{name}) to refer to the formula or use its new name.
EOS
end
end
Expand Down
21 changes: 9 additions & 12 deletions Library/Homebrew/formula.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class Formula

# The path to the alias that was used to identify this {Formula}.
# e.g. `/usr/local/Library/Taps/homebrew/homebrew-core/Aliases/another-name-for-this-formula`
sig { returns(T.nilable(Pathname)) }
sig { returns(T.any(NilClass, Pathname, String)) }
attr_reader :alias_path

# The name of the alias that was used to identify this {Formula}.
Expand Down Expand Up @@ -199,7 +199,7 @@ class Formula

# @private
sig {
params(name: String, path: Pathname, spec: Symbol, alias_path: T.nilable(Pathname),
params(name: String, path: Pathname, spec: Symbol, alias_path: T.any(NilClass, Pathname, String),
tap: T.nilable(Tap), force_bottle: T::Boolean).void
}
def initialize(name, path, spec, alias_path: nil, tap: nil, force_bottle: false)
Expand Down Expand Up @@ -326,22 +326,18 @@ def validate_attributes!
# The alias path that was used to install this formula, if it exists.
# Can differ from {#alias_path}, which is the alias used to find the formula,
# and is specified to this instance.
sig { returns(T.nilable(Pathname)) }
def installed_alias_path
build_tab = build
path = build_tab.source["path"] if build_tab.is_a?(Tab)

return unless path&.match?(%r{#{HOMEBREW_TAP_DIR_REGEX}/Aliases}o)

path = Pathname(path)
return unless path.symlink?
return unless File.symlink?(path)

path
end

sig { returns(T.nilable(String)) }
def installed_alias_name
installed_alias_path&.basename&.to_s
File.basename(installed_alias_path) if installed_alias_path
end

def full_installed_alias_name
Expand All @@ -350,13 +346,14 @@ def full_installed_alias_name

# The path that was specified to find this formula.
def specified_path
return alias_path if alias_path&.exist?
alias_pathname = Pathname(T.must(alias_path)) if alias_path.present?
return alias_pathname if alias_pathname&.exist?

return @unresolved_path if @unresolved_path.exist?

return local_bottle_path if local_bottle_path.presence&.exist?

alias_path || @unresolved_path
alias_pathname || @unresolved_path
end

# The name specified to find this formula.
Expand Down Expand Up @@ -1318,7 +1315,7 @@ def link_overwrite?(path)
f = Formulary.factory(keg.name)
rescue FormulaUnavailableError
# formula for this keg is deleted, so defer to allowlist
rescue TapFormulaAmbiguityError
rescue TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
return false # this keg belongs to another formula
else
# this keg belongs to another unrelated formula
Expand Down Expand Up @@ -2365,7 +2362,7 @@ def to_hash_with_variations(hash_method: :to_hash)

# Take from API, merging in local install status.
if loaded_from_api? && !Homebrew::EnvConfig.no_install_from_api?
json_formula = Homebrew::API::Formula.all_formulae.fetch(name).dup
json_formula = Homebrew::API::Formula.all_formulae[name].dup
return json_formula.merge(
hash.slice("name", "installed", "linked_keg", "pinned", "outdated"),
)
Expand Down
8 changes: 6 additions & 2 deletions Library/Homebrew/formula_auditor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ def audit_file

unversioned_formula = begin
Formulary.factory(full_name).path
rescue FormulaUnavailableError, TapFormulaAmbiguityError
rescue FormulaUnavailableError, TapFormulaAmbiguityError,
TapFormulaWithOldnameAmbiguityError
Pathname.new formula.path.to_s.gsub(/@.*\.rb$/, ".rb")
end
unless unversioned_formula.exist?
Expand Down Expand Up @@ -284,6 +285,9 @@ def audit_deps
rescue TapFormulaAmbiguityError
problem "Ambiguous dependency '#{dep.name}'."
next
rescue TapFormulaWithOldnameAmbiguityError
problem "Ambiguous oldname dependency '#{dep.name.inspect}'."
next
end

if dep_f.oldnames.include?(dep.name.split("/").last)
Expand Down Expand Up @@ -457,7 +461,7 @@ def audit_conflicts
next
rescue FormulaUnavailableError
problem "Can't find conflicting formula #{conflict.name.inspect}."
rescue TapFormulaAmbiguityError
rescue TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
problem "Ambiguous conflicting formula #{conflict.name.inspect}."
end
end
Expand Down

0 comments on commit a4ffd67

Please sign in to comment.