From 44fd8adf1f46074a6bdb1d2bf41ae3f84396d659 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Tue, 25 Jun 2024 22:08:48 +0200 Subject: [PATCH] Share code between cask token and formula name audits. --- Library/Homebrew/cask/audit.rb | 31 +++++--------- Library/Homebrew/formula_auditor.rb | 9 ++++- Library/Homebrew/test/cask/audit_spec.rb | 40 ++++--------------- Library/Homebrew/test/formula_auditor_spec.rb | 6 +-- Library/Homebrew/token_auditor.rb | 40 +++++++++++++++++++ 5 files changed, 68 insertions(+), 58 deletions(-) create mode 100644 Library/Homebrew/token_auditor.rb diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index 83a46b39ef201b..dac70e801873c4 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -8,6 +8,7 @@ require "livecheck/livecheck" require "source_location" require "system_command" +require "token_auditor" require "utils/curl" require "utils/git" require "utils/shared_audits" @@ -391,6 +392,15 @@ def audit_languages end end + sig { void } + def audit_token + token_auditor = Homebrew::TokenAuditor.new(cask.token) + return if (errors = token_auditor.errors).empty? + + add_error "Cask token '#{cask.token}' must not contain #{errors.to_sentence(two_words_connector: " or ", + last_word_connector: " or ")}." + end + sig { void } def audit_token_conflicts return unless token_conflicts? @@ -405,27 +415,6 @@ def audit_token_conflicts end end - sig { void } - def audit_token_valid - add_error "cask token contains non-ascii characters" unless cask.token.ascii_only? - add_error "cask token + should be replaced by -plus-" if cask.token.include? "+" - add_error "cask token whitespace should be replaced by hyphens" if cask.token.include? " " - add_error "cask token underscores should be replaced by hyphens" if cask.token.include? "_" - add_error "cask token should not contain double hyphens" if cask.token.include? "--" - - if cask.token.match?(/[^@a-z0-9-]/) - add_error "cask token should only contain lowercase alphanumeric characters, hyphens and @" - end - - if cask.token.start_with?("-", "@") || cask.token.end_with?("-", "@") - add_error "cask token should not have leading or trailing hyphens and/or @" - end - - add_error "cask token @ unrelated to versioning should be replaced by -at-" if cask.token.count("@") > 1 - add_error "cask token should not contain a hyphen followed by @" if cask.token.include? "-@" - add_error "cask token should not contain @ followed by a hyphen" if cask.token.include? "@-" - end - sig { void } def audit_token_bad_words return unless new_cask? diff --git a/Library/Homebrew/formula_auditor.rb b/Library/Homebrew/formula_auditor.rb index 9fa5600bf764ac..ceb277ae9fe244 100644 --- a/Library/Homebrew/formula_auditor.rb +++ b/Library/Homebrew/formula_auditor.rb @@ -3,6 +3,7 @@ require "deprecate_disable" require "formula_versions" +require "token_auditor" require "resource_auditor" require "utils/shared_audits" @@ -160,10 +161,14 @@ def audit_synced_versions_formulae end end - def audit_formula_name + def audit_name name = formula.name - problem "Formula name '#{name}' must not contain uppercase letters." if name != name.downcase + token_auditor = Homebrew::TokenAuditor.new(name) + unless (errors = token_auditor.errors).empty? + problem "Formula name '#{name}' must not contain #{errors.to_sentence(two_words_connector: " or ", + last_word_connector: " or ")}." + end return unless @strict return unless @core_tap diff --git a/Library/Homebrew/test/cask/audit_spec.rb b/Library/Homebrew/test/cask/audit_spec.rb index 6da7326f7fdf94..622074b2d9f745 100644 --- a/Library/Homebrew/test/cask/audit_spec.rb +++ b/Library/Homebrew/test/cask/audit_spec.rb @@ -208,15 +208,7 @@ def tmp_cask(name, text) let(:cask_token) { "asciiāŒ˜" } it "fails" do - expect(run).to error_with(/contains non-ascii characters/) - end - end - - context "when cask token has +" do - let(:cask_token) { "app++" } - - it "fails" do - expect(run).to error_with(/\+ should be replaced by -plus-/) + expect(run).to error_with(/not contain non-ASCII characters/) end end @@ -240,7 +232,7 @@ def tmp_cask(name, text) let(:cask_token) { "app@stuff@beta" } it "fails" do - expect(run).to error_with(/@ unrelated to versioning should be replaced by -at-/) + expect(run).to error_with(/not contain multiple @ symbols/) end end @@ -248,7 +240,7 @@ def tmp_cask(name, text) let(:cask_token) { "app-@beta" } it "fails" do - expect(run).to error_with(/should not contain a hyphen followed by @/) + expect(run).to error_with(/not contain a hyphen followed by @/) end end @@ -256,7 +248,7 @@ def tmp_cask(name, text) let(:cask_token) { "app@-beta" } it "fails" do - expect(run).to error_with(/should not contain @ followed by a hyphen/) + expect(run).to error_with(/not contain @ followed by a hyphen/) end end @@ -264,23 +256,7 @@ def tmp_cask(name, text) let(:cask_token) { "app stuff" } it "fails" do - expect(run).to error_with(/whitespace should be replaced by hyphens/) - end - end - - context "when cask token has underscores" do - let(:cask_token) { "app_stuff" } - - it "fails" do - expect(run).to error_with(/underscores should be replaced by hyphens/) - end - end - - context "when cask token has non-alphanumeric characters" do - let(:cask_token) { "app(stuff)" } - - it "fails" do - expect(run).to error_with(/alphanumeric characters, hyphens and @/) + expect(run).to error_with(/not contain whitespace/) end end @@ -288,7 +264,7 @@ def tmp_cask(name, text) let(:cask_token) { "app--stuff" } it "fails" do - expect(run).to error_with(/should not contain double hyphens/) + expect(run).to error_with(/not contain double hyphens/) end end @@ -296,7 +272,7 @@ def tmp_cask(name, text) let(:cask_token) { "-app" } it "fails" do - expect(run).to error_with(/should not have leading or trailing hyphens/) + expect(run).to error_with(/not contain a leading hyphen/) end end @@ -304,7 +280,7 @@ def tmp_cask(name, text) let(:cask_token) { "app-" } it "fails" do - expect(run).to error_with(/should not have leading or trailing hyphens/) + expect(run).to error_with(/not contain a trailing hyphen/) end end end diff --git a/Library/Homebrew/test/formula_auditor_spec.rb b/Library/Homebrew/test/formula_auditor_spec.rb index cb52b57c580f86..70cffee63ce739 100644 --- a/Library/Homebrew/test/formula_auditor_spec.rb +++ b/Library/Homebrew/test/formula_auditor_spec.rb @@ -476,7 +476,7 @@ class Foo < Formula end end - describe "#audit_formula_name" do + describe "#audit_name" do specify "no issue" do fa = formula_auditor "foo", <<~RUBY, core_tap: true, strict: true class Foo < Formula @@ -485,7 +485,7 @@ class Foo < Formula end RUBY - fa.audit_formula_name + fa.audit_name expect(fa.problems).to be_empty end @@ -497,7 +497,7 @@ class Foo < Formula end RUBY - fa.audit_formula_name + fa.audit_name expect(fa.problems.first[:message]).to match "must not contain uppercase letters" end end diff --git a/Library/Homebrew/token_auditor.rb b/Library/Homebrew/token_auditor.rb new file mode 100644 index 00000000000000..11ad69388b4ebe --- /dev/null +++ b/Library/Homebrew/token_auditor.rb @@ -0,0 +1,40 @@ +# typed: true +# frozen_string_literal: true + +module Homebrew + class TokenAuditor + sig { returns(String) } + attr_reader :token + + sig { params(token: String).void } + def initialize(token) + @token = token + end + + sig { returns(T::Array[String]) } + def errors + errors = [] + + errors << "uppercase letters" if token.match?(/[A-Z]/) + errors << "whitespace" if token.match?(/\s/) + errors << "non-ASCII characters" unless token.ascii_only? + errors << "double hyphens" if token.include?("--") + + # A bunch of formulae contain these: + # errors << "underscores" if token.include?("_") + # errors << "plus symbols" if token.include?("+") + + errors << "a leading @" if token.start_with?("@") + errors << "a trailing @" if token.end_with?("@") + errors << "a leading hyphen" if token.start_with?("-") + errors << "a trailing hyphen" if token.end_with?("-") + + errors << "multiple @ symbols" if token.count("@") > 1 + + errors << "a hyphen followed by an @" if token.include? "-@" + errors << "an @ followed by a hyphen" if token.include? "@-" + + errors + end + end +end