diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml index dafb1221b7..21f123859b 100644 --- a/Library/.rubocop.yml +++ b/Library/.rubocop.yml @@ -15,6 +15,9 @@ FormulaAudit/Caveats: FormulaAudit/Checksum: Enabled: true +FormulaAudit/ChecksumCase: + Enabled: true + FormulaAuditStrict/BottleBlock: Enabled: true diff --git a/Library/Homebrew/rubocops/checksum_cop.rb b/Library/Homebrew/rubocops/checksum_cop.rb index d9e81a4eff..dcaf60e7d3 100644 --- a/Library/Homebrew/rubocops/checksum_cop.rb +++ b/Library/Homebrew/rubocops/checksum_cop.rb @@ -21,15 +21,6 @@ module RuboCop end end - def get_checksum_node(call) - return if parameters(call).empty? || parameters(call).nil? - if parameters(call).first.str_type? - parameters(call).first - elsif parameters(call).first.hash_type? - parameters(call).first.keys.first - end - end - def audit_sha256(checksum) return if checksum.nil? if regex_match_group(checksum, /^$/) @@ -41,12 +32,31 @@ module RuboCop problem "sha256 should be 64 characters" end - if regex_match_group(checksum, /[^a-f0-9]+/i) - problem "sha256 contains invalid characters" - end + return unless regex_match_group(checksum, /[^a-f0-9]+/i) + problem "sha256 contains invalid characters" + end + end - return unless regex_match_group(checksum, /[A-F]+/) - problem "sha256 should be lowercase" + class ChecksumCase < FormulaCop + def audit_formula(_node, _class_node, _parent_class_node, body_node) + return if body_node.nil? + sha256_calls = find_every_method_call_by_name(body_node, :sha256) + sha256_calls.each do |sha256_call| + checksum = get_checksum_node(sha256_call) + next if checksum.nil? + next unless regex_match_group(checksum, /[A-F]+/) + problem "sha256 should be lowercase" + end + end + + private + + def autocorrect(node) + lambda do |corrector| + correction = node.source.downcase + corrector.insert_before(node.source_range, correction) + corrector.remove(node.source_range) + end end end end diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index 98280841cc..439fde6a55 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -277,6 +277,17 @@ module RuboCop end end + # Returns the sha256 str node given a sha256 call node + def get_checksum_node(call) + return if parameters(call).empty? || parameters(call).nil? + if parameters(call).first.str_type? + parameters(call).first + # sha256 is passed as a key-value pair in bottle blocks + elsif parameters(call).first.hash_type? + parameters(call).first.keys.first + end + end + # Returns the begin position of the node's line in source code def line_start_column(node) node.source_range.source_buffer.line_range(node.loc.line).begin_pos diff --git a/Library/Homebrew/test/rubocops/checksum_cop_spec.rb b/Library/Homebrew/test/rubocops/checksum_cop_spec.rb index 633f3117ac..644152c32c 100644 --- a/Library/Homebrew/test/rubocops/checksum_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/checksum_cop_spec.rb @@ -108,7 +108,13 @@ describe RuboCop::Cop::FormulaAudit::Checksum do expect_offense(expected, actual) end end + end +end +describe RuboCop::Cop::FormulaAudit::ChecksumCase do + subject(:cop) { described_class.new } + + context "When auditing spec checksums" do it "When the checksum has upper case characters" do source = <<-EOS.undent class Foo < Formula @@ -176,4 +182,41 @@ describe RuboCop::Cop::FormulaAudit::Checksum do end end end + + context "When auditing checksum with autocorrect" do + it "When there is uppercase sha256" do + source = <<-EOS.undent + 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" + + resource "foo-package" do + url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz" + sha256 "5cf6e1Ae0a645b426b047aa4cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea9" + end + end + end + EOS + + corrected_source = <<-EOS.undent + 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" + + resource "foo-package" do + url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz" + sha256 "5cf6e1ae0a645b426b047aa4cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea9" + end + end + end + EOS + + new_source = autocorrect_source(cop, source) + expect(new_source).to eq(corrected_source) + end + end end