Merge pull request #20235 from Homebrew/slash-not-plus-in-paths

rubocops/text: Prefer `lib/"string"` over `lib+"string"`
This commit is contained in:
Issy Long 2025-07-11 12:56:54 +00:00 committed by GitHub
commit 7f333ab6ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 12 deletions

View File

@ -90,6 +90,30 @@ module RuboCop
problem "Use separate `make` calls" problem "Use separate `make` calls"
end end
find_every_method_call_by_name(body_node, :+).each do |plus_node|
next unless plus_node.receiver&.send_type?
next unless plus_node.first_argument&.str_type?
receiver_method = plus_node.receiver.method_name
path_arg = plus_node.first_argument.str_content
case receiver_method
when :prefix
next unless (match = path_arg.match(%r{^(bin|include|libexec|lib|sbin|share|Frameworks)(?:/| |$)}))
offending_node(plus_node)
problem "Use `#{match[1].downcase}` instead of `prefix + \"#{match[1]}\"`"
when :bin, :include, :libexec, :lib, :sbin, :share
next if path_arg.empty?
offending_node(plus_node)
good = "#{receiver_method}/\"#{path_arg}\""
problem "Use `#{good}` instead of `#{plus_node.source}`" do |corrector|
corrector.replace(plus_node.loc.expression, good)
end
end
end
body_node.each_descendant(:dstr) do |dstr_node| body_node.each_descendant(:dstr) do |dstr_node|
dstr_node.each_descendant(:begin) do |interpolation_node| dstr_node.each_descendant(:begin) do |interpolation_node|
next unless interpolation_node.source.match?(/#\{\w+\s*\+\s*['"][^}]+\}/) next unless interpolation_node.source.match?(/#\{\w+\s*\+\s*['"][^}]+\}/)
@ -98,20 +122,8 @@ module RuboCop
problem "Do not concatenate paths in string interpolation" problem "Do not concatenate paths in string interpolation"
end end
end end
prefix_path(body_node) do |prefix_node, path|
next unless (match = path.match(%r{^(bin|include|libexec|lib|sbin|share|Frameworks)(?:/| |$)}))
offending_node(prefix_node)
problem "Use `#{match[1].downcase}` instead of `prefix + \"#{match[1]}\"`"
end end
end end
# Find: prefix + "foo"
def_node_search :prefix_path, <<~EOS
$(send (send nil? :prefix) :+ (str $_))
EOS
end
end end
module FormulaAuditStrict module FormulaAuditStrict

View File

@ -231,6 +231,19 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Text do
RUBY RUBY
end end
it 'reports offenses if eg `lib+"thing"` is present' do
expect_offense(<<~RUBY)
class Foo < Formula
def install
(lib+"foo").install
^^^^^^^^^ FormulaAudit/Text: Use `lib/"foo"` instead of `lib+"foo"`
(bin+"foobar").install
^^^^^^^^^^^^ FormulaAudit/Text: Use `bin/"foobar"` instead of `bin+"foobar"`
end
end
RUBY
end
it 'reports an offense if `prefix + "bin"` is present' do it 'reports an offense if `prefix + "bin"` is present' do
expect_offense(<<~RUBY) expect_offense(<<~RUBY)
class Foo < Formula class Foo < Formula