diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index 6121c1ac00e69..478feb0fc6ce5 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -582,7 +582,7 @@ def check_gitlab_prerelease_version tag = SharedAudits.gitlab_tag_from_url(cask.url) tag ||= cask.version - error = SharedAudits.gitlab_release(user, repo, tag) + error = SharedAudits.gitlab_release(user, repo, tag, cask: cask) add_error error if error end diff --git a/Library/Homebrew/tap_auditor.rb b/Library/Homebrew/tap_auditor.rb index aa08ace9e78f0..574dae149a767 100644 --- a/Library/Homebrew/tap_auditor.rb +++ b/Library/Homebrew/tap_auditor.rb @@ -8,12 +8,15 @@ module Homebrew class TapAuditor extend T::Sig - attr_reader :name, :path, :tap_audit_exceptions, :tap_style_exceptions, :tap_pypi_formula_mappings, :problems + attr_reader :name, :path, :formula_names, :cask_tokens, :tap_audit_exceptions, :tap_style_exceptions, + :tap_pypi_formula_mappings, :problems sig { params(tap: Tap, strict: T.nilable(T::Boolean)).void } def initialize(tap, strict:) @name = tap.name @path = tap.path + @formula_names = tap.formula_names + @cask_tokens = tap.cask_tokens @tap_audit_exceptions = tap.audit_exceptions @tap_style_exceptions = tap.style_exceptions @tap_pypi_formula_mappings = tap.pypi_formula_mappings @@ -60,19 +63,17 @@ def check_formula_list(list_file, list) return end - invalid_formulae = [] - list.each do |name, _| - invalid_formulae << name if Formula[name].tap != @name - rescue FormulaUnavailableError - invalid_formulae << name + list = list.keys if list.is_a? Hash + invalid_formulae_casks = list.select do |formula_or_cask_name| + @formula_names.exclude?(formula_or_cask_name) && @cask_tokens.exclude?("#{@name}/#{formula_or_cask_name}") end - return if invalid_formulae.empty? + return if invalid_formulae_casks.empty? problem <<~EOS #{list_file}.json references - formulae that are not found in the #{@name} tap. - Invalid formulae: #{invalid_formulae.join(", ")} + formulae or casks that are not found in the #{@name} tap. + Invalid formulae or casks: #{invalid_formulae_casks.join(", ")} EOS end diff --git a/Library/Homebrew/utils/shared_audits.rb b/Library/Homebrew/utils/shared_audits.rb index 7f574f9a95a8f..7e390307bc042 100644 --- a/Library/Homebrew/utils/shared_audits.rb +++ b/Library/Homebrew/utils/shared_audits.rb @@ -31,39 +31,19 @@ def github_release_data(user, repo, tag) nil end - GITHUB_PRERELEASE_ALLOWLIST = { - "elm-format" => "0.8.3", - "extraterm" => :all, - "freetube" => :all, - "gitless" => "0.8.8", - "haptickey" => :all, - "home-assistant" => :all, - "lidarr" => :all, - "nuclear" => :all, - "pock" => :all, - "riff" => "0.5.0", - "syntax-highlight" => :all, - "telegram-cli" => "1.3.1", - "toggl-track" => :all, - "volta" => "0.8.6", - "xit" => :all, - }.freeze - def github_release(user, repo, tag, formula: nil, cask: nil) release = github_release_data(user, repo, tag) return unless release - if cask && GITHUB_PRERELEASE_ALLOWLIST[cask.token] == :all - return if release["prerelease"] - - return "#{tag} is not a GitHub pre-release but cask '#{cask.token}' is in GITHUB_PRERELEASE_ALLOWLIST." + exception, name, version = if formula + [tap_audit_exception(:github_prerelease_allowlist, formula.tap, formula.name), formula.name, formula.version] + elsif cask + [tap_audit_exception(:github_prerelease_allowlist, cask.tap, cask.token), cask.token, cask.version] end - if release["prerelease"] - return if formula && GITHUB_PRERELEASE_ALLOWLIST[formula.name] == formula.version + return "#{tag} is a GitHub pre-release." if release["prerelease"] && [version, "all"].exclude?(exception) - return "#{tag} is a GitHub pre-release." - end + return "#{tag} is not a GitHub pre-release but '#{name}' is in the GitHub prerelease allowlist." if exception return "#{tag} is a GitHub draft." if release["draft"] end @@ -87,30 +67,28 @@ def gitlab_release_data(user, repo, tag) end end - GITLAB_PRERELEASE_ALLOWLIST = {}.freeze - - def gitlab_release(user, repo, tag, formula: nil) + def gitlab_release(user, repo, tag, formula: nil, cask: nil) release = gitlab_release_data(user, repo, tag) return unless release return if Date.parse(release["released_at"]) <= Date.today - return if formula && GITLAB_PRERELEASE_ALLOWLIST[formula.name] == formula.version + + exception, version = if formula + [tap_audit_exception(:gitlab_prerelease_allowlist, formula.tap, formula.name), formula.version] + elsif cask + [tap_audit_exception(:gitlab_prerelease_allowlist, cask.tap, cask.token), cask.version] + end + return if [version, "all"].include?(exception) "#{tag} is a GitLab pre-release." end - GITHUB_FORK_ALLOWLIST = %w[ - variar/klogg - ].freeze - def github(user, repo) metadata = github_repo_data(user, repo) return if metadata.nil? - if metadata["fork"] && GITHUB_FORK_ALLOWLIST.exclude?("#{user}/#{repo}") - return "GitHub fork (not canonical repository)" - end + return "GitHub fork (not canonical repository)" if metadata["fork"] if (metadata["forks_count"] < 30) && (metadata["subscribers_count"] < 30) && (metadata["stargazers_count"] < 75) @@ -185,4 +163,21 @@ def gitlab_tag_from_url(url) .to_a .second end + + def tap_audit_exception(list, tap, formula_or_cask, value = nil) + return false if tap.audit_exceptions.blank? + return false unless tap.audit_exceptions.key? list + + list = tap.audit_exceptions[list] + + case list + when Array + list.include? formula_or_cask + when Hash + return false if list.exclude? formula_or_cask + return list[formula_or_cask] if value.blank? + + list[formula_or_cask] == value + end + end end