diff --git a/Library/Homebrew/formula_auditor.rb b/Library/Homebrew/formula_auditor.rb index 8c193c460356ba25052080019f03f72295b0d67a..0392b11e7e511a3ee42ed9a03ff06f49504ec14a 100644 --- a/Library/Homebrew/formula_auditor.rb +++ b/Library/Homebrew/formula_auditor.rb @@ -165,11 +165,6 @@ module Homebrew "LGPL-3.0" => ["LGPL-3.0-only", "LGPL-3.0-or-later"], }.freeze - PERMITTED_FORMULA_LICENSE_MISMATCHES = { - "cmockery" => "0.1.2", - "scw@1" => "1.20", - }.freeze - def audit_license if formula.license.present? licenses, exceptions = SPDX.parse_license_expression formula.license @@ -213,7 +208,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 PERMITTED_FORMULA_LICENSE_MISMATCHES[formula.name] == formula.version + return if tap_audit_exception :permitted_formula_license_mismatches, formula.name problem "Formula license #{licenses} does not match GitHub license #{Array(github_license)}." @@ -821,6 +816,7 @@ module Homebrew 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] diff --git a/Library/Homebrew/test/dev-cmd/audit_spec.rb b/Library/Homebrew/test/dev-cmd/audit_spec.rb index 4548be2e0fa686bfa94b3744e2545e07914cf11c..9e078676432cad246fc3cd8f850b15ddae36dc3e 100644 --- a/Library/Homebrew/test/dev-cmd/audit_spec.rb +++ b/Library/Homebrew/test/dev-cmd/audit_spec.rb @@ -423,6 +423,23 @@ module Homebrew .to eq 'Formula license ["0BSD"] does not match GitHub license ["GPL-3.0"].' end + it "allows a formula-specified license that differs from its GitHub "\ + "repository for formulae on the mismatched license allowlist" do + formula_text = <<~RUBY + class Cask < Formula + url "https://github.com/cask/cask/archive/v0.8.4.tar.gz" + head "https://github.com/cask/cask.git" + license "0BSD" + end + RUBY + fa = formula_auditor "cask", formula_text, spdx_license_data: spdx_license_data, + online: true, core_tap: true, new_formula: true, + tap_audit_exceptions: { permitted_formula_license_mismatches: ["cask"] } + + fa.audit_license + expect(fa.problems).to be_empty + end + it "checks online and detects that an array of license does not contain "\ "what is indicated on its Github repository" do formula_text = <<~RUBY @@ -543,6 +560,91 @@ module Homebrew end end + describe "#audit_specs" do + let(:throttle_list) { { throttled_formulae: { "foo" => 10 } } } + let(:versioned_head_spec_list) { { versioned_head_spec_allowlist: ["foo"] } } + + it "allows versions with no throttle rate" do + fa = formula_auditor "bar", <<~RUBY, core_tap: true, tap_audit_exceptions: throttle_list + class Bar < Formula + url "https://brew.sh/foo-1.0.1.tgz" + end + RUBY + + fa.audit_specs + expect(fa.problems).to be_empty + end + + it "allows major/minor versions with throttle rate" do + fa = formula_auditor "foo", <<~RUBY, core_tap: true, tap_audit_exceptions: throttle_list + class Foo < Formula + url "https://brew.sh/foo-1.0.0.tgz" + end + RUBY + + fa.audit_specs + expect(fa.problems).to be_empty + end + + it "allows patch versions to be multiples of the throttle rate" do + fa = formula_auditor "foo", <<~RUBY, core_tap: true, tap_audit_exceptions: throttle_list + class Foo < Formula + url "https://brew.sh/foo-1.0.10.tgz" + end + RUBY + + fa.audit_specs + expect(fa.problems).to be_empty + end + + it "doesn't allow patch versions that aren't multiples of the throttle rate" do + fa = formula_auditor "foo", <<~RUBY, core_tap: true, tap_audit_exceptions: throttle_list + class Foo < Formula + url "https://brew.sh/foo-1.0.1.tgz" + end + RUBY + + fa.audit_specs + expect(fa.problems.first[:message]).to match "should only be updated every 10 releases on multiples of 10" + end + + it "allows non-versioned formulae to have a `HEAD` spec" do + fa = formula_auditor "bar", <<~RUBY, core_tap: true, tap_audit_exceptions: versioned_head_spec_list + class Bar < Formula + url "https://brew.sh/foo-1.0.tgz" + head "https://brew.sh/foo-1.0.tgz" + end + RUBY + + fa.audit_specs + expect(fa.problems).to be_empty + end + + it "doesn't allow versioned formulae to have a `HEAD` spec" do + fa = formula_auditor "bar@1", <<~RUBY, core_tap: true, tap_audit_exceptions: versioned_head_spec_list + class BarAT1 < Formula + url "https://brew.sh/foo-1.0.tgz" + head "https://brew.sh/foo-1.0.tgz" + end + RUBY + + fa.audit_specs + expect(fa.problems.first[:message]).to match "Versioned formulae should not have a `HEAD` spec" + end + + it "allows ersioned formulae on the allowlist to have a `HEAD` spec" do + fa = formula_auditor "foo", <<~RUBY, core_tap: true, tap_audit_exceptions: versioned_head_spec_list + class Foo < Formula + url "https://brew.sh/foo-1.0.tgz" + head "https://brew.sh/foo-1.0.tgz" + end + RUBY + + fa.audit_specs + expect(fa.problems).to be_empty + end + end + describe "#audit_deps" do describe "a dependency on a macOS-provided keg-only formula" do describe "which is allowlisted" do