aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Library/.rubocop.yml9
-rw-r--r--Library/Homebrew/brew.rb6
-rw-r--r--Library/Homebrew/build_environment.rb1
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli.rb5
-rw-r--r--Library/Homebrew/caveats.rb2
-rw-r--r--Library/Homebrew/cleanup.rb1
-rw-r--r--Library/Homebrew/cmd/leaves.rb11
-rw-r--r--Library/Homebrew/constants.rb4
-rw-r--r--Library/Homebrew/dev-cmd/audit.rb168
-rw-r--r--Library/Homebrew/diagnostic.rb2
-rw-r--r--Library/Homebrew/formulary.rb2
-rw-r--r--Library/Homebrew/language/python.rb8
-rw-r--r--Library/Homebrew/readall.rb1
-rw-r--r--Library/Homebrew/rubocops/checksum_cop.rb1
-rw-r--r--Library/Homebrew/rubocops/conflicts_cop.rb6
-rw-r--r--Library/Homebrew/rubocops/extend/formula_cop.rb43
-rw-r--r--Library/Homebrew/rubocops/formula_desc_cop.rb6
-rw-r--r--Library/Homebrew/rubocops/lines_cop.rb271
-rw-r--r--Library/Homebrew/test/Gemfile.lock4
-rw-r--r--Library/Homebrew/test/rubocops/bottle_block_cop_spec.rb28
-rw-r--r--Library/Homebrew/test/rubocops/caveats_cop_spec.rb27
-rw-r--r--Library/Homebrew/test/rubocops/checksum_cop_spec.rb112
-rw-r--r--Library/Homebrew/test/rubocops/class_cop_spec.rb103
-rw-r--r--Library/Homebrew/test/rubocops/components_order_cop_spec.rb81
-rw-r--r--Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb61
-rw-r--r--Library/Homebrew/test/rubocops/conflicts_cop_spec.rb26
-rw-r--r--Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb143
-rw-r--r--Library/Homebrew/test/rubocops/homepage_cop_spec.rb3
-rw-r--r--Library/Homebrew/test/rubocops/lines_cop_spec.rb918
-rw-r--r--Library/Homebrew/test/rubocops/options_cop_spec.rb102
-rw-r--r--Library/Homebrew/test/rubocops/patches_cop_spec.rb41
-rw-r--r--Library/Homebrew/test/rubocops/text_cop_spec.rb197
-rw-r--r--Library/Homebrew/test/rubocops/urls_cop_spec.rb121
-rw-r--r--Library/Homebrew/test/spec_helper.rb8
-rw-r--r--Library/Homebrew/test/support/helper/rubocop.rb13
-rw-r--r--Library/Homebrew/test/tap_spec.rb4
-rw-r--r--Library/Homebrew/utils/github.rb2
37 files changed, 1159 insertions, 1382 deletions
diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml
index d1a3860db..00956076a 100644
--- a/Library/.rubocop.yml
+++ b/Library/.rubocop.yml
@@ -123,6 +123,15 @@ Style/Documentation:
Style/Encoding:
Enabled: true
+# use spaces for indentation; detect tabs
+Layout/Tab:
+ Enabled: true
+
+# We have no use for using `warn` because we are
+# calling Ruby with warnings disabled ourselves.
+Style/StderrPuts:
+ Enabled: false
+
# dashes in filenames are typical
Naming/FileName:
Regex: !ruby/regexp /^[\w\@\-\+\.]+(\.rb)?$/
diff --git a/Library/Homebrew/brew.rb b/Library/Homebrew/brew.rb
index 8c5386612..2cc339a83 100644
--- a/Library/Homebrew/brew.rb
+++ b/Library/Homebrew/brew.rb
@@ -78,7 +78,8 @@ begin
# - a help flag is passed AND a command is matched
# - a help flag is passed AND there is no command specified
# - no arguments are passed
- if empty_argv || help_flag
+ # - if cmd is Cask, let Cask handle the help command instead
+ if (empty_argv || help_flag) && cmd != "cask"
require "cmd/help"
Homebrew.help cmd, empty_argv: empty_argv
# `Homebrew.help` never returns, except for external/unknown commands.
@@ -116,8 +117,11 @@ begin
if Process.uid.zero? && !brew_uid.zero?
tap_commands += %W[/usr/bin/sudo -u ##{brew_uid}]
end
+ # Unset HOMEBREW_HELP to avoid confusing the tap
+ ENV.delete("HOMEBREW_HELP") if help_flag
tap_commands += %W[#{HOMEBREW_BREW_FILE} tap #{possible_tap}]
safe_system(*tap_commands)
+ ENV["HOMEBREW_HELP"] = "1" if help_flag
exec HOMEBREW_BREW_FILE, cmd, *ARGV
end
rescue UsageError => e
diff --git a/Library/Homebrew/build_environment.rb b/Library/Homebrew/build_environment.rb
index dc28b2293..3c494428f 100644
--- a/Library/Homebrew/build_environment.rb
+++ b/Library/Homebrew/build_environment.rb
@@ -46,6 +46,7 @@ module Homebrew
HOMEBREW_SDKROOT HOMEBREW_BUILD_FROM_SOURCE
MAKE GIT CPP
ACLOCAL_PATH PATH CPATH
+ LD_LIBRARY_PATH LD_RUN_PATH LD_PRELOAD LIBRARY_PATH
].select { |key| env.key?(key) }
end
diff --git a/Library/Homebrew/cask/lib/hbc/cli.rb b/Library/Homebrew/cask/lib/hbc/cli.rb
index 9283802d5..e147c8280 100644
--- a/Library/Homebrew/cask/lib/hbc/cli.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli.rb
@@ -154,7 +154,7 @@ module Hbc
def run
command_name, *args = detect_command_and_arguments(*@args)
command = if help?
- args.unshift(command_name)
+ args.unshift(command_name) unless command_name.nil?
"help"
else
self.class.lookup_command(command_name)
@@ -230,8 +230,7 @@ module Hbc
return if @command == "help" && @args.empty?
- unknown_command = @args.empty? ? @command : @args.first
- raise ArgumentError, "Unknown command: #{unknown_command}"
+ raise ArgumentError, "help does not take arguments."
end
def purpose
diff --git a/Library/Homebrew/caveats.rb b/Library/Homebrew/caveats.rb
index 485116cff..49a517bd4 100644
--- a/Library/Homebrew/caveats.rb
+++ b/Library/Homebrew/caveats.rb
@@ -1,3 +1,5 @@
+require "forwardable"
+
class Caveats
extend Forwardable
diff --git a/Library/Homebrew/cleanup.rb b/Library/Homebrew/cleanup.rb
index 340161204..960bcb8b7 100644
--- a/Library/Homebrew/cleanup.rb
+++ b/Library/Homebrew/cleanup.rb
@@ -1,6 +1,5 @@
require "utils/bottles"
require "formula"
-require "thread"
module Homebrew
module Cleanup
diff --git a/Library/Homebrew/cmd/leaves.rb b/Library/Homebrew/cmd/leaves.rb
index 574ceb64e..ecebedbb3 100644
--- a/Library/Homebrew/cmd/leaves.rb
+++ b/Library/Homebrew/cmd/leaves.rb
@@ -13,16 +13,7 @@ module Homebrew
deps_of_installed = Set.new
installed.each do |f|
- deps = []
-
- f.deps.each do |dep|
- if dep.optional? || dep.recommended?
- deps << dep.to_formula.full_name if f.build.with?(dep)
- else
- deps << dep.to_formula.full_name
- end
- end
-
+ deps = f.runtime_dependencies.map { |d| d.to_formula.full_name }
deps_of_installed.merge(deps)
end
diff --git a/Library/Homebrew/constants.rb b/Library/Homebrew/constants.rb
index 956548640..529c49feb 100644
--- a/Library/Homebrew/constants.rb
+++ b/Library/Homebrew/constants.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
# RuboCop version used for `brew style` and `brew cask style`
-HOMEBREW_RUBOCOP_VERSION = "0.50.0"
-HOMEBREW_RUBOCOP_CASK_VERSION = "~> 0.14.4" # has to be updated when RuboCop version changes
+HOMEBREW_RUBOCOP_VERSION = "0.51.0"
+HOMEBREW_RUBOCOP_CASK_VERSION = "~> 0.15.1" # has to be updated when RuboCop version changes
diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb
index ec26eb9cd..bfe4dbc00 100644
--- a/Library/Homebrew/dev-cmd/audit.rb
+++ b/Library/Homebrew/dev-cmd/audit.rb
@@ -820,168 +820,12 @@ class FormulaAuditor
problem "\"(#{Regexp.last_match(1)}...#{Regexp.last_match(2)})\" should be \"(#{Regexp.last_match(3).downcase}+...)\""
end
- if line =~ /((man)\s*\+\s*(['"])(man[1-8])(['"]))/
- problem "\"#{Regexp.last_match(1)}\" should be \"#{Regexp.last_match(4)}\""
- end
-
- # Prefer formula path shortcuts in strings
- if line =~ %r[(\#\{prefix\}/(bin|include|libexec|lib|sbin|share|Frameworks))]
- problem "\"#{Regexp.last_match(1)}\" should be \"\#{#{Regexp.last_match(2).downcase}}\""
- end
-
- if line =~ %r[((\#\{prefix\}/share/man/|\#\{man\}/)(man[1-8]))]
- problem "\"#{Regexp.last_match(1)}\" should be \"\#{#{Regexp.last_match(3)}}\""
- end
-
- if line =~ %r[((\#\{share\}/(man)))[/'"]]
- problem "\"#{Regexp.last_match(1)}\" should be \"\#{#{Regexp.last_match(3)}}\""
- end
-
- if line =~ %r[(\#\{prefix\}/share/(info|man))]
- problem "\"#{Regexp.last_match(1)}\" should be \"\#{#{Regexp.last_match(2)}}\""
- end
-
- if line =~ /depends_on\s+['"](.+)['"]\s+=>\s+:(lua|perl|python|ruby)(\d*)/
- problem "#{Regexp.last_match(2)} modules should be vendored rather than use deprecated `depends_on \"#{Regexp.last_match(1)}\" => :#{Regexp.last_match(2)}#{Regexp.last_match(3)}`"
- end
-
- if line =~ /depends_on\s+['"](.+)['"]\s+=>\s+(.*)/
- dep = Regexp.last_match(1)
- Regexp.last_match(2).split(" ").map do |o|
- break if ["if", "unless"].include?(o)
- next unless o =~ /^\[?['"](.*)['"]/
- problem "Dependency #{dep} should not use option #{Regexp.last_match(1)}"
- end
- end
-
- if line =~ /if\s+ARGV\.include\?\s+'--(HEAD|devel)'/
- problem "Use \"if build.#{Regexp.last_match(1).downcase}?\" instead"
- end
-
problem "Use separate make calls" if line.include?("make && make")
- problem "Use spaces instead of tabs for indentation" if line =~ /^[ ]*\t/
-
- if line.include?("ENV.java_cache")
- problem "In-formula ENV.java_cache usage has been deprecated & should be removed."
- end
-
- # Avoid hard-coding compilers
- if line =~ %r{(system|ENV\[.+\]\s?=)\s?['"](/usr/bin/)?(gcc|llvm-gcc|clang)['" ]}
- problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{Regexp.last_match(3)}\""
- end
-
- if line =~ %r{(system|ENV\[.+\]\s?=)\s?['"](/usr/bin/)?((g|llvm-g|clang)\+\+)['" ]}
- problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{Regexp.last_match(3)}\""
- end
-
- if line =~ /system\s+['"](env|export)(\s+|['"])/
- problem "Use ENV instead of invoking '#{Regexp.last_match(1)}' to modify the environment"
- end
-
- if line =~ /version == ['"]HEAD['"]/
- problem "Use 'build.head?' instead of inspecting 'version'"
- end
-
- if line =~ /build\.include\?[\s\(]+['"]\-\-(.*)['"]/
- problem "Reference '#{Regexp.last_match(1)}' without dashes"
- end
-
- if line =~ /build\.include\?[\s\(]+['"]with(out)?-(.*)['"]/
- problem "Use build.with#{Regexp.last_match(1)}? \"#{Regexp.last_match(2)}\" instead of build.include? 'with#{Regexp.last_match(1)}-#{Regexp.last_match(2)}'"
- end
-
- if line =~ /build\.with\?[\s\(]+['"]-?-?with-(.*)['"]/
- problem "Don't duplicate 'with': Use `build.with? \"#{Regexp.last_match(1)}\"` to check for \"--with-#{Regexp.last_match(1)}\""
- end
-
- if line =~ /build\.without\?[\s\(]+['"]-?-?without-(.*)['"]/
- problem "Don't duplicate 'without': Use `build.without? \"#{Regexp.last_match(1)}\"` to check for \"--without-#{Regexp.last_match(1)}\""
- end
-
- if line =~ /unless build\.with\?(.*)/
- problem "Use if build.without?#{Regexp.last_match(1)} instead of unless build.with?#{Regexp.last_match(1)}"
- end
-
- if line =~ /unless build\.without\?(.*)/
- problem "Use if build.with?#{Regexp.last_match(1)} instead of unless build.without?#{Regexp.last_match(1)}"
- end
-
- if line =~ /(not\s|!)\s*build\.with?\?/
- problem "Don't negate 'build.with?': use 'build.without?'"
- end
-
- if line =~ /(not\s|!)\s*build\.without?\?/
- problem "Don't negate 'build.without?': use 'build.with?'"
- end
-
- if line =~ /ARGV\.(?!(debug\?|verbose\?|value[\(\s]))/
- problem "Use build instead of ARGV to check options"
- end
-
- if line.include?("MACOS_VERSION")
- problem "Use MacOS.version instead of MACOS_VERSION"
- end
-
- if line.include?("MACOS_FULL_VERSION")
- problem "Use MacOS.full_version instead of MACOS_FULL_VERSION"
- end
-
- cats = %w[leopard snow_leopard lion mountain_lion].join("|")
- if line =~ /MacOS\.(?:#{cats})\?/
- problem "\"#{$&}\" is deprecated, use a comparison to MacOS.version instead"
- end
-
- if line =~ /depends_on [A-Z][\w:]+\.new$/
- problem "`depends_on` can take requirement classes instead of instances"
- end
-
- if line =~ /^def (\w+).*$/
- problem "Define method #{Regexp.last_match(1).inspect} in the class body, not at the top-level"
- end
-
- if line.include?("ENV.fortran") && !formula.requirements.map(&:class).include?(FortranRequirement)
- problem "Use `depends_on :fortran` instead of `ENV.fortran`"
- end
-
if line =~ /JAVA_HOME/i && !formula.requirements.map(&:class).include?(JavaRequirement)
problem "Use `depends_on :java` to set JAVA_HOME"
end
- if line =~ /depends_on :(.+) (if.+|unless.+)$/
- conditional_dep_problems(Regexp.last_match(1).to_sym, Regexp.last_match(2), $&)
- end
-
- if line =~ /depends_on ['"](.+)['"] (if.+|unless.+)$/
- conditional_dep_problems(Regexp.last_match(1), Regexp.last_match(2), $&)
- end
-
- if line =~ /(Dir\[("[^\*{},]+")\])/
- problem "#{Regexp.last_match(1)} is unnecessary; just use #{Regexp.last_match(2)}"
- end
-
- if line =~ /system (["'](#{FILEUTILS_METHODS})["' ])/o
- system = Regexp.last_match(1)
- method = Regexp.last_match(2)
- problem "Use the `#{method}` Ruby method instead of `system #{system}`"
- end
-
- if line =~ /assert [^!]+\.include?/
- problem "Use `assert_match` instead of `assert ...include?`"
- end
-
- if line =~ /(assert File\.exist\?|assert \(.*\)\.exist\?)/
- problem "Use `assert_predicate <path_to_file>, :exist?` instead of `#{Regexp.last_match(1)}`"
- end
-
- if line =~ /(assert !File\.exist\?|assert !\(.*\)\.exist\?)/
- problem "Use `refute_predicate <path_to_file>, :exist?` instead of `#{Regexp.last_match(1)}`"
- end
-
- if line =~ /(assert File\.executable\?|assert \(.*\)\.executable\?)/
- problem "Use `assert_predicate <path_to_file>, :executable?` instead of `#{Regexp.last_match(1)}`"
- end
-
return unless @strict
problem "`#{Regexp.last_match(1)}` in formulae is deprecated" if line =~ /(env :(std|userpaths))/
@@ -1028,18 +872,6 @@ class FormulaAuditor
EOS
end
- def conditional_dep_problems(dep, condition, line)
- quoted_dep = quote_dep(dep)
- dep = Regexp.escape(dep.to_s)
-
- case condition
- when /if build\.include\? ['"]with-#{dep}['"]$/, /if build\.with\? ['"]#{dep}['"]$/
- problem %Q(Replace #{line.inspect} with "depends_on #{quoted_dep} => :optional")
- when /unless build\.include\? ['"]without-#{dep}['"]$/, /unless build\.without\? ['"]#{dep}['"]$/
- problem %Q(Replace #{line.inspect} with "depends_on #{quoted_dep} => :recommended")
- end
- end
-
def quote_dep(dep)
dep.is_a?(Symbol) ? dep.inspect : "'#{dep}'"
end
diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb
index 49402bc07..51a892e28 100644
--- a/Library/Homebrew/diagnostic.rb
+++ b/Library/Homebrew/diagnostic.rb
@@ -1097,7 +1097,7 @@ module Homebrew
def all
methods.map(&:to_s).grep(/^check_/)
end
- end # end class Checks
+ end
end
end
diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb
index 7eb85ed97..1b1987717 100644
--- a/Library/Homebrew/formulary.rb
+++ b/Library/Homebrew/formulary.rb
@@ -422,7 +422,7 @@ module Formulary
CoreTap.instance.formula_dir/"#{name.to_s.downcase}.rb"
end
- def self.tap_paths(name, taps = Dir["#{HOMEBREW_LIBRARY}/Taps/*/*/"])
+ def self.tap_paths(name, taps = Dir[HOMEBREW_LIBRARY/"Taps/*/*/"])
name = name.to_s.downcase
taps.map do |tap|
Pathname.glob([
diff --git a/Library/Homebrew/language/python.rb b/Library/Homebrew/language/python.rb
index 931cc59fc..49e3d1a46 100644
--- a/Library/Homebrew/language/python.rb
+++ b/Library/Homebrew/language/python.rb
@@ -245,7 +245,7 @@ module Language
"-v", "--no-deps", "--no-binary", ":all:",
"--ignore-installed", *targets
end
- end # class Virtualenv
- end # module Virtualenv
- end # module Python
-end # module Language
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/readall.rb b/Library/Homebrew/readall.rb
index 5f4fd947c..1b6ae016e 100644
--- a/Library/Homebrew/readall.rb
+++ b/Library/Homebrew/readall.rb
@@ -1,6 +1,5 @@
require "formula"
require "tap"
-require "thread"
module Readall
class << self
diff --git a/Library/Homebrew/rubocops/checksum_cop.rb b/Library/Homebrew/rubocops/checksum_cop.rb
index dcaf60e7d..23a787809 100644
--- a/Library/Homebrew/rubocops/checksum_cop.rb
+++ b/Library/Homebrew/rubocops/checksum_cop.rb
@@ -24,6 +24,7 @@ module RuboCop
def audit_sha256(checksum)
return if checksum.nil?
if regex_match_group(checksum, /^$/)
+ @offense_source_range = @offensive_node.source_range
problem "sha256 is empty"
return
end
diff --git a/Library/Homebrew/rubocops/conflicts_cop.rb b/Library/Homebrew/rubocops/conflicts_cop.rb
index 1cca3f8ae..96edf480c 100644
--- a/Library/Homebrew/rubocops/conflicts_cop.rb
+++ b/Library/Homebrew/rubocops/conflicts_cop.rb
@@ -6,10 +6,8 @@ module RuboCop
module FormulaAudit
# This cop audits versioned Formulae for `conflicts_with`
class Conflicts < FormulaCop
- MSG = <<~EOS.freeze
- Versioned formulae should not use `conflicts_with`.
- Use `keg_only :versioned_formula` instead.
- EOS
+ MSG = "Versioned formulae should not use `conflicts_with`. " \
+ "Use `keg_only :versioned_formula` instead.".freeze
WHITELIST = %w[
node@
diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb
index 7531e62b7..2e9a7657e 100644
--- a/Library/Homebrew/rubocops/extend/formula_cop.rb
+++ b/Library/Homebrew/rubocops/extend/formula_cop.rb
@@ -56,6 +56,7 @@ module RuboCop
# Returns all string nodes among the descendants of given node
def find_strings(node)
return [] if node.nil?
+ return node if node.str_type?
node.each_descendant(:str)
end
@@ -101,7 +102,9 @@ module RuboCop
def find_method_with_args(node, method_name, *args)
methods = find_every_method_call_by_name(node, method_name)
methods.each do |method|
- yield method if parameters_passed?(method, *args)
+ next unless parameters_passed?(method, *args)
+ return true unless block_given?
+ yield method
end
end
@@ -119,6 +122,7 @@ module RuboCop
method.receiver.method_name != instance
@offense_source_range = method.source_range
@offensive_node = method
+ return true unless block_given?
yield method
end
end
@@ -167,12 +171,26 @@ module RuboCop
type_match && name_match
end
+ # Find CONSTANTs in the source
+ # if block given, yield matching nodes
+ def find_const(node, const_name)
+ return if node.nil?
+ node.each_descendant(:const) do |const_node|
+ next unless const_node.const_name == const_name
+ @offensive_node = const_node
+ @offense_source_range = const_node.source_range
+ yield const_node if block_given?
+ return true
+ end
+ nil
+ end
+
def_node_search :required_dependency?, <<~EOS
- (send nil :depends_on ({str sym} _))
+ (send nil? :depends_on ({str sym} _))
EOS
def_node_search :required_dependency_name?, <<~EOS
- (send nil :depends_on ({str sym} %1))
+ (send nil? :depends_on ({str sym} %1))
EOS
def_node_search :dependency_type_hash_match?, <<~EOS
@@ -222,15 +240,17 @@ module RuboCop
end
# Returns a method definition node with method_name
- def find_method_def(node, method_name)
+ # Returns first method def if method_name is nil
+ def find_method_def(node, method_name = nil)
return if node.nil?
node.each_child_node(:def) do |def_node|
def_method_name = method_name(def_node)
- next unless method_name == def_method_name
+ next unless method_name == def_method_name || method_name.nil?
@offensive_node = def_node
@offense_source_range = def_node.source_range
return def_node
end
+ return if node.parent.nil?
# If not found then, parent node becomes the offensive node
@offensive_node = node.parent
@offense_source_range = node.parent.source_range
@@ -250,11 +270,15 @@ module RuboCop
end
# Check if method_name is called among the direct children nodes in the given node
+ # Check if the node itself is the method
def method_called?(node, method_name)
+ if node.send_type? && node.method_name == method_name
+ offending_node(node)
+ return true
+ end
node.each_child_node(:send) do |call_node|
next unless call_node.method_name == method_name
- @offensive_node = call_node
- @offense_source_range = call_node.source_range
+ offending_node(call_node)
return true
end
false
@@ -291,6 +315,11 @@ module RuboCop
true
end
+ # Check if negation is present in the given node
+ def negated?(node)
+ method_called?(node, :!)
+ end
+
# Return all the caveats' string nodes in an array
def caveats_strings
find_strings(find_method_def(@body, :caveats))
diff --git a/Library/Homebrew/rubocops/formula_desc_cop.rb b/Library/Homebrew/rubocops/formula_desc_cop.rb
index 05f60c9d5..e56a4cc56 100644
--- a/Library/Homebrew/rubocops/formula_desc_cop.rb
+++ b/Library/Homebrew/rubocops/formula_desc_cop.rb
@@ -29,10 +29,8 @@ module RuboCop
desc_length = "#{@formula_name}: #{string_content(desc)}".length
max_desc_length = 80
return if desc_length <= max_desc_length
- problem <<~EOS
- Description is too long. "name: desc" should be less than #{max_desc_length} characters.
- Length is calculated as #{@formula_name} + desc. (currently #{desc_length})
- EOS
+ problem "Description is too long. \"name: desc\" should be less than #{max_desc_length} characters. " \
+ "Length is calculated as #{@formula_name} + desc. (currently #{desc_length})"
end
end
diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb
index 4172aad96..c5f2e7585 100644
--- a/Library/Homebrew/rubocops/lines_cop.rb
+++ b/Library/Homebrew/rubocops/lines_cop.rb
@@ -8,11 +8,11 @@ module RuboCop
def audit_formula(_node, _class_node, _parent_class_node, _body_node)
[:automake, :autoconf, :libtool].each do |dependency|
next unless depends_on?(dependency)
- problem ":#{dependency} is deprecated. Usage should be \"#{dependency}\""
+ problem ":#{dependency} is deprecated. Usage should be \"#{dependency}\"."
end
- problem ':apr is deprecated. Usage should be "apr-util"' if depends_on?(:apr)
- problem ":tex is deprecated" if depends_on?(:tex)
+ problem ':apr is deprecated. Usage should be "apr-util".' if depends_on?(:apr)
+ problem ":tex is deprecated." if depends_on?(:tex)
end
end
@@ -21,7 +21,7 @@ module RuboCop
begin_pos = start_column(parent_class_node)
end_pos = end_column(class_node)
return unless begin_pos-end_pos != 3
- problem "Use a space in class inheritance: class #{class_name(class_node)} < #{class_name(parent_class_node)}"
+ problem "Use a space in class inheritance: class #{@formula_name.capitalize} < #{class_name(parent_class_node)}"
end
end
@@ -53,6 +53,87 @@ module RuboCop
end
end
+ class AssertStatements < FormulaCop
+ def audit_formula(_node, _class_node, _parent_class_node, body_node)
+ find_every_method_call_by_name(body_node, :assert).each do |method|
+ if method_called_ever?(method, :include?) && !method_called_ever?(method, :!)
+ problem "Use `assert_match` instead of `assert ...include?`"
+ end
+
+ if method_called_ever?(method, :exist?) && !method_called_ever?(method, :!)
+ problem "Use `assert_predicate <path_to_file>, :exist?` instead of `#{method.source}`"
+ end
+
+ if method_called_ever?(method, :exist?) && method_called_ever?(method, :!)
+ problem "Use `refute_predicate <path_to_file>, :exist?` instead of `#{method.source}`"
+ end
+
+ if method_called_ever?(method, :executable?) && !method_called_ever?(method, :!)
+ problem "Use `assert_predicate <path_to_file>, :executable?` instead of `#{method.source}`"
+ end
+ end
+ end
+ end
+
+ class OptionDeclarations < FormulaCop
+ def audit_formula(_node, _class_node, _parent_class_node, body_node)
+ if find_method_def(body_node, :options)
+ problem "Use new-style option definitions"
+ end
+
+ find_instance_method_call(body_node, :build, :without?) do |method|
+ next unless unless_modifier?(method.parent)
+ correct = method.source.gsub("out?", "?")
+ problem "Use if #{correct} instead of unless #{method.source}"
+ end
+
+ find_instance_method_call(body_node, :build, :with?) do |method|
+ next unless unless_modifier?(method.parent)
+ correct = method.source.gsub("?", "out?")
+ problem "Use if #{correct} instead of unless #{method.source}"
+ end
+
+ find_instance_method_call(body_node, :build, :with?) do |method|
+ next unless negated?(method.parent)
+ problem "Don't negate 'build.with?': use 'build.without?'"
+ end
+
+ find_instance_method_call(body_node, :build, :without?) do |method|
+ next unless negated?(method.parent)
+ problem "Don't negate 'build.without?': use 'build.with?'"
+ end
+
+ find_instance_method_call(body_node, :build, :without?) do |method|
+ arg = parameters(method).first
+ next unless match = regex_match_group(arg, /-?-?without-(.*)/)
+ problem "Don't duplicate 'without': Use `build.without? \"#{match[1]}\"` to check for \"--without-#{match[1]}\""
+ end
+
+ find_instance_method_call(body_node, :build, :with?) do |method|
+ arg = parameters(method).first
+ next unless match = regex_match_group(arg, /-?-?with-(.*)/)
+ problem "Don't duplicate 'with': Use `build.with? \"#{match[1]}\"` to check for \"--with-#{match[1]}\""
+ end
+
+ find_instance_method_call(body_node, :build, :include?) do |method|
+ arg = parameters(method).first
+ next unless match = regex_match_group(arg, /with(out)?-(.*)/)
+ problem "Use build.with#{match[1]}? \"#{match[2]}\" instead of build.include? 'with#{match[1]}-#{match[2]}'"
+ end
+
+ find_instance_method_call(body_node, :build, :include?) do |method|
+ arg = parameters(method).first
+ next unless match = regex_match_group(arg, /\-\-(.*)/)
+ problem "Reference '#{match[1]}' without dashes"
+ end
+ end
+
+ def unless_modifier?(node)
+ return false unless node.if_type?
+ node.modifier_form? && node.unless?
+ end
+ end
+
class Miscellaneous < FormulaCop
def audit_formula(_node, _class_node, _parent_class_node, body_node)
# FileUtils is included in Formula
@@ -81,18 +162,128 @@ module RuboCop
end
end
+ [:debug?, :verbose?, :value].each do |method_name|
+ find_instance_method_call(body_node, "ARGV", method_name) do
+ problem "Use build instead of ARGV to check options"
+ end
+ end
+
+ find_instance_method_call(body_node, :man, :+) do |method|
+ next unless match = regex_match_group(parameters(method).first, /man[1-8]/)
+ problem "\"#{method.source}\" should be \"#{match[0]}\""
+ end
+
+ # Avoid hard-coding compilers
+ find_every_method_call_by_name(body_node, :system).each do |method|
+ param = parameters(method).first
+ if match = regex_match_group(param, %r{^(/usr/bin/)?(gcc|llvm-gcc|clang)\s?})
+ problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[2]}\""
+ elsif match = regex_match_group(param, %r{(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?})
+ problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[2]}\""
+ end
+ end
+
+ find_instance_method_call(body_node, "ENV", :[]=) do |method|
+ param = parameters(method)[1]
+ if match = regex_match_group(param, %r{^(/usr/bin/)?(gcc|llvm-gcc|clang)\s?})
+ problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[2]}\""
+ elsif match = regex_match_group(param, %r{^(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?})
+ problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[2]}\""
+ end
+ end
+
+ # Prefer formula path shortcuts in strings
+ formula_path_strings(body_node, :share) do |p|
+ next unless match = regex_match_group(p, %r{(/(man))/?})
+ problem "\"\#{share}#{match[1]}\" should be \"\#{#{match[2]}}\""
+ end
+
+ formula_path_strings(body_node, :prefix) do |p|
+ if match = regex_match_group(p, %r{(/share/(info|man))$})
+ problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2]}}\""
+ end
+ if match = regex_match_group(p, %r{((/share/man/)(man[1-8]))})
+ problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[3]}}\""
+ end
+ if match = regex_match_group(p, %r{(/(bin|include|libexec|lib|sbin|share|Frameworks))}i)
+ problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2].downcase}}\""
+ end
+ end
+
+ find_every_method_call_by_name(body_node, :depends_on).each do |method|
+ key, value = destructure_hash(parameters(method).first)
+ next if key.nil? || value.nil?
+ next unless match = regex_match_group(value, /(lua|perl|python|ruby)(\d*)/)
+ problem "#{match[1]} modules should be vendored rather than use deprecated #{method.source}`"
+ end
+
+ find_every_method_call_by_name(body_node, :system).each do |method|
+ next unless match = regex_match_group(parameters(method).first, /(env|export)(\s+)?/)
+ problem "Use ENV instead of invoking '#{match[1]}' to modify the environment"
+ end
+
+ find_every_method_call_by_name(body_node, :depends_on).each do |method|
+ next if modifier?(method.parent)
+ param = parameters(method).first
+ dep, option = hash_dep(param)
+ next if dep.nil? || option.nil?
+ offending_node(param)
+ problem "Dependency #{string_content(dep)} should not use option #{string_content(option)}"
+ end
+
+ find_instance_method_call(body_node, :version, :==) do |method|
+ next unless parameters_passed?(method, "HEAD")
+ problem "Use 'build.head?' instead of inspecting 'version'"
+ end
+
+ find_instance_method_call(body_node, "ENV", :fortran) do
+ next if depends_on?(:fortran)
+ problem "Use `depends_on :fortran` instead of `ENV.fortran`"
+ end
+
+ find_instance_method_call(body_node, "ARGV", :include?) do |method|
+ param = parameters(method).first
+ next unless match = regex_match_group(param, /--(HEAD|devel)/)
+ problem "Use \"if build.#{match[1].downcase}?\" instead"
+ end
+
+ find_const(body_node, "MACOS_VERSION") do
+ problem "Use MacOS.version instead of MACOS_VERSION"
+ end
+
+ find_const(body_node, "MACOS_FULL_VERSION") do
+ problem "Use MacOS.full_version instead of MACOS_FULL_VERSION"
+ end
+
+ conditional_dependencies(body_node) do |node, method, param, dep_node|
+ dep = string_content(dep_node)
+ if node.if?
+ if (method == :include? && regex_match_group(param, /with-#{dep}$/)) ||
+ (method == :with? && regex_match_group(param, /#{dep}$/))
+ offending_node(dep_node.parent)
+ problem "Replace #{node.source} with #{dep_node.parent.source} => :optional"
+ end
+ elsif node.unless?
+ if (method == :include? && regex_match_group(param, /without-#{dep}$/)) ||
+ (method == :without? && regex_match_group(param, /#{dep}$/))
+ offending_node(dep_node.parent)
+ problem "Replace #{node.source} with #{dep_node.parent.source} => :recommended"
+ end
+ end
+ end
+
find_method_with_args(body_node, :fails_with, :llvm) do
problem "'fails_with :llvm' is now a no-op so should be removed"
end
- find_method_with_args(body_node, :system, /^(otool|install_name_tool|lipo)$/) do
+ find_method_with_args(body_node, :system, /(otool|install_name_tool|lipo)/) do
next if @formula_name == "cctools"
problem "Use ruby-macho instead of calling #{@offensive_node.source}"
end
find_every_method_call_by_name(body_node, :system).each do |method_node|
# Skip Kibana: npm cache edge (see formula for more details)
- next if @formula_name =~ /^kibana(\@\d+(\.\d+)?)?$/
+ next if @formula_name =~ /^kibana(\@\d+(\.\d+)?)?$/i
first_param, second_param = parameters(method_node)
next if !node_equals?(first_param, "npm") ||
!node_equals?(second_param, "install")
@@ -104,15 +295,13 @@ module RuboCop
problem "Use new-style test definitions (test do)"
end
- if find_method_def(body_node, :options)
- problem "Use new-style option definitions"
+ find_method_with_args(body_node, :skip_clean, :all) do
+ problem "`skip_clean :all` is deprecated; brew no longer strips symbols. " \
+ "Pass explicit paths to prevent Homebrew from removing empty folders."
end
- find_method_with_args(body_node, :skip_clean, :all) do
- problem <<~EOS.chomp
- `skip_clean :all` is deprecated; brew no longer strips symbols
- Pass explicit paths to prevent Homebrew from removing empty folders.
- EOS
+ if find_method_def(@processed_source.ast)
+ problem "Define method #{method_name(@offensive_node)} in the class body, not at the top-level"
end
find_instance_method_call(body_node, :build, :universal?) do
@@ -128,11 +317,65 @@ module RuboCop
find_instance_method_call(body_node, "ENV", :x11) do
problem 'Use "depends_on :x11" instead of "ENV.x11"'
end
+
+ find_every_method_call_by_name(body_node, :depends_on).each do |method|
+ next unless method_called?(method, :new)
+ problem "`depends_on` can take requirement classes instead of instances"
+ end
+
+ os = [:leopard?, :snow_leopard?, :lion?, :mountain_lion?]
+ os.each do |version|
+ find_instance_method_call(body_node, "MacOS", version) do |method|
+ problem "\"#{method.source}\" is deprecated, use a comparison to MacOS.version instead"
+ end
+ end
+
+ find_instance_method_call(body_node, "Dir", :[]) do |method|
+ path = parameters(method).first
+ next unless path.str_type?
+ next unless match = regex_match_group(path, /^[^\*{},]+$/)
+ problem "Dir([\"#{string_content(path)}\"]) is unnecessary; just use \"#{match[0]}\""
+ end
+
+ fileutils_methods = Regexp.new(FileUtils.singleton_methods(false).map { |m| "(?-mix:^" + Regexp.escape(m) + "$)" }.join("|"))
+ find_every_method_call_by_name(body_node, :system).each do |method|
+ param = parameters(method).first
+ next unless match = regex_match_group(param, fileutils_methods)
+ problem "Use the `#{match}` Ruby method instead of `#{method.source}`"
+ end
+ end
+
+ def modifier?(node)
+ return false unless node.if_type?
+ node.modifier_form?
end
+ def_node_search :conditional_dependencies, <<~EOS
+ {$(if (send (send nil? :build) ${:include? :with? :without?} $(str _))
+ (send nil? :depends_on $({str sym} _)) nil?)
+
+ $(if (send (send nil? :build) ${:include? :with? :without?} $(str _)) nil?
+ (send nil? :depends_on $({str sym} _)))}
+ EOS
+
+ # Match depends_on with hash as argument
+ def_node_matcher :hash_dep, <<~EOS
+ {(hash (pair $(str _) $(str _)))
+ (hash (pair $(str _) (array $(str _) ...)))}
+ EOS
+
+ def_node_matcher :destructure_hash, <<~EOS
+ (hash (pair $(str _) $(sym _)))
+ EOS
+
+ def_node_search :formula_path_strings, <<~EOS
+ {(dstr (begin (send nil? %1)) $(str _ ))
+ (dstr _ (begin (send nil? %1)) $(str _ ))}
+ EOS
+
# Node Pattern search for Language::Node
def_node_search :languageNodeModule?, <<~EOS
- (const (const nil :Language) :Node)
+ (const (const nil? :Language) :Node)
EOS
end
end
diff --git a/Library/Homebrew/test/Gemfile.lock b/Library/Homebrew/test/Gemfile.lock
index ba12d091d..1620d7099 100644
--- a/Library/Homebrew/test/Gemfile.lock
+++ b/Library/Homebrew/test/Gemfile.lock
@@ -36,7 +36,7 @@ GEM
rspec-support (3.6.0)
rspec-wait (0.0.9)
rspec (>= 3, < 4)
- rubocop (0.50.0)
+ rubocop (0.51.0)
parallel (~> 1.10)
parser (>= 2.3.3.1, < 3.0)
powerpack (~> 0.1)
@@ -61,7 +61,7 @@ DEPENDENCIES
rspec
rspec-its
rspec-wait
- rubocop (= 0.50.0)
+ rubocop (= 0.51.0)
simplecov
BUNDLED WITH
diff --git a/Library/Homebrew/test/rubocops/bottle_block_cop_spec.rb b/Library/Homebrew/test/rubocops/bottle_block_cop_spec.rb
index 659750858..e0982dcba 100644
--- a/Library/Homebrew/test/rubocops/bottle_block_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/bottle_block_cop_spec.rb
@@ -1,6 +1,3 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/bottle_block_cop"
describe RuboCop::Cop::FormulaAuditStrict::BottleBlock do
@@ -8,34 +5,16 @@ describe RuboCop::Cop::FormulaAuditStrict::BottleBlock do
context "When auditing Bottle Block" do
it "When there is revision in bottle block" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
bottle do
cellar :any
revision 2
+ ^^^^^^^^^^ Use rebuild instead of revision in bottle block
end
end
- EOS
-
- expected_offenses = [{ message: described_class::MSG,
- severity: :convention,
- line: 5,
- column: 4,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
- end
-
- def expect_offense(expected, actual)
- expect(actual.message).to eq(expected[:message])
- expect(actual.severity).to eq(expected[:severity])
- expect(actual.line).to eq(expected[:line])
- expect(actual.column).to eq(expected[:column])
+ RUBY
end
end
@@ -50,6 +29,7 @@ describe RuboCop::Cop::FormulaAuditStrict::BottleBlock do
end
end
EOS
+
corrected_source = <<~EOS
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
diff --git a/Library/Homebrew/test/rubocops/caveats_cop_spec.rb b/Library/Homebrew/test/rubocops/caveats_cop_spec.rb
index 68f79e08a..9c92d8fb8 100644
--- a/Library/Homebrew/test/rubocops/caveats_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/caveats_cop_spec.rb
@@ -1,6 +1,3 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/caveats_cop"
describe RuboCop::Cop::FormulaAudit::Caveats do
@@ -8,34 +5,16 @@ describe RuboCop::Cop::FormulaAudit::Caveats do
context "When auditing caveats" do
it "When there is setuid mentioned in caveats" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
homepage "http://example.com/foo"
url "http://example.com/foo-1.0.tgz"
def caveats
"setuid"
+ ^^^^^^ Don\'t recommend setuid in the caveats, suggest sudo instead.
end
end
- EOS
-
- expected_offenses = [{ message: "Don't recommend setuid in the caveats, suggest sudo instead.",
- severity: :convention,
- line: 5,
- column: 5,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
- end
-
- def expect_offense(expected, actual)
- expect(actual.message).to eq(expected[:message])
- expect(actual.severity).to eq(expected[:severity])
- expect(actual.line).to eq(expected[:line])
- expect(actual.column).to eq(expected[:column])
+ RUBY
end
end
end
diff --git a/Library/Homebrew/test/rubocops/checksum_cop_spec.rb b/Library/Homebrew/test/rubocops/checksum_cop_spec.rb
index ab70f2dcf..3f720c90f 100644
--- a/Library/Homebrew/test/rubocops/checksum_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/checksum_cop_spec.rb
@@ -1,6 +1,3 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/checksum_cop"
describe RuboCop::Cop::FormulaAudit::Checksum do
@@ -8,105 +5,60 @@ describe RuboCop::Cop::FormulaAudit::Checksum do
context "When auditing spec checksums" do
it "When the checksum is empty" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
stable do
url "https://github.com/foo-lang/foo-compiler/archive/0.18.0.tar.gz"
sha256 ""
+ ^^ sha256 is empty
resource "foo-package" do
url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz"
sha256 ""
+ ^^ sha256 is empty
end
end
end
- EOS
-
- expected_offenses = [{ message: "sha256 is empty",
- severity: :convention,
- line: 5,
- column: 12,
- source: source },
- { message: "sha256 is empty",
- severity: :convention,
- line: 9,
- column: 14,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When the checksum is not 64 characters" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
stable do
url "https://github.com/foo-lang/foo-compiler/archive/0.18.0.tar.gz"
sha256 "5cf6e1ae0a645b426c0474cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9ad"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ sha256 should be 64 characters
resource "foo-package" do
url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz"
sha256 "5cf6e1ae0a645b426c047aaa4cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ sha256 should be 64 characters
end
end
end
- EOS
-
- expected_offenses = [{ message: "sha256 should be 64 characters",
- severity: :convention,
- line: 5,
- column: 12,
- source: source },
- { message: "sha256 should be 64 characters",
- severity: :convention,
- line: 9,
- column: 14,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When the checksum has invalid chars" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
stable do
url "https://github.com/foo-lang/foo-compiler/archive/0.18.0.tar.gz"
sha256 "5cf6e1ae0a645b426c0k7cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9a"
+ ^ sha256 contains invalid characters
resource "foo-package" do
url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz"
sha256 "5cf6e1ae0a645b426x047aa4cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea9"
+ ^ sha256 contains invalid characters
end
end
end
- EOS
-
- expected_offenses = [{ message: "sha256 contains invalid characters",
- severity: :convention,
- line: 5,
- column: 31,
- source: source },
- { message: "sha256 contains invalid characters",
- severity: :convention,
- line: 9,
- column: 31,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
end
end
@@ -116,46 +68,32 @@ describe RuboCop::Cop::FormulaAudit::ChecksumCase do
context "When auditing spec checksums" do
it "When the checksum has upper case characters" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
stable do
url "https://github.com/foo-lang/foo-compiler/archive/0.18.0.tar.gz"
sha256 "5cf6e1ae0A645b426c0a7cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9a"
+ ^ sha256 should be lowercase
resource "foo-package" do
url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz"
sha256 "5cf6e1Ae0a645b426b047aa4cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea9"
+ ^ sha256 should be lowercase
end
end
end
- EOS
-
- expected_offenses = [{ message: "sha256 should be lowercase",
- severity: :convention,
- line: 5,
- column: 21,
- source: source },
- { message: "sha256 should be lowercase",
- severity: :convention,
- line: 9,
- column: 20,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When auditing stable blocks outside spec blocks" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
resource "foo-outside" do
url "https://github.com/foo-lang/foo-outside/archive/0.18.0.tar.gz"
sha256 "A4cc7cd3f7d1605ffa1ac5755cf6e1ae0a645b426b047a6a39a8b2268ddc7ea9"
+ ^ sha256 should be lowercase
end
stable do
url "https://github.com/foo-lang/foo-compiler/archive/0.18.0.tar.gz"
@@ -167,19 +105,7 @@ describe RuboCop::Cop::FormulaAudit::ChecksumCase do
end
end
end
- EOS
-
- expected_offenses = [{ message: "sha256 should be lowercase",
- severity: :convention,
- line: 5,
- column: 12,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
end
diff --git a/Library/Homebrew/test/rubocops/class_cop_spec.rb b/Library/Homebrew/test/rubocops/class_cop_spec.rb
index 3f210af11..2ea58777a 100644
--- a/Library/Homebrew/test/rubocops/class_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/class_cop_spec.rb
@@ -1,81 +1,62 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/class_cop"
describe RuboCop::Cop::FormulaAudit::ClassName do
subject(:cop) { described_class.new }
- context "When auditing formula" do
- it "with deprecated inheritance" do
- formulas = [{
- "class" => "GithubGistFormula",
- }, {
- "class" => "ScriptFileFormula",
- }, {
- "class" => "AmazonWebServicesFormula",
- }]
-
- formulas.each do |formula|
- source = <<~EOS
- class Foo < #{formula["class"]}
- url 'http://example.com/foo-1.0.tgz'
- end
- EOS
+ it "reports an offense when using ScriptFileFormula" do
+ expect_offense(<<~RUBY)
+ class Foo < ScriptFileFormula
+ ^^^^^^^^^^^^^^^^^ ScriptFileFormula is deprecated, use Formula instead
+ url 'http://example.com/foo-1.0.tgz'
+ end
+ RUBY
+ end
- expected_offenses = [{ message: "#{formula["class"]} is deprecated, use Formula instead",
- severity: :convention,
- line: 1,
- column: 12,
- source: source }]
+ it "reports an offense when using GithubGistFormula" do
+ expect_offense(<<~RUBY)
+ class Foo < GithubGistFormula
+ ^^^^^^^^^^^^^^^^^ GithubGistFormula is deprecated, use Formula instead
+ url 'http://example.com/foo-1.0.tgz'
+ end
+ RUBY
+ end
- inspect_source(source)
+ it "reports an offense when using AmazonWebServicesFormula" do
+ expect_offense(<<~RUBY)
+ class Foo < AmazonWebServicesFormula
+ ^^^^^^^^^^^^^^^^^^^^^^^^ AmazonWebServicesFormula is deprecated, use Formula instead
+ url 'http://example.com/foo-1.0.tgz'
+ end
+ RUBY
+ end
- expected_offenses.zip(cop.offenses.reverse).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ it "supports auto-correcting deprecated parent classes" do
+ source = <<~EOS
+ class Foo < AmazonWebServicesFormula
+ url 'http://example.com/foo-1.0.tgz'
end
- end
+ EOS
- it "with deprecated inheritance and autocorrect" do
- source = <<~EOS
- class Foo < AmazonWebServicesFormula
- url 'http://example.com/foo-1.0.tgz'
- end
- EOS
- corrected_source = <<~EOS
- class Foo < Formula
- url 'http://example.com/foo-1.0.tgz'
- end
- EOS
+ corrected_source = <<~EOS
+ class Foo < Formula
+ url 'http://example.com/foo-1.0.tgz'
+ end
+ EOS
- new_source = autocorrect_source(source)
- expect(new_source).to eq(corrected_source)
- end
+ new_source = autocorrect_source(source)
+ expect(new_source).to eq(corrected_source)
end
end
describe RuboCop::Cop::FormulaAuditStrict::Test do
subject(:cop) { described_class.new }
- context "When auditing formula" do
- it "without a test block" do
- source = <<~EOS
- class Foo < Formula
- url 'http://example.com/foo-1.0.tgz'
- end
- EOS
- expected_offenses = [{ message: described_class::MSG,
- severity: :convention,
- line: 1,
- column: 0,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
+ it "reports an offense when there is no test block" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ ^^^^^^^^^^^^^^^^^^^ A `test do` test block should be added
+ url 'http://example.com/foo-1.0.tgz'
end
- end
+ RUBY
end
end
diff --git a/Library/Homebrew/test/rubocops/components_order_cop_spec.rb b/Library/Homebrew/test/rubocops/components_order_cop_spec.rb
index a4726c001..cd7cc5893 100644
--- a/Library/Homebrew/test/rubocops/components_order_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/components_order_cop_spec.rb
@@ -1,6 +1,3 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/components_order_cop"
describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
@@ -8,28 +5,17 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
context "When auditing formula components order" do
it "When url precedes homepage" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
homepage "http://example.com"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `homepage` (line 3) should be put before `url` (line 2)
end
- EOS
-
- expected_offenses = [{ message: "`homepage` (line 3) should be put before `url` (line 2)",
- severity: :convention,
- line: 3,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When `resource` precedes `depends_on`" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "https://example.com/foo-1.0.tgz"
@@ -38,24 +24,13 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
end
depends_on "openssl"
+ ^^^^^^^^^^^^^^^^^^^^ `depends_on` (line 8) should be put before `resource` (line 4)
end
- EOS
-
- expected_offenses = [{ message: "`depends_on` (line 8) should be put before `resource` (line 4)",
- severity: :convention,
- line: 8,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When `test` precedes `plist`" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "https://example.com/foo-1.0.tgz"
@@ -64,53 +39,24 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
end
def plist
+ ^^^^^^^^^ `plist` (line 8) should be put before `test` (line 4)
end
end
- EOS
-
- expected_offenses = [{ message: "`plist` (line 8) should be put before `test` (line 4)",
- severity: :convention,
- line: 8,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When only one of many `depends_on` precedes `conflicts_with`" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
depends_on "autoconf" => :build
conflicts_with "visionmedia-watch"
depends_on "automake" => :build
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `depends_on` (line 4) should be put before `conflicts_with` (line 3)
depends_on "libtool" => :build
depends_on "pkg-config" => :build
depends_on "gettext"
end
- EOS
-
- expected_offenses = [{ message: "`depends_on` (line 4) should be put before `conflicts_with` (line 3)",
- severity: :convention,
- line: 4,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
- end
-
- def expect_offense(expected, actual)
- expect(actual.message).to eq(expected[:message])
- expect(actual.severity).to eq(expected[:severity])
- expect(actual.line).to eq(expected[:line])
- expect(actual.column).to eq(expected[:column])
+ RUBY
end
end
@@ -122,6 +68,7 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
homepage "http://example.com"
end
EOS
+
correct_source = <<~EOS
class Foo < Formula
homepage "http://example.com"
@@ -145,6 +92,7 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
depends_on "openssl"
end
EOS
+
correct_source = <<~EOS
class Foo < Formula
url "https://example.com/foo-1.0.tgz"
@@ -156,6 +104,7 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
end
end
EOS
+
corrected_source = autocorrect_source(source)
expect(corrected_source).to eq(correct_source)
end
diff --git a/Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb b/Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb
index e899a9b07..d8878ae79 100644
--- a/Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb
@@ -1,6 +1,3 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/components_redundancy_cop"
describe RuboCop::Cop::FormulaAuditStrict::ComponentsRedundancy do
@@ -8,80 +5,40 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsRedundancy do
context "When auditing formula components common errors" do
it "When url outside stable block" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `url` should be put inside `stable` block
stable do
# stuff
end
end
- EOS
-
- expected_offenses = [{ message: "`url` should be put inside `stable` block",
- severity: :convention,
- line: 2,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When both `head` and `head do` are present" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
head "http://example.com/foo.git"
head do
+ ^^^^^^^ `head` and `head do` should not be simultaneously present
# stuff
end
end
- EOS
-
- expected_offenses = [{ message: "`head` and `head do` should not be simultaneously present",
- severity: :convention,
- line: 3,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When both `bottle :modifier` and `bottle do` are present" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
bottle do
+ ^^^^^^^^^ `bottle :modifier` and `bottle do` should not be simultaneously present
# bottles go here
end
bottle :unneeded
end
- EOS
-
- expected_offenses = [{ message: "`bottle :modifier` and `bottle do` should not be simultaneously present",
- severity: :convention,
- line: 3,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
- end
-
- def expect_offense(expected, actual)
- expect(actual.message).to eq(expected[:message])
- expect(actual.severity).to eq(expected[:severity])
- expect(actual.line).to eq(expected[:line])
- expect(actual.column).to eq(expected[:column])
+ RUBY
end
end
end
diff --git a/Library/Homebrew/test/rubocops/conflicts_cop_spec.rb b/Library/Homebrew/test/rubocops/conflicts_cop_spec.rb
index 40efe8545..5f6f020fd 100644
--- a/Library/Homebrew/test/rubocops/conflicts_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/conflicts_cop_spec.rb
@@ -1,6 +1,3 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/conflicts_cop"
describe RuboCop::Cop::FormulaAudit::Conflicts do
@@ -8,36 +5,23 @@ describe RuboCop::Cop::FormulaAudit::Conflicts do
context "When auditing formula for conflicts with" do
it "multiple conflicts_with" do
- source = <<~EOS
+ expect_offense(<<~RUBY, "/homebrew-core/Formula/foo@2.0.rb")
class FooAT20 < Formula
url 'http://example.com/foo-2.0.tgz'
conflicts_with "mysql", "mariadb", "percona-server",
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Versioned formulae should not use `conflicts_with`. Use `keg_only :versioned_formula` instead.
:because => "both install plugins"
end
- EOS
-
- expected_offenses = [{ message: described_class::MSG,
- severity: :convention,
- line: 3,
- column: 2,
- source: source }]
-
- inspect_source(source, "/homebrew-core/Formula/foo@2.0.rb")
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "no conflicts_with" do
- source = <<~EOS
+ expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/foo@2.0.rb")
class FooAT20 < Formula
url 'http://example.com/foo-2.0.tgz'
desc 'Bar'
end
- EOS
- inspect_source(source, "/homebrew-core/Formula/foo@2.0.rb")
- expect(cop.offenses).to eq([])
+ RUBY
end
end
end
diff --git a/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb b/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb
index 0f0189aa8..3ddc42d34 100644
--- a/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb
@@ -1,6 +1,3 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/formula_desc_cop"
describe RuboCop::Cop::FormulaAuditStrict::DescLength do
@@ -8,93 +5,43 @@ describe RuboCop::Cop::FormulaAuditStrict::DescLength do
context "When auditing formula desc" do
it "When there is no desc" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
+ ^^^^^^^^^^^^^^^^^^^ Formula should have a desc (Description).
url 'http://example.com/foo-1.0.tgz'
end
- EOS
-
- expected_offenses = [{ message: "Formula should have a desc (Description).",
- severity: :convention,
- line: 1,
- column: 0,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "reports an offense when desc is an empty string" do
- source = <<~EOS
+ expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
desc ''
+ ^^^^^^^ The desc (description) should not be an empty string.
end
- EOS
-
- msg = "The desc (description) should not be an empty string."
- expected_offenses = [{ message: msg,
- severity: :convention,
- line: 3,
- column: 2,
- source: source }]
-
- inspect_source(source, "/homebrew-core/Formula/foo.rb")
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When desc is too long" do
- source = <<~EOS
+ expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
desc 'Bar#{"bar" * 29}'
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Description is too long. "name: desc" should be less than 80 characters. Length is calculated as foo + desc. (currently 95)
end
- EOS
-
- msg = <<~EOS
- Description is too long. "name: desc" should be less than 80 characters.
- Length is calculated as foo + desc. (currently 95)
- EOS
- expected_offenses = [{ message: msg,
- severity: :convention,
- line: 3,
- column: 2,
- source: source }]
-
- inspect_source(source, "/homebrew-core/Formula/foo.rb")
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When desc is multiline string" do
- source = <<~EOS
+ expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
desc 'Bar#{"bar" * 9}'\
'#{"foo" * 21}'
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Description is too long. "name: desc" should be less than 80 characters. Length is calculated as foo + desc. (currently 98)
end
- EOS
-
- msg = <<~EOS
- Description is too long. "name: desc" should be less than 80 characters.
- Length is calculated as foo + desc. (currently 98)
- EOS
- expected_offenses = [{ message: msg,
- severity: :convention,
- line: 3,
- column: 2,
- source: source }]
-
- inspect_source(source, "/homebrew-core/Formula/foo.rb")
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
end
end
@@ -104,83 +51,44 @@ describe RuboCop::Cop::FormulaAuditStrict::Desc do
context "When auditing formula desc" do
it "When wrong \"command-line\" usage in desc" do
- source = <<~EOS
+ expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
desc 'command line'
+ ^ Description should start with a capital letter
+ ^^^^^^^^^^^^ Description should use \"command-line\" instead of \"command line\"
end
- EOS
-
- expected_offenses = [{ message: "Description should use \"command-line\" instead of \"command line\"",
- severity: :convention,
- line: 3,
- column: 8,
- source: source }]
-
- inspect_source(source)
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When an article is used in desc" do
- source = <<~EOS
+ expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
desc 'An '
+ ^^^ Description shouldn\'t start with an indefinite article i.e. \"An\"
end
- EOS
-
- expected_offenses = [{ message: "Description shouldn't start with an indefinite article i.e. \"An\"",
- severity: :convention,
- line: 3,
- column: 8,
- source: source }]
-
- inspect_source(source)
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When an lowercase letter starts a desc" do
- source = <<~EOS
+ expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
desc 'bar'
+ ^ Description should start with a capital letter
end
- EOS
-
- expected_offenses = [{ message: "Description should start with a capital letter",
- severity: :convention,
- line: 3,
- column: 8,
- source: source }]
-
- inspect_source(source)
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When formula name is in desc" do
- source = <<~EOS
+ expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
desc 'Foo is a foobar'
+ ^^^^ Description shouldn\'t start with the formula name
end
- EOS
-
- expected_offenses = [{ message: "Description shouldn't start with the formula name",
- severity: :convention,
- line: 3,
- column: 8,
- source: source }]
-
- inspect_source(source, "/homebrew-core/Formula/foo.rb")
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "autocorrects all rules" do
@@ -190,6 +98,7 @@ describe RuboCop::Cop::FormulaAuditStrict::Desc do
desc ' an bar: commandline foo '
end
EOS
+
correct_source = <<~EOS
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
diff --git a/Library/Homebrew/test/rubocops/homepage_cop_spec.rb b/Library/Homebrew/test/rubocops/homepage_cop_spec.rb
index be9dddae6..d394f94a1 100644
--- a/Library/Homebrew/test/rubocops/homepage_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/homepage_cop_spec.rb
@@ -1,6 +1,3 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/homepage_cop"
describe RuboCop::Cop::FormulaAudit::Homepage do
diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb
index 7e93bee75..e65eff1fc 100644
--- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb
@@ -1,260 +1,342 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/lines_cop"
describe RuboCop::Cop::FormulaAudit::Lines do
subject(:cop) { described_class.new }
- context "When auditing lines" do
- it "with correctable deprecated dependencies" do
- formulae = [{
- "dependency" => :automake,
- "correct" => "automake",
- }, {
- "dependency" => :autoconf,
- "correct" => "autoconf",
- }, {
- "dependency" => :libtool,
- "correct" => "libtool",
- }, {
- "dependency" => :apr,
- "correct" => "apr-util",
- }, {
- "dependency" => :tex,
- }]
-
- formulae.each do |formula|
- source = <<~EOS
- class Foo < Formula
- url 'http://example.com/foo-1.0.tgz'
- depends_on :#{formula["dependency"]}
- end
- EOS
- if formula.key?("correct")
- offense = ":#{formula["dependency"]} is deprecated. Usage should be \"#{formula["correct"]}\""
- else
- offense = ":#{formula["dependency"]} is deprecated"
- end
- expected_offenses = [{ message: offense,
- severity: :convention,
- line: 3,
- column: 2,
- source: source }]
+ it "reports an offense when using depends_on :automake" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ url 'http://example.com/foo-1.0.tgz'
+ depends_on :automake
+ ^^^^^^^^^^^^^^^^^^^^ :automake is deprecated. Usage should be \"automake\".
+ end
+ RUBY
+ end
- inspect_source(source)
+ it "reports an offense when using depends_on :autoconf" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ url 'http://example.com/foo-1.0.tgz'
+ depends_on :autoconf
+ ^^^^^^^^^^^^^^^^^^^^ :autoconf is deprecated. Usage should be \"autoconf\".
+ end
+ RUBY
+ end
- expected_offenses.zip(cop.offenses.reverse).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ it "reports an offense when using depends_on :libtool" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ url 'http://example.com/foo-1.0.tgz'
+ depends_on :libtool
+ ^^^^^^^^^^^^^^^^^^^ :libtool is deprecated. Usage should be \"libtool\".
end
- end
+ RUBY
+ end
+
+ it "reports an offense when using depends_on :apr" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ url 'http://example.com/foo-1.0.tgz'
+ depends_on :apr
+ ^^^^^^^^^^^^^^^ :apr is deprecated. Usage should be \"apr-util\".
+ end
+ RUBY
+ end
+
+ it "reports an offense when using depends_on :tex" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ url 'http://example.com/foo-1.0.tgz'
+ depends_on :tex
+ ^^^^^^^^^^^^^^^ :tex is deprecated.
+ end
+ RUBY
end
end
describe RuboCop::Cop::FormulaAudit::ClassInheritance do
subject(:cop) { described_class.new }
- context "When auditing lines" do
- it "with no space in class inheritance" do
- source = <<~EOS
- class Foo<Formula
- desc "foo"
- url 'http://example.com/foo-1.0.tgz'
- end
- EOS
-
- expected_offenses = [{ message: "Use a space in class inheritance: class Foo < Formula",
- severity: :convention,
- line: 1,
- column: 10,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
+ it "reports an offense when not using spaces for class inheritance" do
+ expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
+ class Foo<Formula
+ ^^^^^^^ Use a space in class inheritance: class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
end
- end
+ RUBY
end
end
describe RuboCop::Cop::FormulaAudit::Comments do
subject(:cop) { described_class.new }
- context "When auditing formulae" do
- it "with commented cmake call" do
- source = <<~EOS
+ context "When auditing formula" do
+ it "commented cmake call" do
+ expect_offense(<<~RUBY)
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
# system "cmake", ".", *std_cmake_args
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Please remove default template comments
end
- EOS
-
- expected_offenses = [{ message: "Please remove default template comments",
- severity: :convention,
- line: 4,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
- it "with default template comments" do
- source = <<~EOS
+ it "default template comments" do
+ expect_offense(<<~RUBY)
class Foo < Formula
# PLEASE REMOVE
+ ^^^^^^^^^^^^^^^ Please remove default template comments
desc "foo"
url 'http://example.com/foo-1.0.tgz'
end
- EOS
-
- expected_offenses = [{ message: "Please remove default template comments",
- severity: :convention,
- line: 2,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
- it "with commented out depends_on" do
- source = <<~EOS
+ it "commented out depends_on" do
+ expect_offense(<<~RUBY)
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
# depends_on "foo"
+ ^^^^^^^^^^^^^^^^^^ Commented-out dependency "foo"
end
- EOS
+ RUBY
+ end
+ end
+end
- expected_offenses = [{ message: 'Commented-out dependency "foo"',
- severity: :convention,
- line: 4,
- column: 2,
- source: source }]
+describe RuboCop::Cop::FormulaAudit::AssertStatements do
+ subject(:cop) { described_class.new }
- inspect_source(source)
+ it "assert ...include usage" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ assert File.read("inbox").include?("Sample message 1")
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `assert_match` instead of `assert ...include?`
+ end
+ RUBY
+ end
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
+ it "assert ...exist? without a negation" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ assert File.exist? "default.ini"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^ Use `assert_predicate <path_to_file>, :exist?` instead of `assert File.exist? "default.ini"`
end
- end
+ RUBY
+ end
+
+ it "assert ...exist? with a negation" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ assert !File.exist?("default.ini")
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `refute_predicate <path_to_file>, :exist?` instead of `assert !File.exist?("default.ini")`
+ end
+ RUBY
+ end
+
+ it "assert ...executable? without a negation" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ assert File.executable? f
+ ^^^^^^^^^^^^^^^^^^ Use `assert_predicate <path_to_file>, :executable?` instead of `assert File.executable? f`
+ end
+ RUBY
+ end
+end
+
+describe RuboCop::Cop::FormulaAudit::OptionDeclarations do
+ subject(:cop) { described_class.new }
+
+ it "unless build.without? conditional" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ def post_install
+ return unless build.without? "bar"
+ ^^^^^^^^^^^^^^^^^^^^ Use if build.with? "bar" instead of unless build.without? "bar"
+ end
+ end
+ RUBY
+ end
+
+ it "unless build.with? conditional" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ def post_install
+ return unless build.with? "bar"
+ ^^^^^^^^^^^^^^^^^ Use if build.without? "bar" instead of unless build.with? "bar"
+ end
+ end
+ RUBY
+ end
+
+ it "negated build.with? conditional" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ def post_install
+ return if !build.with? "bar"
+ ^^^^^^^^^^^^^^^^^^ Don't negate 'build.with?': use 'build.without?'
+ end
+ end
+ RUBY
+ end
+
+ it "negated build.without? conditional" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ def post_install
+ return if !build.without? "bar"
+ ^^^^^^^^^^^^^^^^^^^^^ Don't negate 'build.without?': use 'build.with?'
+ end
+ end
+ RUBY
+ end
+
+ it "unnecessary build.without? conditional" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ def post_install
+ return if build.without? "--without-bar"
+ ^^^^^^^^^^^^^ Don't duplicate 'without': Use `build.without? \"bar\"` to check for \"--without-bar\"
+ end
+ end
+ RUBY
+ end
+
+ it "unnecessary build.with? conditional" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ def post_install
+ return if build.with? "--with-bar"
+ ^^^^^^^^^^ Don't duplicate 'with': Use `build.with? \"bar\"` to check for \"--with-bar\"
+ end
+ end
+ RUBY
+ end
+
+ it "build.include? conditional" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ def post_install
+ return if build.include? "without-bar"
+ ^^^^^^^^^^^ Use build.without? \"bar\" instead of build.include? 'without-bar'
+ end
+ end
+ RUBY
+ end
+
+ it "build.include? with dashed args conditional" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ def post_install
+ return if build.include? "--bar"
+ ^^^^^ Reference 'bar' without dashes
+ end
+ end
+ RUBY
+ end
+
+ it "def options usage" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+
+ def options
+ ^^^^^^^^^^^ Use new-style option definitions
+ [["--bar", "desc"]]
+ end
+ end
+ RUBY
end
end
describe RuboCop::Cop::FormulaAudit::Miscellaneous do
subject(:cop) { described_class.new }
- context "When auditing formulae" do
- it "with FileUtils" do
- source = <<~EOS
+ context "When auditing formula" do
+ it "FileUtils usage" do
+ expect_offense(<<~RUBY)
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
FileUtils.mv "hello"
+ ^^^^^^^^^^^^^^^^^^^^ Don\'t need \'FileUtils.\' before mv
end
- EOS
-
- expected_offenses = [{ message: "Don't need 'FileUtils.' before mv",
- severity: :convention,
- line: 4,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
- it "with long inreplace block vars" do
- source = <<~EOS
+ it "long inreplace block vars" do
+ expect_offense(<<~RUBY)
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
inreplace "foo" do |longvar|
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \"inreplace <filenames> do |s|\" is preferred over \"|longvar|\".
somerandomCall(longvar)
end
end
- EOS
-
- expected_offenses = [{ message: "\"inreplace <filenames> do |s|\" is preferred over \"|longvar|\".",
- severity: :convention,
- line: 4,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
- it "with invalid rebuild" do
- source = <<~EOS
+ it "an invalid rebuild statement" do
+ expect_offense(<<~RUBY)
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
bottle do
rebuild 0
+ ^^^^^^^^^ 'rebuild 0' should be removed
sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra
end
end
- EOS
-
- expected_offenses = [{ message: "'rebuild 0' should be removed",
- severity: :convention,
- line: 5,
- column: 4,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
- it "with OS.linux? check" do
- source = <<~EOS
+ it "OS.linux? check" do
+ expect_offense(<<~RUBY, "/homebrew-core/")
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
bottle do
if OS.linux?
+ ^^^^^^^^^ Don\'t use OS.linux?; Homebrew/core only supports macOS
nil
end
sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra
end
end
- EOS
-
- expected_offenses = [{ message: "Don't use OS.linux?; Homebrew/core only supports macOS",
- severity: :convention,
- line: 5,
- column: 7,
- source: source }]
-
- inspect_source(source, "/homebrew-core/")
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
- it "with fails_with :llvm" do
- source = <<~EOS
+ it "fails_with :llvm block" do
+ expect_offense(<<~RUBY)
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
@@ -262,270 +344,450 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra
end
fails_with :llvm do
+ ^^^^^^^^^^^^^^^^ 'fails_with :llvm' is now a no-op so should be removed
build 2335
cause "foo"
end
end
- EOS
-
- expected_offenses = [{ message: "'fails_with :llvm' is now a no-op so should be removed",
- severity: :convention,
- line: 7,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
- it "with def test" do
- source = <<~EOS
+ it "def test's deprecated usage" do
+ expect_offense(<<~RUBY)
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
def test
+ ^^^^^^^^ Use new-style test definitions (test do)
assert_equals "1", "1"
end
end
- EOS
+ RUBY
+ end
- expected_offenses = [{ message: "Use new-style test definitions (test do)",
- severity: :convention,
- line: 5,
- column: 2,
- source: source }]
+ it "with deprecated skip_clean call" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ skip_clean :all
+ ^^^^^^^^^^^^^^^ `skip_clean :all` is deprecated; brew no longer strips symbols. Pass explicit paths to prevent Homebrew from removing empty folders.
+ end
+ RUBY
+ end
- inspect_source(source)
+ it "build.universal? deprecated usage" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ if build.universal?
+ ^^^^^^^^^^^^^^^^ macOS has been 64-bit only since 10.6 so build.universal? is deprecated.
+ "foo"
+ end
+ end
+ RUBY
+ end
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ it "build.universal? deprecation exempted formula" do
+ expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/wine.rb")
+ class Wine < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ if build.universal?
+ "foo"
+ end
+ end
+ RUBY
end
- it "with def options" do
- source = <<~EOS
+ it "deprecated ENV.universal_binary usage" do
+ expect_offense(<<~RUBY)
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
+ if build?
+ ENV.universal_binary
+ ^^^^^^^^^^^^^^^^^^^^ macOS has been 64-bit only since 10.6 so ENV.universal_binary is deprecated.
+ end
+ end
+ RUBY
+ end
- def options
- [["--bar", "desc"]]
+ it "ENV.universal_binary deprecation exempted formula" do
+ expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/wine.rb")
+ class Wine < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ if build?
+ ENV.universal_binary
end
end
- EOS
+ RUBY
+ end
- expected_offenses = [{ message: "Use new-style option definitions",
- severity: :convention,
- line: 5,
- column: 2,
- source: source }]
+ it "deprecated ENV.x11 usage" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ if build?
+ ENV.x11
+ ^^^^^^^ Use "depends_on :x11" instead of "ENV.x11"
+ end
+ end
+ RUBY
+ end
- inspect_source(source)
+ it "install_name_tool usage instead of ruby-macho" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ system "install_name_tool", "-id"
+ ^^^^^^^^^^^^^^^^^ Use ruby-macho instead of calling "install_name_tool"
+ end
+ RUBY
+ end
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ it "ruby-macho alternatives audit exempted formula" do
+ expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/cctools.rb")
+ class Cctools < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ system "install_name_tool", "-id"
+ end
+ RUBY
end
- it "with deprecated skip_clean call" do
- source = <<~EOS
+ it "npm install without language::Node args" do
+ expect_offense(<<~RUBY)
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
- skip_clean :all
+ system "npm", "install"
+ ^^^^^^^^^^^^^^^^^^^^^^^ Use Language::Node for npm install args
end
- EOS
-
- expected_offenses = [{ message: <<~EOS.chomp,
- `skip_clean :all` is deprecated; brew no longer strips symbols
- Pass explicit paths to prevent Homebrew from removing empty folders.
- EOS
- severity: :convention,
- line: 4,
- column: 2,
- source: source }]
+ RUBY
+ end
- inspect_source(source)
+ it "npm install without language::Node args in kibana(exempted formula)" do
+ expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/kibana@4.4.rb")
+ class KibanaAT44 < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ system "npm", "install"
+ end
+ RUBY
+ end
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ it "depends_on with an instance as argument" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ depends_on FOO::BAR.new
+ ^^^^^^^^^^^^ `depends_on` can take requirement classes instead of instances
+ end
+ RUBY
end
- it "with build.universal?" do
- source = <<~EOS
+ it "old style OS check" do
+ expect_offense(<<~RUBY)
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
- if build.universal?
- "foo"
- end
+ depends_on :foo if MacOS.snow_leopard?
+ ^^^^^^^^^^^^^^^^^^^ \"MacOS.snow_leopard?\" is deprecated, use a comparison to MacOS.version instead
end
- EOS
+ RUBY
+ end
- expected_offenses = [{ message: "macOS has been 64-bit only since 10.6 so build.universal? is deprecated.",
- severity: :convention,
- line: 4,
- column: 5,
- source: source }]
+ it "non glob DIR usage" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ rm_rf Dir["src/{llvm,test,librustdoc,etc/snapshot.pyc}"]
+ rm_rf Dir["src/snapshot.pyc"]
+ ^^^^^^^^^^^^^^^^ Dir(["src/snapshot.pyc"]) is unnecessary; just use "src/snapshot.pyc"
+ end
+ RUBY
+ end
- inspect_source(source)
+ it "system call to fileUtils Method" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ system "mkdir", "foo"
+ ^^^^^ Use the `mkdir` Ruby method instead of `system "mkdir", "foo"`
+ end
+ RUBY
+ end
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ it "top-level function def outside class body" do
+ expect_offense(<<~RUBY)
+ def test
+ ^^^^^^^^ Define method test in the class body, not at the top-level
+ nil
+ end
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ end
+ RUBY
end
- it "with a build.universal? exemption reports no offenses" do
- source = <<~EOS
- class Wine < Formula
+ it "Using ARGV to check options" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
- if build.universal?
- "foo"
+ def install
+ verbose = ARGV.verbose?
+ ^^^^^^^^^^^^^ Use build instead of ARGV to check options
end
end
- EOS
-
- inspect_source(source, "/homebrew-core/Formula/wine.rb")
- expect(cop.offenses).to be_empty
+ RUBY
end
- it "with ENV.universal_binary" do
- source = <<~EOS
+ it 'man+"man8" usage' do
+ expect_offense(<<~RUBY)
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
- if build?
- ENV.universal_binary
+ def install
+ man1.install man+"man8" => "faad.1"
+ ^^^^ "man+"man8"" should be "man8"
end
end
- EOS
-
- expected_offenses = [{ message: "macOS has been 64-bit only since 10.6 so ENV.universal_binary is deprecated.",
- severity: :convention,
- line: 5,
- column: 5,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
- it "with an ENV.universal_binary exemption reports no offenses" do
- source = <<~EOS
- class Wine < Formula
+ it "hardcoded gcc compiler" do
+ expect_offense(<<~'RUBY')
+ class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
- if build?
- ENV.universal_binary
+ def install
+ system "/usr/bin/gcc", "foo"
+ ^^^^^^^^^^^^ Use "#{ENV.cc}" instead of hard-coding "gcc"
end
end
- EOS
+ RUBY
+ end
- inspect_source(source, "/homebrew-core/Formula/wine.rb")
- expect(cop.offenses).to be_empty
+ it "hardcoded g++ compiler" do
+ expect_offense(<<~'RUBY')
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ def install
+ system "/usr/bin/g++", "-o", "foo", "foo.cc"
+ ^^^^^^^^^^^^ Use "#{ENV.cxx}" instead of hard-coding "g++"
+ end
+ end
+ RUBY
end
- it "with ENV.x11" do
- source = <<~EOS
+ it "hardcoded llvm-g++ compiler" do
+ expect_offense(<<~'RUBY')
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
- if build?
- ENV.x11
+ def install
+ ENV["COMPILER_PATH"] = "/usr/bin/llvm-g++"
+ ^^^^^^^^^^^^^^^^^ Use "#{ENV.cxx}" instead of hard-coding "llvm-g++"
end
end
- EOS
+ RUBY
+ end
- expected_offenses = [{ message: 'Use "depends_on :x11" instead of "ENV.x11"',
- severity: :convention,
- line: 5,
- column: 5,
- source: source }]
+ it "hardcoded gcc compiler" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ def install
+ ENV["COMPILER_PATH"] = "/usr/bin/gcc"
+ ^^^^^^^^^^^^ Use \"\#{ENV.cc}\" instead of hard-coding \"gcc\"
+ end
+ end
+ RUBY
+ end
- inspect_source(source)
+ it "formula path shortcut : man" do
+ expect_offense(<<~'RUBY')
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ def install
+ mv "#{share}/man", share
+ ^^^^ "#{share}/man" should be "#{man}"
+ end
+ end
+ RUBY
+ end
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ it "formula path shortcut : libexec" do
+ expect_offense(<<~'RUBY')
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ def install
+ mv "#{prefix}/libexec", share
+ ^^^^^^^^ "#{prefix}/libexec" should be "#{libexec}"
+ end
+ end
+ RUBY
end
- it "with ruby-macho alternatives" do
- source = <<~EOS
+ it "formula path shortcut : info" do
+ expect_offense(<<~'RUBY')
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
- system "install_name_tool", "-id"
+ def install
+ system "./configure", "--INFODIR=#{prefix}/share/info"
+ ^^^^^^ "#{prefix}/share" should be "#{share}"
+ ^^^^^^^^^^^ "#{prefix}/share/info" should be "#{info}"
+ end
end
- EOS
+ RUBY
+ end
- expected_offenses = [{ message: 'Use ruby-macho instead of calling "install_name_tool"',
- severity: :convention,
- line: 4,
- column: 10,
- source: source }]
+ it "formula path shortcut : man8" do
+ expect_offense(<<~'RUBY')
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ def install
+ system "./configure", "--MANDIR=#{prefix}/share/man/man8"
+ ^^^^^^ "#{prefix}/share" should be "#{share}"
+ ^^^^^^^^^^^^^^^ "#{prefix}/share/man/man8" should be "#{man8}"
+ end
+ end
+ RUBY
+ end
- inspect_source(source)
+ it "dependecies which have to vendored" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ depends_on "lpeg" => :lua51
+ ^^^^^ lua modules should be vendored rather than use deprecated depends_on \"lpeg\" => :lua51`
+ end
+ RUBY
+ end
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ it "manually setting env" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ system "export", "var=value"
+ ^^^^^^ Use ENV instead of invoking 'export' to modify the environment
+ end
+ RUBY
end
- it "with ruby-macho alternatives audit exempted formula" do
- source = <<~EOS
- class Cctools < Formula
+ it "dependencies with invalid options" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
- system "install_name_tool", "-id"
+ depends_on "foo" => "with-bar"
+ ^^^^^^^^^^^^^^^^^^^ Dependency foo should not use option with-bar
end
- EOS
+ RUBY
+ end
- inspect_source(source, "/homebrew-core/Formula/cctools.rb")
- expect(cop.offenses).to eq([])
+ it "inspecting version manually" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ if version == "HEAD"
+ ^^^^^^^^^^^^^^^^^ Use 'build.head?' instead of inspecting 'version'
+ foo()
+ end
+ end
+ RUBY
end
- it "with npm install without language::Node args" do
- source = <<~EOS
+ it "deprecated ENV.fortran usage" do
+ expect_offense(<<~RUBY)
class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
- system "npm", "install"
+ test do
+ ENV.fortran
+ ^^^^^^^^^^^ Use `depends_on :fortran` instead of `ENV.fortran`
+ end
end
- EOS
+ RUBY
+ end
- expected_offenses = [{ message: "Use Language::Node for npm install args",
- severity: :convention,
- line: 4,
- column: 2,
- source: source }]
+ it "deprecated ARGV.include? (--HEAD) usage" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ test do
+ head = ARGV.include? "--HEAD"
+ ^^^^^^ Use "if build.head?" instead
+ end
+ end
+ RUBY
+ end
- inspect_source(source)
+ it "deprecated MACOS_VERSION const usage" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ test do
+ version = MACOS_VERSION
+ ^^^^^^^^^^^^^ Use MacOS.version instead of MACOS_VERSION
+ end
+ end
+ RUBY
+ end
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ it "deprecated if build.with? conditional dependency" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ depends_on "foo" if build.with? "with-foo"
+ ^^^^^^^^^^^^^^^^ Replace depends_on "foo" if build.with? "with-foo" with depends_on "foo" => :optional
+ end
+ RUBY
end
- it "with npm install without language::Node args in kibana" do
- source = <<~EOS
- class KibanaAT44 < Formula
+ it "unless conditional dependency with build.without?" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
desc "foo"
url 'http://example.com/foo-1.0.tgz'
- system "npm", "install"
+ depends_on :foo unless build.without? "foo"
+ ^^^^^^^^^^^^^^^ Replace depends_on :foo unless build.without? "foo" with depends_on :foo => :recommended
end
- EOS
+ RUBY
+ end
- inspect_source(source, "/homebrew-core/Formula/kibana@4.4.rb")
- expect(cop.offenses).to eq([])
+ it "unless conditional dependency with build.include?" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ depends_on :foo unless build.include? "without-foo"
+ ^^^^^^^^^^^^^^^ Replace depends_on :foo unless build.include? "without-foo" with depends_on :foo => :recommended
+ end
+ RUBY
end
end
end
diff --git a/Library/Homebrew/test/rubocops/options_cop_spec.rb b/Library/Homebrew/test/rubocops/options_cop_spec.rb
index 1ed6ee740..b888f4315 100644
--- a/Library/Homebrew/test/rubocops/options_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/options_cop_spec.rb
@@ -1,32 +1,16 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/options_cop"
describe RuboCop::Cop::FormulaAudit::Options do
subject(:cop) { described_class.new }
- context "When auditing options" do
- it "32-bit" do
- source = <<~EOS
- class Foo < Formula
- url 'http://example.com/foo-1.0.tgz'
- option "32-bit", "with 32-bit"
- end
- EOS
-
- expected_offenses = [{ message: described_class::DEPRECATION_MSG,
- severity: :convention,
- line: 3,
- column: 10,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
+ it "reports an offense when using the 32-bit option" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ url 'http://example.com/foo-1.0.tgz'
+ option "32-bit", "with 32-bit"
+ ^^^^^^ macOS has been 64-bit only since 10.6 so 32-bit options are deprecated.
end
- end
+ RUBY
end
end
@@ -35,71 +19,34 @@ describe RuboCop::Cop::FormulaAuditStrict::Options do
context "When auditing options strictly" do
it "with universal" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
option :universal
+ ^^^^^^^^^^^^^^^^^ macOS has been 64-bit only since 10.6 so universal options are deprecated.
end
- EOS
-
- expected_offenses = [{ message: described_class::DEPRECATION_MSG,
- severity: :convention,
- line: 3,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "with deprecated options" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
option :cxx11
option "examples", "with-examples"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Options should begin with with/without. Migrate '--examples' with `deprecated_option`.
end
- EOS
-
- MSG_1 = "Options should begin with with/without."\
- " Migrate '--examples' with `deprecated_option`.".freeze
- expected_offenses = [{ message: MSG_1,
- severity: :convention,
- line: 4,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "with misc deprecated options" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
option "without-check"
+ ^^^^^^^^^^^^^^^^^^^^^^ Use '--without-test' instead of '--without-check'. Migrate '--without-check' with `deprecated_option`.
end
- EOS
-
- MSG_2 = "Use '--without-test' instead of '--without-check'."\
- " Migrate '--without-check' with `deprecated_option`.".freeze
- expected_offenses = [{ message: MSG_2,
- severity: :convention,
- line: 3,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
end
end
@@ -109,24 +56,13 @@ describe RuboCop::Cop::NewFormulaAudit::Options do
context "When auditing options for a new formula" do
it "with deprecated options" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
deprecated_option "examples" => "with-examples"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ New Formula should not use `deprecated_option`
end
- EOS
-
- expected_offenses = [{ message: described_class::MSG,
- severity: :convention,
- line: 3,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
end
end
diff --git a/Library/Homebrew/test/rubocops/patches_cop_spec.rb b/Library/Homebrew/test/rubocops/patches_cop_spec.rb
index fdecb676e..771171160 100644
--- a/Library/Homebrew/test/rubocops/patches_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/patches_cop_spec.rb
@@ -1,6 +1,3 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/patches_cop"
describe RuboCop::Cop::FormulaAudit::Patches do
@@ -8,37 +5,24 @@ describe RuboCop::Cop::FormulaAudit::Patches do
context "When auditing legacy patches" do
it "When there is no legacy patch" do
- source = <<~EOS
+ expect_no_offenses(<<~RUBY)
class Foo < Formula
url 'http://example.com/foo-1.0.tgz'
end
- EOS
- inspect_source(source)
- expect(cop.offenses).to eq([])
+ RUBY
end
it "Formula with `def patches`" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
homepage "ftp://example.com/foo"
url "http://example.com/foo-1.0.tgz"
def patches
+ ^^^^^^^^^^^ Use the patch DSL instead of defining a 'patches' method
DATA
end
end
- EOS
-
- expected_offenses = [{ message: "Use the patch DSL instead of defining a 'patches' method",
- severity: :convention,
- line: 4,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "Patch URLs" do
@@ -120,7 +104,10 @@ describe RuboCop::Cop::FormulaAudit::Patches do
source: source }]
end
expected_offense.zip([cop.offenses.last]).each do |expected, actual|
- expect_offense(expected, actual)
+ expect(actual.message).to eq(expected[:message])
+ expect(actual.severity).to eq(expected[:severity])
+ expect(actual.line).to eq(expected[:line])
+ expect(actual.column).to eq(expected[:column])
end
end
end
@@ -157,7 +144,10 @@ describe RuboCop::Cop::FormulaAudit::Patches do
inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
+ expect(actual.message).to eq(expected[:message])
+ expect(actual.severity).to eq(expected[:severity])
+ expect(actual.line).to eq(expected[:line])
+ expect(actual.column).to eq(expected[:column])
end
end
end
@@ -233,7 +223,10 @@ describe RuboCop::Cop::FormulaAudit::Patches do
source: source }]
end
expected_offense.zip([cop.offenses.last]).each do |expected, actual|
- expect_offense(expected, actual)
+ expect(actual.message).to eq(expected[:message])
+ expect(actual.severity).to eq(expected[:severity])
+ expect(actual.line).to eq(expected[:line])
+ expect(actual.column).to eq(expected[:column])
end
end
end
diff --git a/Library/Homebrew/test/rubocops/text_cop_spec.rb b/Library/Homebrew/test/rubocops/text_cop_spec.rb
index dbddff1ad..84e2344c5 100644
--- a/Library/Homebrew/test/rubocops/text_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/text_cop_spec.rb
@@ -1,6 +1,3 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/text_cop"
describe RuboCop::Cop::FormulaAudit::Text do
@@ -8,189 +5,114 @@ describe RuboCop::Cop::FormulaAudit::Text do
context "When auditing formula text" do
it "with both openssl and libressl optional dependencies" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
homepage "http://example.com"
depends_on "openssl"
depends_on "libressl" => :optional
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Formulae should not depend on both OpenSSL and LibreSSL (even optionally).
end
- EOS
-
- expected_offenses = [{ message: "Formulae should not depend on both OpenSSL and LibreSSL (even optionally).",
- severity: :convention,
- line: 6,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "with both openssl and libressl dependencies" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
homepage "http://example.com"
depends_on "openssl"
depends_on "libressl"
+ ^^^^^^^^^^^^^^^^^^^^^ Formulae should not depend on both OpenSSL and LibreSSL (even optionally).
end
- EOS
-
- expected_offenses = [{ message: "Formulae should not depend on both OpenSSL and LibreSSL (even optionally).",
- severity: :convention,
- line: 6,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When xcodebuild is called without SYMROOT" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
homepage "http://example.com"
def install
xcodebuild "-project", "meow.xcodeproject"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ xcodebuild should be passed an explicit \"SYMROOT\"
end
end
- EOS
-
- expected_offenses = [{ message: "xcodebuild should be passed an explicit \"SYMROOT\"",
- severity: :convention,
- line: 6,
- column: 4,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When xcodebuild is called without any args" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
homepage "http://example.com"
def install
xcodebuild
+ ^^^^^^^^^^ xcodebuild should be passed an explicit \"SYMROOT\"
end
end
- EOS
-
- expected_offenses = [{ message: "xcodebuild should be passed an explicit \"SYMROOT\"",
- severity: :convention,
- line: 6,
- column: 4,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When go get is executed" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
homepage "http://example.com"
def install
system "go", "get", "bar"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^ Formulae should not use `go get`. If non-vendored resources are required use `go_resource`s.
end
end
- EOS
-
- expected_offenses = [{ message: "Formulae should not use `go get`. If non-vendored resources are required use `go_resource`s.",
- severity: :convention,
- line: 6,
- column: 4,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When xcodebuild is executed" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
homepage "http://example.com"
def install
system "xcodebuild", "foo", "bar"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use \"xcodebuild *args\" instead of \"system 'xcodebuild', *args\"
end
end
- EOS
-
- expected_offenses = [{ message: "use \"xcodebuild *args\" instead of \"system 'xcodebuild', *args\"",
- severity: :convention,
- line: 6,
- column: 4,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When scons is executed" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
homepage "http://example.com"
def install
system "scons", "foo", "bar"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use \"scons *args\" instead of \"system 'scons', *args\"
end
end
- EOS
-
- expected_offenses = [{ message: "use \"scons *args\" instead of \"system 'scons', *args\"",
- severity: :convention,
- line: 6,
- column: 4,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When plist_options are not defined when using a formula-defined plist", :ruby23 do
- source = <<~RUBY
+ expect_offense(<<~RUBY)
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
homepage "http://example.com"
def install
system "xcodebuild", "foo", "bar"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use \"xcodebuild *args\" instead of \"system 'xcodebuild', *args\"
end
def plist
+ ^^^^^^^^^ Please set plist_options when using a formula-defined plist.
<<~XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -204,23 +126,12 @@ describe RuboCop::Cop::FormulaAudit::Text do
end
end
RUBY
-
- expected_offenses = [{ message: "Please set plist_options when using a formula-defined plist.",
- severity: :convention,
- line: 9,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
end
it "When language/go is require'd" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
require "language/go"
+ ^^^^^^^^^^^^^^^^^^^^^ require "language/go" is unnecessary unless using `go_resource`s
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
@@ -228,30 +139,20 @@ describe RuboCop::Cop::FormulaAudit::Text do
def install
system "go", "get", "bar"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^ Formulae should not use `go get`. If non-vendored resources are required use `go_resource`s.
end
end
- EOS
-
- expected_offenses = [{ message: "require \"language/go\" is unnecessary unless using `go_resource`s",
- severity: :convention,
- line: 1,
- column: 0,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When formula uses virtualenv and also `setuptools` resource" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
homepage "http://example.com"
resource "setuptools" do
+ ^^^^^^^^^^^^^^^^^^^^^ Formulae using virtualenvs do not need a `setuptools` resource.
url "https://foo.com/foo.tar.gz"
sha256 "db0904a28253cfe53e7dedc765c71596f3c53bb8a866ae50123320ec1a7b73fd"
end
@@ -260,51 +161,21 @@ describe RuboCop::Cop::FormulaAudit::Text do
virtualenv_create(libexec)
end
end
- EOS
-
- expected_offenses = [{ message: "Formulae using virtualenvs do not need a `setuptools` resource.",
- severity: :convention,
- line: 5,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
it "When Formula.factory(name) is used" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
homepage "http://example.com"
def install
Formula.factory(name)
+ ^^^^^^^^^^^^^^^^^^^^^ \"Formula.factory(name)\" is deprecated in favor of \"Formula[name]\"
end
end
- EOS
-
- expected_offenses = [{ message: "\"Formula.factory(name)\" is deprecated in favor of \"Formula[name]\"",
- severity: :convention,
- line: 6,
- column: 4,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses).each do |expected, actual|
- expect_offense(expected, actual)
- end
- end
-
- def expect_offense(expected, actual)
- expect(actual.message).to eq(expected[:message])
- expect(actual.severity).to eq(expected[:severity])
- expect(actual.line).to eq(expected[:line])
- expect(actual.column).to eq(expected[:column])
+ RUBY
end
end
end
diff --git a/Library/Homebrew/test/rubocops/urls_cop_spec.rb b/Library/Homebrew/test/rubocops/urls_cop_spec.rb
index 0bda7f110..494028bd5 100644
--- a/Library/Homebrew/test/rubocops/urls_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/urls_cop_spec.rb
@@ -1,6 +1,3 @@
-require "rubocop"
-require "rubocop/rspec/support"
-require_relative "../../extend/string"
require_relative "../../rubocops/urls_cop"
describe RuboCop::Cop::FormulaAudit::Urls do
@@ -129,65 +126,40 @@ describe RuboCop::Cop::FormulaAudit::Urls do
inspect_source(source)
expected_offenses.zip(cop.offenses.reverse).each do |expected, actual|
- expect_offense(expected, actual)
+ expect(actual.message).to eq(expected[:message])
+ expect(actual.severity).to eq(expected[:severity])
+ expect(actual.line).to eq(expected[:line])
+ expect(actual.column).to eq(expected[:column])
end
end
end
it "with offenses in stable/devel/head block" do
- formulas = [{
- "url" => "git://github.com/foo.git",
- "msg" => "Please use https:// for git://github.com/foo.git",
- "col" => 4,
- }]
- formulas.each do |formula|
- source = <<~EOS
- class Foo < Formula
- desc "foo"
- url "https://foo.com"
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url "https://foo.com"
- devel do
- url "#{formula["url"]}",
- :tag => "v1.0.0-alpha.1",
- :revision => "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- version "1.0.0-alpha.1"
- end
+ devel do
+ url "git://github.com/foo.git",
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Please use https:// for git://github.com/foo.git
+ :tag => "v1.0.0-alpha.1",
+ :revision => "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ version "1.0.0-alpha.1"
end
- EOS
- expected_offenses = [{ message: formula["msg"],
- severity: :convention,
- line: 6,
- column: formula["col"],
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses.reverse).each do |expected, actual|
- expect_offense(expected, actual)
end
- end
+ RUBY
end
it "with duplicate mirror" do
- source = <<~EOS
+ expect_offense(<<~RUBY)
class Foo < Formula
desc "foo"
url "https://ftpmirror.fnu.org/foo/foo-1.0.tar.gz"
mirror "https://ftpmirror.fnu.org/foo/foo-1.0.tar.gz"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ URL should not be duplicated as a mirror: https://ftpmirror.fnu.org/foo/foo-1.0.tar.gz
end
- EOS
-
- expected_offenses = [{ message: "URL should not be duplicated as a mirror: https://ftpmirror.fnu.org/foo/foo-1.0.tar.gz",
- severity: :convention,
- line: 4,
- column: 2,
- source: source }]
-
- inspect_source(source)
-
- expected_offenses.zip(cop.offenses.reverse).each do |expected, actual|
- expect_offense(expected, actual)
- end
+ RUBY
end
end
end
@@ -195,42 +167,31 @@ end
describe RuboCop::Cop::FormulaAuditStrict::PyPiUrls do
subject(:cop) { described_class.new }
- context "When auditing urls" do
- it "with pypi offenses" do
- formulas = [{
- "url" => "https://pypi.python.org/packages/source/foo/foo-0.1.tar.gz",
- "msg" => "https://pypi.python.org/packages/source/foo/foo-0.1.tar.gz should be `https://files.pythonhosted.org/packages/source/foo/foo-0.1.tar.gz`",
- "col" => 2,
- "corrected_url" =>"https://files.pythonhosted.org/packages/source/foo/foo-0.1.tar.gz",
- }]
- formulas.each do |formula|
- source = <<~EOS
- class Foo < Formula
- desc "foo"
- url "#{formula["url"]}"
- end
- EOS
- corrected_source = <<~EOS
- class Foo < Formula
- desc "foo"
- url "#{formula["corrected_url"]}"
- end
- EOS
- expected_offenses = [{ message: formula["msg"],
- severity: :convention,
- line: 3,
- column: formula["col"],
- source: source }]
+ context "when a pypi.python.org URL is used" do
+ it "reports an offense" do
+ expect_offense(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url "https://pypi.python.org/packages/source/foo/foo-0.1.tar.gz"
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ https://pypi.python.org/packages/source/foo/foo-0.1.tar.gz should be `https://files.pythonhosted.org/packages/source/foo/foo-0.1.tar.gz`
+ end
+ RUBY
+ end
- inspect_source(source)
- # Check for expected offenses
- expected_offenses.zip(cop.offenses.reverse).each do |expected, actual|
- expect_offense(expected, actual)
+ it "support auto-correction" do
+ corrected = autocorrect_source(<<~RUBY)
+ class Foo < Formula
+ desc "foo"
+ url "https://pypi.python.org/packages/source/foo/foo-0.1.tar.gz"
end
- # Check for expected auto corrected source
- new_source = autocorrect_source(source)
- expect(new_source).to eq(corrected_source)
- end
+ RUBY
+
+ expect(corrected).to eq <<~RUBY
+ class Foo < Formula
+ desc "foo"
+ url "https://files.pythonhosted.org/packages/source/foo/foo-0.1.tar.gz"
+ end
+ RUBY
end
end
end
diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb
index a5821ee14..c40a72fcc 100644
--- a/Library/Homebrew/test/spec_helper.rb
+++ b/Library/Homebrew/test/spec_helper.rb
@@ -2,6 +2,8 @@ require "find"
require "pathname"
require "rspec/its"
require "rspec/wait"
+require "rubocop"
+require "rubocop/rspec/support"
require "set"
if ENV["HOMEBREW_TESTS_COVERAGE"]
@@ -23,7 +25,6 @@ require "test/support/helper/fixtures"
require "test/support/helper/formula"
require "test/support/helper/mktmpdir"
require "test/support/helper/output_as_tty"
-require "test/support/helper/rubocop"
require "test/support/helper/spec/shared_context/homebrew_cask" if OS.mac?
require "test/support/helper/spec/shared_context/integration_test"
@@ -43,11 +44,14 @@ RSpec.configure do |config|
config.filter_run_when_matching :focus
+ config.include(FileUtils)
+
+ config.include(RuboCop::RSpec::ExpectOffense)
+
config.include(Test::Helper::Fixtures)
config.include(Test::Helper::Formula)
config.include(Test::Helper::MkTmpDir)
config.include(Test::Helper::OutputAsTTY)
- config.include(Test::Helper::RuboCop)
config.before(:each, :needs_compat) do
skip "Requires compatibility layer." if ENV["HOMEBREW_NO_COMPAT"]
diff --git a/Library/Homebrew/test/support/helper/rubocop.rb b/Library/Homebrew/test/support/helper/rubocop.rb
deleted file mode 100644
index 351f2ad82..000000000
--- a/Library/Homebrew/test/support/helper/rubocop.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module Test
- module Helper
- module RuboCop
- def expect_offense(expected, actual)
- expect(actual).to_not be_nil
- expect(actual.message).to eq(expected[:message])
- expect(actual.severity).to eq(expected[:severity])
- expect(actual.line).to eq(expected[:line])
- expect(actual.column).to eq(expected[:column])
- end
- end
- end
-end
diff --git a/Library/Homebrew/test/tap_spec.rb b/Library/Homebrew/test/tap_spec.rb
index 76af27b92..cb908da9f 100644
--- a/Library/Homebrew/test/tap_spec.rb
+++ b/Library/Homebrew/test/tap_spec.rb
@@ -1,6 +1,4 @@
describe Tap do
- include FileUtils
-
alias_matcher :have_formula_file, :be_formula_file
alias_matcher :have_custom_remote, :be_custom_remote
@@ -307,8 +305,6 @@ describe Tap do
end
describe CoreTap do
- include FileUtils
-
specify "attributes" do
expect(subject.user).to eq("Homebrew")
expect(subject.repo).to eq("core")
diff --git a/Library/Homebrew/utils/github.rb b/Library/Homebrew/utils/github.rb
index f88d52403..e73951c8d 100644
--- a/Library/Homebrew/utils/github.rb
+++ b/Library/Homebrew/utils/github.rb
@@ -235,7 +235,7 @@ module GitHub
def issues_for_formula(name, options = {})
tap = options[:tap] || CoreTap.instance
- search_issues(name, state: "open", repo: "#{tap.user}/homebrew-#{tap.repo}")
+ search_issues(name, state: "open", repo: "#{tap.user}/homebrew-#{tap.repo}", in: "title")
end
def print_pull_requests_matching(query)