diff --git a/Library/Homebrew/rubocops/uses_from_macos.rb b/Library/Homebrew/rubocops/uses_from_macos.rb index 539de517fb..57cc9b02c8 100644 --- a/Library/Homebrew/rubocops/uses_from_macos.rb +++ b/Library/Homebrew/rubocops/uses_from_macos.rb @@ -8,18 +8,86 @@ module RuboCop module FormulaAudit # This cop audits formulae that are keg-only because they are provided by macos. class ProvidedByMacos < FormulaCop + PROVIDED_BY_MACOS_FORMULAE = %w[ + apr + bc + bison + bzip2 + cups + curl + dyld-headers + ed + expat + file-formula + flex + gcore + gnu-getopt + icu4c + krb5 + libarchive + libedit + libffi + libiconv + libpcap + libressl + libxml2 + libxslt + llvm + lsof + m4 + ncompress + ncurses + net-snmp + openldap + openlibm + pod2man + rpcgen + ruby + sqlite + ssh-copy-id + swift + tcl-tk + texinfo + unifdef + unzip + zip + zlib + ].freeze + def audit_formula(_node, _class_node, _parent_class_node, body_node) find_method_with_args(body_node, :keg_only, :provided_by_macos) do - unless tap_style_exception? :provided_by_macos_formulae - problem "Formulae that are `keg_only :provided_by_macos` should be added to "\ - "`style_exceptions/provided_by_macos_formulae.json`" - end + return if PROVIDED_BY_MACOS_FORMULAE.include? @formula_name + return if tap_style_exception? :provided_by_macos_formulae + + problem "Formulae that are `keg_only :provided_by_macos` should be added to "\ + "`style_exceptions/provided_by_macos_formulae.json`" end end end # This cop audits `uses_from_macos` dependencies in formulae. class UsesFromMacos < FormulaCop + # These formulae aren't `keg_only :provided_by_macos` but are provided by + # macOS (or very similarly, e.g. OpenSSL where system provides LibreSSL). + # TODO: consider making some of these keg-only. + ALLOWED_USES_FROM_MACOS_DEPS = %w[ + bash + cpio + expect + groff + gzip + openssl + openssl@1.1 + perl + php + python + python@3 + rsync + vim + xz + zsh + ].freeze + def audit_formula(_node, _class_node, _parent_class_node, body_node) find_method_with_args(body_node, :uses_from_macos, /^"(.+)"/).each do |method| dep = if parameters(method).first.instance_of?(RuboCop::AST::StrNode) @@ -28,10 +96,13 @@ module RuboCop parameters(method).first.keys.first end - next if tap_style_exception? :provided_by_macos_formulae, string_content(dep) - next if tap_style_exception? :non_keg_only_provided_by_macos_formulae, string_content(dep) + dep_name = string_content(dep) + next if ALLOWED_USES_FROM_MACOS_DEPS.include? dep_name + next if ProvidedByMacos::PROVIDED_BY_MACOS_FORMULAE.include? dep_name + next if tap_style_exception? :provided_by_macos_formulae, dep_name + next if tap_style_exception? :non_keg_only_provided_by_macos_formulae, dep_name - problem "`uses_from_macos` should only be used for macOS dependencies, not #{string_content(dep)}." + problem "`uses_from_macos` should only be used for macOS dependencies, not #{dep_name}." end end end diff --git a/Library/Homebrew/test/rubocops/provided_by_macos_spec.rb b/Library/Homebrew/test/rubocops/provided_by_macos_spec.rb index e2c331cc87..5f09e9357e 100644 --- a/Library/Homebrew/test/rubocops/provided_by_macos_spec.rb +++ b/Library/Homebrew/test/rubocops/provided_by_macos_spec.rb @@ -58,4 +58,6 @@ describe RuboCop::Cop::FormulaAudit::ProvidedByMacos do end RUBY end + + include_examples "formulae exist", described_class::PROVIDED_BY_MACOS_FORMULAE end diff --git a/Library/Homebrew/test/rubocops/uses_from_macos_spec.rb b/Library/Homebrew/test/rubocops/uses_from_macos_spec.rb index 7495d680b2..6a12800505 100644 --- a/Library/Homebrew/test/rubocops/uses_from_macos_spec.rb +++ b/Library/Homebrew/test/rubocops/uses_from_macos_spec.rb @@ -17,4 +17,6 @@ describe RuboCop::Cop::FormulaAudit::UsesFromMacos do end RUBY end + + include_examples "formulae exist", described_class::ALLOWED_USES_FROM_MACOS_DEPS end diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb index fc0c1ecbab..47a9d38ab3 100644 --- a/Library/Homebrew/test/spec_helper.rb +++ b/Library/Homebrew/test/spec_helper.rb @@ -47,6 +47,7 @@ require "test/support/helper/output_as_tty" require "test/support/helper/spec/shared_context/homebrew_cask" if OS.mac? require "test/support/helper/spec/shared_context/integration_test" +require "test/support/helper/spec/shared_examples/formulae_exist" TEST_DIRECTORIES = [ CoreTap.instance.path/"Formula", diff --git a/Library/Homebrew/test/support/helper/spec/shared_examples/formulae_exist.rb b/Library/Homebrew/test/support/helper/spec/shared_examples/formulae_exist.rb new file mode 100644 index 0000000000..e52610016f --- /dev/null +++ b/Library/Homebrew/test/support/helper/spec/shared_examples/formulae_exist.rb @@ -0,0 +1,13 @@ +# typed: false +# frozen_string_literal: true + +shared_examples "formulae exist" do |array| + array.each do |f| + it "#{f} formula exists" do + core_tap = Pathname("#{HOMEBREW_LIBRARY_PATH}/../Taps/homebrew/homebrew-core") + formula_path = core_tap/"Formula/#{f}.rb" + alias_path = core_tap/"Aliases/#{f}" + expect(formula_path.exist? || alias_path.exist?).to be true + end + end +end