formula_auditor: move out synced_versions_formulae logic

* tap: take ownership of synced_versions_formulae.json
* formula: add synced_with_other_formulae? logic

Signed-off-by: Michael Cho <michael@michaelcho.dev>
This commit is contained in:
Michael Cho 2024-03-03 01:55:56 -05:00
parent 53c1107fd2
commit 72f8399110
No known key found for this signature in database
GPG Key ID: 55E85E28A7CD1E85
4 changed files with 43 additions and 32 deletions

View File

@ -469,16 +469,12 @@ module Homebrew
Latest livecheck version: #{new_versions} Latest livecheck version: #{new_versions}
Latest Repology version: #{repology_latest} Latest Repology version: #{repology_latest}
EOS EOS
if formula_or_cask.is_a?(Formula) if formula_or_cask.is_a?(Formula) && formula_or_cask.synced_with_other_formulae?
require "formula_auditor" outdated_synced_formulae = synced_with(formula_or_cask, new_version.general)
auditor = FormulaAuditor.new(formula_or_cask) puts <<~EOS if outdated_synced_formulae.present?
if auditor.synced_with_other_formulae? Version syncing: #{title_name} version should be kept in sync with
outdated_synced_formulae = synced_with(auditor, formula_or_cask, new_version.general) #{outdated_synced_formulae.join(", ")}.
puts <<~EOS if outdated_synced_formulae.present? EOS
Version syncing: #{title_name} version should be kept in sync with
#{outdated_synced_formulae.join(", ")}.
EOS
end
end end
puts <<~EOS unless args.no_pull_requests? puts <<~EOS unless args.no_pull_requests?
Open pull requests: #{open_pull_requests || "none"} Open pull requests: #{open_pull_requests || "none"}
@ -521,15 +517,14 @@ module Homebrew
sig { sig {
params( params(
auditor: FormulaAuditor,
formula: Formula, formula: Formula,
new_version: T.nilable(T.any(Version, Cask::DSL::Version)), new_version: T.nilable(T.any(Version, Cask::DSL::Version)),
).returns(T::Array[String]) ).returns(T::Array[String])
} }
def synced_with(auditor, formula, new_version) def synced_with(formula, new_version)
synced_with = [] synced_with = []
auditor.synced_versions_formulae_json.each do |synced_formulae| formula.tap&.synced_versions_formulae&.each do |synced_formulae|
next unless synced_formulae.include?(formula.name) next unless synced_formulae.include?(formula.name)
synced_formulae.each do |synced_formula| synced_formulae.each do |synced_formula|

View File

@ -525,6 +525,14 @@ class Formula
end.sort_by(&:version).reverse end.sort_by(&:version).reverse
end end
# Whether this {Formula} is version-synced with other formulae.
sig { returns(T::Boolean) }
def synced_with_other_formulae?
return false if @tap.nil?
@tap.synced_versions_formulae.any? { |synced_formulae| synced_formulae.include?(name) }
end
# A named {Resource} for the currently active {SoftwareSpec}. # A named {Resource} for the currently active {SoftwareSpec}.
# Additional downloads can be defined as {#resource}s. # Additional downloads can be defined as {#resource}s.
# {Resource#stage} will create a temporary directory and yield to a block. # {Resource#stage} will create a temporary directory and yield to a block.

View File

@ -140,27 +140,13 @@ module Homebrew
@aliases ||= Formula.aliases + Formula.tap_aliases @aliases ||= Formula.aliases + Formula.tap_aliases
end end
def synced_versions_formulae_json
@synced_versions_formulae_json ||= JSON.parse(File.read("#{formula.tap.path}/synced_versions_formulae.json"))
end
def synced_with_other_formulae?
return false unless formula.tap
synced_versions_formulae_file = "#{formula.tap.path}/synced_versions_formulae.json"
return false unless File.exist?(synced_versions_formulae_file)
synced_versions_formulae_json.any? { |synced_version_formulae| synced_version_formulae.include?(formula.name) }
end
def audit_synced_versions_formulae def audit_synced_versions_formulae
return unless formula.tap return unless formula.synced_with_other_formulae?
return unless synced_with_other_formulae?
name = formula.name name = formula.name
version = formula.version version = formula.version
synced_versions_formulae_json.each do |synced_version_formulae| formula.tap.synced_versions_formulae.each do |synced_version_formulae|
next unless synced_version_formulae.include?(name) next unless synced_version_formulae.include?(name)
synced_version_formulae.each do |synced_formula| synced_version_formulae.each do |synced_formula|

View File

@ -22,9 +22,10 @@ class Tap
HOMEBREW_TAP_FORMULA_RENAMES_FILE = "formula_renames.json" HOMEBREW_TAP_FORMULA_RENAMES_FILE = "formula_renames.json"
HOMEBREW_TAP_MIGRATIONS_FILE = "tap_migrations.json" HOMEBREW_TAP_MIGRATIONS_FILE = "tap_migrations.json"
HOMEBREW_TAP_AUTOBUMP_FILE = ".github/autobump.txt" HOMEBREW_TAP_AUTOBUMP_FILE = ".github/autobump.txt"
HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS_FILE = "pypi_formula_mappings.json"
HOMEBREW_TAP_SYNCED_VERSIONS_FORMULAE_FILE = "synced_versions_formulae.json"
HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR = "audit_exceptions" HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR = "audit_exceptions"
HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR = "style_exceptions" HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR = "style_exceptions"
HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS = "pypi_formula_mappings.json"
TAP_MIGRATIONS_STALE_SECONDS = 86400 # 1 day TAP_MIGRATIONS_STALE_SECONDS = 86400 # 1 day
@ -32,9 +33,10 @@ class Tap
#{HOMEBREW_TAP_FORMULA_RENAMES_FILE} #{HOMEBREW_TAP_FORMULA_RENAMES_FILE}
#{HOMEBREW_TAP_CASK_RENAMES_FILE} #{HOMEBREW_TAP_CASK_RENAMES_FILE}
#{HOMEBREW_TAP_MIGRATIONS_FILE} #{HOMEBREW_TAP_MIGRATIONS_FILE}
#{HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS_FILE}
#{HOMEBREW_TAP_SYNCED_VERSIONS_FORMULAE_FILE}
#{HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR}/*.json #{HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR}/*.json
#{HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR}/*.json #{HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR}/*.json
#{HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS}
].freeze ].freeze
def self.fetch(*args) def self.fetch(*args)
@ -177,6 +179,7 @@ class Tap
@audit_exceptions = nil @audit_exceptions = nil
@style_exceptions = nil @style_exceptions = nil
@pypi_formula_mappings = nil @pypi_formula_mappings = nil
@synced_versions_formulae = nil
@config = nil @config = nil
@spell_checker = nil @spell_checker = nil
remove_instance_variable(:@private) if instance_variable_defined?(:@private) remove_instance_variable(:@private) if instance_variable_defined?(:@private)
@ -857,7 +860,17 @@ class Tap
# Hash with pypi formula mappings # Hash with pypi formula mappings
def pypi_formula_mappings def pypi_formula_mappings
@pypi_formula_mappings = read_formula_list path/HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS @pypi_formula_mappings = read_formula_list path/HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS_FILE
end
# Array with synced versions formulae
sig { returns(T::Array[T::Array[String]]) }
def synced_versions_formulae
@synced_versions_formulae ||= if (synced_file = path/HOMEBREW_TAP_SYNCED_VERSIONS_FORMULAE_FILE).file?
JSON.parse(synced_file.read)
else
[]
end
end end
# @private # @private
@ -1168,6 +1181,15 @@ class CoreTap < AbstractCoreTap
end end
end end
# @private
sig { returns(T::Array[T::Array[String]]) }
def synced_versions_formulae
@synced_versions_formulae ||= begin
ensure_installed!
super
end
end
# @private # @private
sig { params(file: Pathname).returns(String) } sig { params(file: Pathname).returns(String) }
def formula_file_to_name(file) def formula_file_to_name(file)