# frozen_string_literal: true require "rubocops/lines" RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do subject(:cop) { described_class.new } context "when auditing formula miscellany" do it "reports an offense for unneeded `FileUtils` usage" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' FileUtils.mv "hello" ^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: No need for `FileUtils.` before `mv` end RUBY end it "reports an offense for long `inreplace` block variable names" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' inreplace "foo" do |longvar| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: `inreplace do |s|` is preferred over `|longvar|`. somerandomCall(longvar) end end RUBY end it "reports an offense for invalid `rebuild` numbers" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' bottle do rebuild 0 ^^^^^^^^^ FormulaAudit/Miscellaneous: `rebuild 0` should be removed sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra end end RUBY end it "reports an offense when a useless `fails_with :llvm` is used" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' bottle do sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra end fails_with :llvm do ^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: `fails_with :llvm` is now a no-op and should be removed build 2335 cause "foo" end end RUBY end it "reports an offense when `def test` is used" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' def test ^^^^^^^^ FormulaAudit/Miscellaneous: Use new-style test definitions (`test do`) assert_equals "1", "1" end end RUBY end it "reports an offense when `skip_clean` is used" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' skip_clean :all ^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: `skip_clean :all` is deprecated; brew no longer strips symbols. Pass explicit paths to prevent Homebrew from removing empty folders. end RUBY end it "reports an offense when `build.universal?` is used" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' if build.universal? ^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: macOS has been 64-bit only since 10.6 so build.universal? is deprecated. "foo" end end RUBY end it "reports no offenses when `build.universal?` is used in an exempt formula" do expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/wine.rb") class Wine < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' if build.universal? "foo" end end RUBY end it "reports an offense when `ENV.universal_binary` is used" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' if build? ENV.universal_binary ^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: macOS has been 64-bit only since 10.6 so ENV.universal_binary is deprecated. end end RUBY end it "reports no offenses when `ENV.universal_binary` is used in an exempt formula" do expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/wine.rb") class Wine < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' if build? ENV.universal_binary end end RUBY end it "reports an offense when `install_name_tool` is called" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' system "install_name_tool", "-id" ^^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use ruby-macho instead of calling "install_name_tool" end RUBY end it "reports an offense when `depends_on` is called with an instance" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' depends_on FOO::BAR.new ^^^^^^^^^^^^ FormulaAudit/Miscellaneous: `depends_on` can take requirement classes instead of instances end RUBY end it "reports an offense when `Dir` is called without a globbing argument" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' rm_rf Dir["src/{llvm,test,librustdoc,etc/snapshot.pyc}"] rm_rf Dir["src/snapshot.pyc"] ^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: `Dir(["src/snapshot.pyc"])` is unnecessary; just use `src/snapshot.pyc` end RUBY end it "reports an offense when executing a system command for which there is a Ruby FileUtils equivalent" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' system "mkdir", "foo" ^^^^^^^ FormulaAudit/Miscellaneous: Use the `mkdir` Ruby method instead of `system "mkdir", "foo"` end RUBY end it "reports an offense when top-level functions are defined outside of a class body" do expect_offense(<<~RUBY) def test ^^^^^^^^ FormulaAudit/Miscellaneous: Define method `test` in the class body, not at the top-level nil end class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' end RUBY end it 'reports an offense when `man+"man8"` is used' do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' def install man1.install man+"man8" => "faad.1" ^^^^^^ FormulaAudit/Miscellaneous: `man+"man8"` should be `man8` end end RUBY end it "reports an offense when a hard-coded `gcc` is referenced" do expect_offense(<<~'RUBY') class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' def install system "/usr/bin/gcc", "foo" ^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `#{ENV.cc}` instead of hard-coding `gcc` end end RUBY end it "reports an offense when a hard-coded `g++` is referenced" do expect_offense(<<~'RUBY') class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' def install system "/usr/bin/g++", "-o", "foo", "foo.cc" ^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `#{ENV.cxx}` instead of hard-coding `g++` end end RUBY end it "reports an offense when a hard-coded `c++` is set as COMPILER_PATH" do expect_offense(<<~'RUBY') class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' def install ENV["COMPILER_PATH"] = "/usr/bin/c++" ^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `#{ENV.cxx}` instead of hard-coding `c++` end end RUBY end it "reports an offense when a hard-coded `gcc` is set as COMPILER_PATH" do expect_offense(<<~'RUBY') class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' def install ENV["COMPILER_PATH"] = "/usr/bin/gcc" ^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `#{ENV.cc}` instead of hard-coding `gcc` end end RUBY end it "reports an offense when the formula path shortcut `man` could be used" do expect_offense(<<~'RUBY') class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' def install mv "#{share}/man", share ^^^^ FormulaAudit/Miscellaneous: `#{share}/man` should be `#{man}` end end RUBY end it "reports an offense when the formula path shortcut `libexec` could be used" do expect_offense(<<~'RUBY') class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' def install mv "#{prefix}/libexec", share ^^^^^^^^ FormulaAudit/Miscellaneous: `#{prefix}/libexec` should be `#{libexec}` end end RUBY end it "reports an offense when the formula path shortcut `info` could be used" do expect_offense(<<~'RUBY') class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' def install system "./configure", "--INFODIR=#{prefix}/share/info" ^^^^^^^^^^^ FormulaAudit/Miscellaneous: `#{prefix}/share/info` should be `#{info}` end end RUBY end it "reports an offense when the formula path shortcut `man8` could be used" do expect_offense(<<~'RUBY') class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' def install system "./configure", "--MANDIR=#{prefix}/share/man/man8" ^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: `#{prefix}/share/man/man8` should be `#{man8}` end end RUBY end it "reports an offense when unvendored lua modules are used" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' depends_on "lpeg" => :lua51 ^^^^^^ FormulaAudit/Miscellaneous: lua modules should be vendored rather than using deprecated `depends_on "lpeg" => :lua51` end RUBY end it "reports an offense when `export` is used to set environment variables" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' system "export", "var=value" ^^^^^^^^ FormulaAudit/Miscellaneous: Use `ENV` instead of invoking `export` to modify the environment end RUBY end it "reports an offense when dependencies with invalid options are used" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' depends_on "foo" => "with-bar" ^^^^^^^^^^ FormulaAudit/Miscellaneous: Dependency 'foo' should not use option `with-bar` end RUBY end it "reports an offense when dependencies with invalid options are used in an array" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' depends_on "httpd" => [:build, :test] depends_on "foo" => [:optional, "with-bar"] ^^^^^^^^^^ FormulaAudit/Miscellaneous: Dependency 'foo' should not use option `with-bar` depends_on "icu4c" => [:optional, "c++11"] ^^^^^^^ FormulaAudit/Miscellaneous: Dependency 'icu4c' should not use option `c++11` end RUBY end it "reports an offense when `build.head?` could be used instead of checking `version`" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' if version == "HEAD" ^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `build.head?` instead of inspecting `version` foo() end end RUBY end it "reports an offense when `ARGV.include? (--HEAD)` is used" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' test do head = ARGV.include? "--HEAD" ^^^^ FormulaAudit/Miscellaneous: Use `build.with?` or `build.without?` instead of `ARGV` to check options ^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `if build.head?` instead end end RUBY end it "reports an offense when `needs :openmp` is used" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' needs :openmp ^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: `needs :openmp` should be replaced with `depends_on "gcc"` end RUBY end it "reports an offense when `MACOS_VERSION` is used" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' test do version = MACOS_VERSION ^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `MacOS.version` instead of `MACOS_VERSION` end end RUBY end it "reports an offense when `build.with?` is used for a conditional dependency" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' depends_on "foo" if build.with? "foo" ^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Replace `depends_on "foo" if build.with? "foo"` with `depends_on "foo" => :optional` end RUBY end it "reports an offense when `build.without?` is used for a negated conditional dependency" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' depends_on :foo unless build.without? "foo" ^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Replace `depends_on :foo unless build.without? "foo"` with `depends_on :foo => :recommended` end RUBY end it "reports an offense when `build.include?` is used for a negated conditional dependency" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' depends_on :foo unless build.include? "without-foo" ^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Replace `depends_on :foo unless build.include? "without-foo"` with `depends_on :foo => :recommended` end RUBY end end end