diff --git a/Library/Homebrew/rubocops/resource_requires_dependencies.rb b/Library/Homebrew/rubocops/resource_requires_dependencies.rb new file mode 100644 index 0000000000000..c067208e10851 --- /dev/null +++ b/Library/Homebrew/rubocops/resource_requires_dependencies.rb @@ -0,0 +1,32 @@ +# typed: true +# frozen_string_literal: true + +require "rubocops/extend/formula_cop" + +module RuboCop + module Cop + module FormulaAudit + # This cop audits Python formulae that include the "lxml" resource + # to ensure that they also have the correct `uses_from_macos` + # dependencies. + # + # @api private + class ResourceRequiresDependencies < FormulaCop + def audit_formula(_node, _class_node, _parent_class_node, body_node) + return if body_node.nil? + + resource_nodes = find_every_method_call_by_name(body_node, :resource) + lxml = resource_nodes.find { |node| node.arguments.first.str_content == "lxml" } + return unless lxml + + uses_from_macos_nodes = find_every_method_call_by_name(body_node, :uses_from_macos) + dependencies = uses_from_macos_nodes.map { |node| node.arguments.first.str_content } + return if dependencies.include?("libxml2") && dependencies.include?("libxslt") + + offending_node(lxml) + problem "Add `uses_from_macos` lines above for `\"libxml2\"` and `\"libxslt\"`." + end + end + end + end +end diff --git a/Library/Homebrew/test/rubocops/resource_requires_dependencies_spec.rb b/Library/Homebrew/test/rubocops/resource_requires_dependencies_spec.rb new file mode 100644 index 0000000000000..581c5e6c3e8f4 --- /dev/null +++ b/Library/Homebrew/test/rubocops/resource_requires_dependencies_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require "rubocops/resource_requires_dependencies" + +RSpec.describe RuboCop::Cop::FormulaAudit::ResourceRequiresDependencies do + subject(:cop) { described_class.new } + + context "when a formula does not have the lxml resource" do + it "does not report offenses" do + expect_no_offenses(<<~RUBY) + class Foo < Formula + url "https://brew.sh/foo-1.0.tgz" + homepage "https://brew.sh" + + uses_from_macos "libxml2" + + resource "not-lxml" do + url "blah" + sha256 "blah" + end + end + RUBY + end + end + + context "when a formula has the lxml resource" do + it "does not report offenses if the dependencies are present" do + expect_no_offenses(<<~RUBY) + class Foo < Formula + url "https://brew.sh/foo-1.0.tgz" + homepage "https://brew.sh" + + uses_from_macos "libxml2" + uses_from_macos "libxslt" + + resource "lxml" do + url "blah" + sha256 "blah" + end + end + RUBY + end + + it "reports offenses if missing a dependency" do + expect_offense(<<~RUBY) + class Foo < Formula + url "https://brew.sh/foo-1.0.tgz" + homepage "https://brew.sh" + + uses_from_macos "libsomethingelse" + uses_from_macos "not_libxml2" + + resource "lxml" do + ^^^^^^^^^^^^^^^ FormulaAudit/ResourceRequiresDependencies: Add `uses_from_macos` lines above for `"libxml2"` and `"libxslt"`. + url "blah" + sha256 "blah" + end + end + RUBY + end + end +end