From 40e4b38d0508a815b81135c012aea3e3d1f4d2dd Mon Sep 17 00:00:00 2001 From: Rylan Polster Date: Sat, 10 Oct 2020 13:38:43 -0400 Subject: [PATCH 1/2] style: python versions must match python dependency --- Library/Homebrew/rubocops/lines.rb | 37 +++++ Library/Homebrew/test/rubocops/lines_spec.rb | 140 +++++++++++++++++++ 2 files changed, 177 insertions(+) diff --git a/Library/Homebrew/rubocops/lines.rb b/Library/Homebrew/rubocops/lines.rb index 9f7dfe437a..e7d70da60e 100644 --- a/Library/Homebrew/rubocops/lines.rb +++ b/Library/Homebrew/rubocops/lines.rb @@ -319,6 +319,43 @@ module RuboCop EOS end + # This cop makes sure that python versions are consistent. + # + # @api private + class PythonVersions < FormulaCop + def audit_formula(_node, _class_node, _parent_class_node, body_node) + python_formula_node = find_every_method_call_by_name(body_node, :depends_on).find do |dep| + string_content(parameters(dep).first).start_with? "python@" + end + + return if python_formula_node.blank? + + python_version = string_content(parameters(python_formula_node).first).split("@").last + + find_strings(body_node).each do |str| + string_content = string_content(str) + + next unless match = string_content.match(/^python(@)?(\d\.\d)$/) + next if python_version == match[2] + + @fix = if match[1] + "python@#{python_version}" + else + "python#{python_version}" + end + + offending_node(str) + problem "References to `#{string_content}` should match the specified python dependency (`#{@fix}`)" + end + end + + def autocorrect(node) + lambda do |corrector| + corrector.replace(node.source_range, "\"#{@fix}\"") + end + end + end + # This cop checks for other miscellaneous style violations. # # @api private diff --git a/Library/Homebrew/test/rubocops/lines_spec.rb b/Library/Homebrew/test/rubocops/lines_spec.rb index fa61dd9a64..aa4f0069af 100644 --- a/Library/Homebrew/test/rubocops/lines_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_spec.rb @@ -731,6 +731,146 @@ describe RuboCop::Cop::FormulaAudit::Licenses do end end +describe RuboCop::Cop::FormulaAudit::PythonVersions do + subject(:cop) { described_class.new } + + context "When auditing python versions" do + it "allow python with no dependency" do + expect_no_offenses(<<~RUBY) + class Foo < Formula + def install + puts "python@3.8" + end + end + RUBY + end + + it "allow non versioned python references" do + expect_no_offenses(<<~RUBY) + class Foo < Formula + depends_on "python@3.9" + + def install + puts "python" + end + end + RUBY + end + + it "allow python with no version" do + expect_no_offenses(<<~RUBY) + class Foo < Formula + depends_on "python@3.9" + + def install + puts "python3" + end + end + RUBY + end + + it "allow matching versions" do + expect_no_offenses(<<~RUBY) + class Foo < Formula + depends_on "python@3.9" + + def install + puts "python@3.9" + end + end + RUBY + end + + it "allow matching versions without `@`" do + expect_no_offenses(<<~RUBY) + class Foo < Formula + depends_on "python@3.9" + + def install + puts "python3.9" + end + end + RUBY + end + + it "do not allow mismatching versions" do + expect_offense(<<~RUBY) + class Foo < Formula + depends_on "python@3.9" + + def install + puts "python@3.8" + ^^^^^^^^^^^^ References to `python@3.8` should match the specified python dependency (`python@3.9`) + end + end + RUBY + end + + it "do not allow mismatching versions without `@`" do + expect_offense(<<~RUBY) + class Foo < Formula + depends_on "python@3.9" + + def install + puts "python3.8" + ^^^^^^^^^^^ References to `python3.8` should match the specified python dependency (`python3.9`) + end + end + RUBY + end + + it "autocorrects mismatching versions" do + source = <<~RUBY + class Foo < Formula + depends_on "python@3.9" + + def install + puts "python@3.8" + end + end + RUBY + + corrected_source = <<~RUBY + class Foo < Formula + depends_on "python@3.9" + + def install + puts "python@3.9" + end + end + RUBY + + new_source = autocorrect_source(source) + expect(new_source).to eq(corrected_source) + end + + it "autocorrects mismatching versions without `@`" do + source = <<~RUBY + class Foo < Formula + depends_on "python@3.9" + + def install + puts "python3.8" + end + end + RUBY + + corrected_source = <<~RUBY + class Foo < Formula + depends_on "python@3.9" + + def install + puts "python3.9" + end + end + RUBY + + new_source = autocorrect_source(source) + expect(new_source).to eq(corrected_source) + end + end +end + describe RuboCop::Cop::FormulaAudit::Miscellaneous do subject(:cop) { described_class.new } From 3b944434cfba22338758f0705de4813d076b444f Mon Sep 17 00:00:00 2001 From: Rylan Polster Date: Sun, 11 Oct 2020 09:46:14 -0400 Subject: [PATCH 2/2] style: allow python versions with two digits --- Library/Homebrew/rubocops/lines.rb | 2 +- Library/Homebrew/test/rubocops/lines_spec.rb | 100 +++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/rubocops/lines.rb b/Library/Homebrew/rubocops/lines.rb index e7d70da60e..ef4eaf0352 100644 --- a/Library/Homebrew/rubocops/lines.rb +++ b/Library/Homebrew/rubocops/lines.rb @@ -335,7 +335,7 @@ module RuboCop find_strings(body_node).each do |str| string_content = string_content(str) - next unless match = string_content.match(/^python(@)?(\d\.\d)$/) + next unless match = string_content.match(/^python(@)?(\d\.\d+)$/) next if python_version == match[2] @fix = if match[1] diff --git a/Library/Homebrew/test/rubocops/lines_spec.rb b/Library/Homebrew/test/rubocops/lines_spec.rb index aa4f0069af..d9c117deb8 100644 --- a/Library/Homebrew/test/rubocops/lines_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_spec.rb @@ -793,6 +793,30 @@ describe RuboCop::Cop::FormulaAudit::PythonVersions do RUBY end + it "allow matching versions with two digits" do + expect_no_offenses(<<~RUBY) + class Foo < Formula + depends_on "python@3.10" + + def install + puts "python@3.10" + end + end + RUBY + end + + it "allow matching versions without `@` with two digits" do + expect_no_offenses(<<~RUBY) + class Foo < Formula + depends_on "python@3.10" + + def install + puts "python3.10" + end + end + RUBY + end + it "do not allow mismatching versions" do expect_offense(<<~RUBY) class Foo < Formula @@ -819,6 +843,32 @@ describe RuboCop::Cop::FormulaAudit::PythonVersions do RUBY end + it "do not allow mismatching versions with two digits" do + expect_offense(<<~RUBY) + class Foo < Formula + depends_on "python@3.11" + + def install + puts "python@3.10" + ^^^^^^^^^^^^^ References to `python@3.10` should match the specified python dependency (`python@3.11`) + end + end + RUBY + end + + it "do not allow mismatching versions without `@` with two digits" do + expect_offense(<<~RUBY) + class Foo < Formula + depends_on "python@3.11" + + def install + puts "python3.10" + ^^^^^^^^^^^^ References to `python3.10` should match the specified python dependency (`python3.11`) + end + end + RUBY + end + it "autocorrects mismatching versions" do source = <<~RUBY class Foo < Formula @@ -868,6 +918,56 @@ describe RuboCop::Cop::FormulaAudit::PythonVersions do new_source = autocorrect_source(source) expect(new_source).to eq(corrected_source) end + + it "autocorrects mismatching versions with two digits" do + source = <<~RUBY + class Foo < Formula + depends_on "python@3.10" + + def install + puts "python@3.9" + end + end + RUBY + + corrected_source = <<~RUBY + class Foo < Formula + depends_on "python@3.10" + + def install + puts "python@3.10" + end + end + RUBY + + new_source = autocorrect_source(source) + expect(new_source).to eq(corrected_source) + end + + it "autocorrects mismatching versions without `@` with two digits" do + source = <<~RUBY + class Foo < Formula + depends_on "python@3.11" + + def install + puts "python3.10" + end + end + RUBY + + corrected_source = <<~RUBY + class Foo < Formula + depends_on "python@3.11" + + def install + puts "python3.11" + end + end + RUBY + + new_source = autocorrect_source(source) + expect(new_source).to eq(corrected_source) + end end end