Refactor audit exception handling

This commit is contained in:
Rylan Polster 2021-10-04 21:45:20 -04:00
parent d124d8eae8
commit fa4bb7d74a
No known key found for this signature in database
GPG Key ID: 46A744940CFF4D64
8 changed files with 52 additions and 95 deletions

View File

@ -44,7 +44,6 @@ module Cask
@strict = strict @strict = strict
@new_cask = new_cask @new_cask = new_cask
@token_conflicts = token_conflicts @token_conflicts = token_conflicts
@tap_audit_exceptions = cask.tap&.audit_exceptions
end end
def run! def run!
@ -737,25 +736,25 @@ module Cask
return unless download return unless download
if cask.url && !cask.url.using if cask.url && !cask.url.using
check_url_for_https_availability(cask.url, "binary URL", check_url_for_https_availability(cask.url, "binary URL", cask.token, cask.tap,
user_agents: [cask.url.user_agent]) user_agents: [cask.url.user_agent])
end end
check_url_for_https_availability(cask.appcast, "appcast URL", check_content: true) if cask.appcast && appcast? if cask.appcast && appcast?
check_url_for_https_availability(cask.appcast, "appcast URL", cask.token, cask.tap, check_content: true)
end
return unless cask.homepage return unless cask.homepage
check_url_for_https_availability(cask.homepage, check_url_for_https_availability(cask.homepage, "homepage URL", cask.token, cask.tap,
"homepage URL",
cask.token,
user_agents: [:browser, :default], user_agents: [:browser, :default],
check_content: true, check_content: true,
strict: strict?) strict: strict?)
end end
def check_url_for_https_availability(url_to_check, url_type, cask_token, **options) def check_url_for_https_availability(url_to_check, url_type, cask_token, tap, **options)
problem = curl_check_http_content(url_to_check.to_s, url_type, **options) problem = curl_check_http_content(url_to_check.to_s, url_type, **options)
exception = tap_audit_exception(:cert_error_allowlist, cask_token, url_to_check) exception = tap&.audit_exception(:cert_error_allowlist, cask_token, url_to_check.to_s)
if problem if problem
add_error problem unless exception add_error problem unless exception
@ -763,22 +762,5 @@ module Cask
add_error "#{url_to_check} is in the certificate error allowlist but does not have a certificate error" add_error "#{url_to_check} is in the certificate error allowlist but does not have a certificate error"
end end
end end
def tap_audit_exception(list, 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? cask
when Hash
return false unless list.include? cask
return list[cask] if value.blank?
list[cask] == value
end
end
end end
end end

View File

@ -177,7 +177,6 @@ module Homebrew
except: args.except, except: args.except,
spdx_license_data: spdx_license_data, spdx_license_data: spdx_license_data,
spdx_exception_data: spdx_exception_data, spdx_exception_data: spdx_exception_data,
tap_audit_exceptions: f.tap&.audit_exceptions,
style_offenses: style_offenses ? style_offenses.for_path(f.path) : nil, style_offenses: style_offenses ? style_offenses.for_path(f.path) : nil,
display_cop_names: args.display_cop_names?, display_cop_names: args.display_cop_names?,
}.compact }.compact

View File

@ -90,7 +90,7 @@ module FormulaCellarChecks
def check_flat_namespace(formula) def check_flat_namespace(formula)
return unless formula.prefix.directory? return unless formula.prefix.directory?
return if formula.tap.present? && tap_audit_exception(:flat_namespace_allowlist, formula.name) return if formula.tap.present? && formula.tap.audit_exception(:flat_namespace_allowlist, formula.name)
keg = Keg.new(formula.prefix) keg = Keg.new(formula.prefix)
flat_namespace_files = keg.mach_o_files.reject do |file| flat_namespace_files = keg.mach_o_files.reject do |file|

View File

@ -35,7 +35,6 @@ module Homebrew
@specs = %w[stable head].map { |s| formula.send(s) }.compact @specs = %w[stable head].map { |s| formula.send(s) }.compact
@spdx_license_data = options[:spdx_license_data] @spdx_license_data = options[:spdx_license_data]
@spdx_exception_data = options[:spdx_exception_data] @spdx_exception_data = options[:spdx_exception_data]
@tap_audit_exceptions = options[:tap_audit_exceptions]
end end
def audit_style def audit_style
@ -196,7 +195,7 @@ module Homebrew
return unless github_license return unless github_license
return if (licenses + ["NOASSERTION"]).include?(github_license) return if (licenses + ["NOASSERTION"]).include?(github_license)
return if PERMITTED_LICENSE_MISMATCHES[github_license]&.any? { |license| licenses.include? license } return if PERMITTED_LICENSE_MISMATCHES[github_license]&.any? { |license| licenses.include? license }
return if tap_audit_exception :permitted_formula_license_mismatches, formula.name return if formula.tap&.audit_exception :permitted_formula_license_mismatches, formula.name
problem "Formula license #{licenses} does not match GitHub license #{Array(github_license)}." problem "Formula license #{licenses} does not match GitHub license #{Array(github_license)}."
@ -236,7 +235,7 @@ module Homebrew
dep_f.keg_only_reason.provided_by_macos? && dep_f.keg_only_reason.provided_by_macos? &&
dep_f.keg_only_reason.applicable? && dep_f.keg_only_reason.applicable? &&
formula.requirements.none?(LinuxRequirement) && formula.requirements.none?(LinuxRequirement) &&
!tap_audit_exception(:provided_by_macos_depends_on_allowlist, dep.name) !formula.tap&.audit_exception(:provided_by_macos_depends_on_allowlist, dep.name)
new_formula_problem( new_formula_problem(
"Dependency '#{dep.name}' is provided by macOS; " \ "Dependency '#{dep.name}' is provided by macOS; " \
"please replace 'depends_on' with 'uses_from_macos'.", "please replace 'depends_on' with 'uses_from_macos'.",
@ -281,7 +280,7 @@ module Homebrew
end end
return unless @core_tap return unless @core_tap
return if tap_audit_exception :versioned_dependencies_conflicts_allowlist, formula.name return if formula.tap&.audit_exception :versioned_dependencies_conflicts_allowlist, formula.name
# The number of conflicts on Linux is absurd. # The number of conflicts on Linux is absurd.
# TODO: remove this and check these there too. # TODO: remove this and check these there too.
@ -397,7 +396,7 @@ module Homebrew
return if formula.name.start_with?("openssl", "libressl") && formula.keg_only_reason.by_macos? return if formula.name.start_with?("openssl", "libressl") && formula.keg_only_reason.by_macos?
end end
return if tap_audit_exception :versioned_keg_only_allowlist, formula.name return if formula.tap&.audit_exception :versioned_keg_only_allowlist, formula.name
problem "Versioned formulae in homebrew/core should use `keg_only :versioned_formula`" problem "Versioned formulae in homebrew/core should use `keg_only :versioned_formula`"
end end
@ -409,7 +408,7 @@ module Homebrew
return unless @online return unless @online
return if tap_audit_exception :cert_error_allowlist, formula.name, homepage return if formula.tap&.audit_exception :cert_error_allowlist, formula.name, homepage
return unless DevelopmentTools.curl_handles_most_https_certificates? return unless DevelopmentTools.curl_handles_most_https_certificates?
@ -536,7 +535,7 @@ module Homebrew
except = @except.to_a except = @except.to_a
if spec_name == :head && if spec_name == :head &&
tap_audit_exception(:head_non_default_branch_allowlist, formula.name, spec.specs[:branch]) formula.tap&.audit_exception(:head_non_default_branch_allowlist, formula.name, spec.specs[:branch])
except << "head_branch" except << "head_branch"
end end
@ -573,7 +572,7 @@ module Homebrew
return unless @core_tap return unless @core_tap
if formula.head && @versioned_formula && if formula.head && @versioned_formula &&
!tap_audit_exception(:versioned_head_spec_allowlist, formula.name) !formula.tap&.audit_exception(:versioned_head_spec_allowlist, formula.name)
problem "Versioned formulae should not have a `HEAD` spec" problem "Versioned formulae should not have a `HEAD` spec"
end end
@ -593,7 +592,7 @@ module Homebrew
stable_url_minor_version = stable_url_version.minor.to_i stable_url_minor_version = stable_url_version.minor.to_i
formula_suffix = stable.version.patch.to_i formula_suffix = stable.version.patch.to_i
throttled_rate = tap_audit_exception(:throttled_formulae, formula.name) throttled_rate = formula.tap&.audit_exception(:throttled_formulae, formula.name)
if throttled_rate && formula_suffix.modulo(throttled_rate).nonzero? if throttled_rate && formula_suffix.modulo(throttled_rate).nonzero?
problem "should only be updated every #{throttled_rate} releases on multiples of #{throttled_rate}" problem "should only be updated every #{throttled_rate} releases on multiples of #{throttled_rate}"
end end
@ -602,13 +601,13 @@ module Homebrew
when /[\d._-](alpha|beta|rc\d)/ when /[\d._-](alpha|beta|rc\d)/
matched = Regexp.last_match(1) matched = Regexp.last_match(1)
version_prefix = stable_version_string.sub(/\d+$/, "") version_prefix = stable_version_string.sub(/\d+$/, "")
return if tap_audit_exception :unstable_allowlist, formula.name, version_prefix return if formula.tap&.audit_exception :unstable_allowlist, formula.name, version_prefix
return if tap_audit_exception :unstable_devel_allowlist, formula.name, version_prefix return if formula.tap&.audit_exception :unstable_devel_allowlist, formula.name, version_prefix
problem "Stable version URLs should not contain #{matched}" problem "Stable version URLs should not contain #{matched}"
when %r{download\.gnome\.org/sources}, %r{ftp\.gnome\.org/pub/GNOME/sources}i when %r{download\.gnome\.org/sources}, %r{ftp\.gnome\.org/pub/GNOME/sources}i
version_prefix = stable.version.major_minor version_prefix = stable.version.major_minor
return if tap_audit_exception :gnome_devel_allowlist, formula.name, version_prefix return if formula.tap&.audit_exception :gnome_devel_allowlist, formula.name, version_prefix
return if stable_url_version < Version.create("1.0") return if stable_url_version < Version.create("1.0")
# All minor versions are stable in the new GNOME version scheme (which starts at version 40.0) # All minor versions are stable in the new GNOME version scheme (which starts at version 40.0)
# https://discourse.gnome.org/t/new-gnome-versioning-scheme/4235 # https://discourse.gnome.org/t/new-gnome-versioning-scheme/4235
@ -812,22 +811,5 @@ module Homebrew
def head_only?(formula) def head_only?(formula)
formula.head && formula.stable.nil? formula.head && formula.stable.nil?
end end
def tap_audit_exception(list, formula, 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
when Hash
return false unless list.include? formula
return list[formula] if value.blank?
list[formula] == value
end
end
end end
end end

View File

@ -332,13 +332,13 @@ module FormulaCellarChecks
end.map(&:to_h) # To prevent transformation into nested arrays end.map(&:to_h) # To prevent transformation into nested arrays
universal_binaries_expected = if formula.tap.present? && formula.tap.core_tap? universal_binaries_expected = if formula.tap.present? && formula.tap.core_tap?
tap_audit_exception(:universal_binary_allowlist, formula.name) formula.tap.audit_exception(:universal_binary_allowlist, formula.name)
else else
true true
end end
return if mismatches.empty? && universal_binaries_expected return if mismatches.empty? && universal_binaries_expected
mismatches_expected = formula.tap.blank? || tap_audit_exception(:mismatched_binary_allowlist, formula.name) mismatches_expected = formula.tap&.audit_exception(:mismatched_binary_allowlist, formula.name) || true
return if compatible_universal_binaries.empty? && mismatches_expected return if compatible_universal_binaries.empty? && mismatches_expected
return if universal_binaries_expected && mismatches_expected return if universal_binaries_expected && mismatches_expected

View File

@ -1212,12 +1212,6 @@ class FormulaInstaller
super super
end end
# This is a stub for calls made to this method at install time.
# Exceptions are correctly identified when doing `brew audit`.
def tap_audit_exception(*)
true
end
def self.locked def self.locked
@locked ||= [] @locked ||= []
end end

View File

@ -691,6 +691,23 @@ class Tap
"#{name}/#{file.basename}" "#{name}/#{file.basename}"
end end
def audit_exception(list, formula_or_cask, value = nil)
return false if audit_exceptions.blank?
return false unless audit_exceptions.key? list
list = audit_exceptions[list]
case list
when Array
list.include? formula_or_cask
when Hash
return false unless list.include? formula_or_cask
return list[formula_or_cask] if value.blank?
list[formula_or_cask] == value
end
end
private private
def read_or_set_private_config def read_or_set_private_config

View File

@ -37,9 +37,9 @@ module SharedAudits
return unless release return unless release
exception, name, version = if formula exception, name, version = if formula
[tap_audit_exception(:github_prerelease_allowlist, formula.tap, formula.name), formula.name, formula.version] [formula.tap&.audit_exception(:github_prerelease_allowlist, formula.name), formula.name, formula.version]
elsif cask elsif cask
[tap_audit_exception(:github_prerelease_allowlist, cask.tap, cask.token), cask.token, cask.version] [cask.tap&.audit_exception(:github_prerelease_allowlist, cask.token), cask.token, cask.version]
end end
return "#{tag} is a GitHub pre-release." if release["prerelease"] && [version, "all"].exclude?(exception) return "#{tag} is a GitHub pre-release." if release["prerelease"] && [version, "all"].exclude?(exception)
@ -77,9 +77,9 @@ module SharedAudits
return if DateTime.parse(release["released_at"]) <= DateTime.now return if DateTime.parse(release["released_at"]) <= DateTime.now
exception, version = if formula exception, version = if formula
[tap_audit_exception(:gitlab_prerelease_allowlist, formula.tap, formula.name), formula.version] [formula.tap&.audit_exception(:gitlab_prerelease_allowlist, formula.name), formula.version]
elsif cask elsif cask
[tap_audit_exception(:gitlab_prerelease_allowlist, cask.tap, cask.token), cask.version] [cask.tap&.audit_exception(:gitlab_prerelease_allowlist, cask.token), cask.version]
end end
return if [version, "all"].include?(exception) return if [version, "all"].include?(exception)
@ -166,21 +166,4 @@ module SharedAudits
.to_a .to_a
.second .second
end 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 end