diff --git a/Library/Homebrew/rubocops/uses_from_macos.rb b/Library/Homebrew/rubocops/uses_from_macos.rb index 539de517fbdee..554a16b42c5ad 100644 --- a/Library/Homebrew/rubocops/uses_from_macos.rb +++ b/Library/Homebrew/rubocops/uses_from_macos.rb @@ -8,18 +8,93 @@ module Cop 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`" + return if PROVIDED_BY_MACOS_FORMULAE.include? @formula_name + return if tap_style_exception? :provided_by_macos_formulae + + message = if formula_tap == "homebrew-core" + "Formulae in homebrew/core that are `keg_only :provided_by_macos` should be "\ + "added to the `PROVIDED_BY_MACOS_FORMULAE` list (in the Homebrew/brew repo)" + else + "Formulae that are `keg_only :provided_by_macos` should be added to "\ + "`style_exceptions/provided_by_macos_formulae.json`" end + + problem message 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 +103,13 @@ def audit_formula(_node, _class_node, _parent_class_node, body_node) 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 e2c331cc87045..a0035f2b3ff0e 100644 --- a/Library/Homebrew/test/rubocops/provided_by_macos_spec.rb +++ b/Library/Homebrew/test/rubocops/provided_by_macos_spec.rb @@ -33,6 +33,18 @@ class Baz < Formula RUBY end + it "fails for homebrew-core formulae not in provided_by_macos_formulae list" do + expect_offense(<<~RUBY, "/homebrew-core/") + class Baz < Formula + url "https://brew.sh/baz-1.0.tgz" + homepage "https://brew.sh" + + keg_only :provided_by_macos + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Formulae in homebrew/core that are `keg_only :provided_by_macos` should be added to the `PROVIDED_BY_MACOS_FORMULAE` list (in the Homebrew/brew repo) + end + RUBY + end + it "succeeds for formulae in provided_by_macos_formulae list" do setup_style_exceptions @@ -58,4 +70,6 @@ class Baz < Formula 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 7495d680b2313..6a1280050518b 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 @@ class Foo < Formula 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 fc0c1ecbab6ce..47a9d38ab3d3b 100644 --- a/Library/Homebrew/test/spec_helper.rb +++ b/Library/Homebrew/test/spec_helper.rb @@ -47,6 +47,7 @@ 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 0000000000000..e52610016fc31 --- /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 diff --git a/manpages/brew.1 b/manpages/brew.1 index 4c34c64c7bc0c..684615bdd0b43 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BREW" "1" "November 2020" "Homebrew" "brew" +.TH "BREW" "1" "December 2020" "Homebrew" "brew" . .SH "NAME" \fBbrew\fR \- The Missing Package Manager for macOS (or Linux)