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
@new_cask = new_cask
@token_conflicts = token_conflicts
@tap_audit_exceptions = cask.tap&.audit_exceptions
end
def run!
@ -737,25 +736,25 @@ module Cask
return unless download
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])
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
check_url_for_https_availability(cask.homepage,
"homepage URL",
cask.token,
check_url_for_https_availability(cask.homepage, "homepage URL", cask.token, cask.tap,
user_agents: [:browser, :default],
check_content: true,
strict: strict?)
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)
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
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"
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

View File

@ -169,17 +169,16 @@ module Homebrew
formula_results = audit_formulae.sort.map do |f|
only = only_cops ? ["style"] : args.only
options = {
new_formula: new_formula,
strict: strict,
online: online,
git: args.git?,
only: only,
except: args.except,
spdx_license_data: spdx_license_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,
display_cop_names: args.display_cop_names?,
new_formula: new_formula,
strict: strict,
online: online,
git: args.git?,
only: only,
except: args.except,
spdx_license_data: spdx_license_data,
spdx_exception_data: spdx_exception_data,
style_offenses: style_offenses ? style_offenses.for_path(f.path) : nil,
display_cop_names: args.display_cop_names?,
}.compact
fa = FormulaAuditor.new(f, **options)

View File

@ -90,7 +90,7 @@ module FormulaCellarChecks
def check_flat_namespace(formula)
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)
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
@spdx_license_data = options[:spdx_license_data]
@spdx_exception_data = options[:spdx_exception_data]
@tap_audit_exceptions = options[:tap_audit_exceptions]
end
def audit_style
@ -196,7 +195,7 @@ module Homebrew
return unless github_license
return if (licenses + ["NOASSERTION"]).include?(github_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)}."
@ -236,7 +235,7 @@ module Homebrew
dep_f.keg_only_reason.provided_by_macos? &&
dep_f.keg_only_reason.applicable? &&
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(
"Dependency '#{dep.name}' is provided by macOS; " \
"please replace 'depends_on' with 'uses_from_macos'.",
@ -281,7 +280,7 @@ module Homebrew
end
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.
# 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?
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`"
end
@ -409,7 +408,7 @@ module Homebrew
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?
@ -536,7 +535,7 @@ module Homebrew
except = @except.to_a
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"
end
@ -573,7 +572,7 @@ module Homebrew
return unless @core_tap
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"
end
@ -593,7 +592,7 @@ module Homebrew
stable_url_minor_version = stable_url_version.minor.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?
problem "should only be updated every #{throttled_rate} releases on multiples of #{throttled_rate}"
end
@ -602,13 +601,13 @@ module Homebrew
when /[\d._-](alpha|beta|rc\d)/
matched = Regexp.last_match(1)
version_prefix = stable_version_string.sub(/\d+$/, "")
return if 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_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}"
when %r{download\.gnome\.org/sources}, %r{ftp\.gnome\.org/pub/GNOME/sources}i
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")
# 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
@ -812,22 +811,5 @@ module Homebrew
def head_only?(formula)
formula.head && formula.stable.nil?
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

View File

@ -332,13 +332,13 @@ module FormulaCellarChecks
end.map(&:to_h) # To prevent transformation into nested arrays
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
true
end
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 universal_binaries_expected && mismatches_expected

View File

@ -1212,12 +1212,6 @@ class FormulaInstaller
super
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
@locked ||= []
end

View File

@ -691,6 +691,23 @@ class Tap
"#{name}/#{file.basename}"
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
def read_or_set_private_config

View File

@ -37,9 +37,9 @@ module SharedAudits
return unless release
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
[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
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
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
[tap_audit_exception(:gitlab_prerelease_allowlist, cask.tap, cask.token), cask.version]
[cask.tap&.audit_exception(:gitlab_prerelease_allowlist, cask.token), cask.version]
end
return if [version, "all"].include?(exception)
@ -166,21 +166,4 @@ module SharedAudits
.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