diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml index 0e3f49fdff..8099c7ad07 100644 --- a/Library/.rubocop.yml +++ b/Library/.rubocop.yml @@ -12,9 +12,6 @@ FormulaAudit/Text: FormulaAudit/Caveats: Enabled: true -FormulaAudit/Checksum: - Enabled: true - FormulaAuditStrict/BottleBlock: Enabled: true diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 105bc0e86a..e069fef365 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -1246,6 +1246,7 @@ class ResourceAuditor def audit audit_version + audit_checksum audit_download_strategy audit_urls self @@ -1272,6 +1273,28 @@ class ResourceAuditor problem "version #{version} should not end with an underline and a number" end + def audit_checksum + return unless checksum + + case checksum.hash_type + when :md5 + problem "MD5 checksums are deprecated, please use SHA256" + return + when :sha1 + problem "SHA1 checksums are deprecated, please use SHA256" + return + when :sha256 then len = 64 + end + + if checksum.empty? + problem "#{checksum.hash_type} is empty" + else + problem "#{checksum.hash_type} should be #{len} characters" unless checksum.hexdigest.length == len + problem "#{checksum.hash_type} contains invalid characters" unless checksum.hexdigest =~ /^[a-fA-F0-9]+$/ + problem "#{checksum.hash_type} should be lowercase" unless checksum.hexdigest == checksum.hexdigest.downcase + end + end + def audit_download_strategy if url =~ %r{^(cvs|bzr|hg|fossil)://} || url =~ %r{^(svn)\+http://} problem "Use of the #{$&} scheme is deprecated, pass `:using => :#{$1}` instead" diff --git a/Library/Homebrew/rubocops.rb b/Library/Homebrew/rubocops.rb index 4710654fa2..c4a38cdb77 100644 --- a/Library/Homebrew/rubocops.rb +++ b/Library/Homebrew/rubocops.rb @@ -5,4 +5,3 @@ require_relative "./rubocops/components_redundancy_cop" require_relative "./rubocops/homepage_cop" require_relative "./rubocops/text_cop" require_relative "./rubocops/caveats_cop" -require_relative "./rubocops/checksum_cop" diff --git a/Library/Homebrew/rubocops/checksum_cop.rb b/Library/Homebrew/rubocops/checksum_cop.rb deleted file mode 100644 index 98e6a8bd35..0000000000 --- a/Library/Homebrew/rubocops/checksum_cop.rb +++ /dev/null @@ -1,55 +0,0 @@ -require_relative "./extend/formula_cop" - -module RuboCop - module Cop - module FormulaAudit - class Checksum < FormulaCop - def audit_formula(_node, _class_node, _parent_class_node, body_node) - %w[Stable Devel HEAD].each do |name| - next unless spec_node = find_block(body_node, name.downcase.to_sym) - _, _, spec_body = *spec_node - audit_checksums(spec_body, name) - resource_blocks = find_all_blocks(spec_body, :resource) - resource_blocks.each do |rb| - _, _, resource_body = *rb - audit_checksums(resource_body, name, string_content(parameters(rb).first)) - end - end - end - - def audit_checksums(node, spec, resource_name = nil) - msg_prefix = if resource_name - "#{spec} resource \"#{resource_name}\": " - else - "#{spec}: " - end - if find_node_method_by_name(node, :md5) - problem "#{msg_prefix}MD5 checksums are deprecated, please use SHA256" - end - - if find_node_method_by_name(node, :sha1) - problem "#{msg_prefix}SHA1 checksums are deprecated, please use SHA256" - end - - checksum_node = find_node_method_by_name(node, :sha256) - checksum = parameters(checksum_node).first - if string_content(checksum).size.zero? - problem "#{msg_prefix}sha256 is empty" - return - end - - if string_content(checksum).size != 64 && regex_match_group(checksum, /^\w*$/) - problem "#{msg_prefix}sha256 should be 64 characters" - end - - unless regex_match_group(checksum, /^[a-f0-9]+$/i) - problem "#{msg_prefix}sha256 contains invalid characters" - end - - return unless regex_match_group(checksum, /^[a-f0-9]+$/) - problem "#{msg_prefix}sha256 should be lowercase" - end - end - end - end -end diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index b6fa45d3fb..75a3e72d5d 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -167,18 +167,12 @@ module RuboCop nil end - # Returns an array of block nodes of depth first order named block_name below node + # Returns an array of block nodes named block_name inside node def find_blocks(node, block_name) return if node.nil? node.each_child_node(:block).select { |block_node| block_name == block_node.method_name } end - # Returns an array of block nodes of any depth below node in AST - def find_all_blocks(node, block_name) - return if node.nil? - node.each_descendant(:block).select { |block_node| block_name == block_node.method_name } - end - # Returns a method definition node with method_name def find_method_def(node, method_name) return if node.nil? @@ -256,7 +250,8 @@ module RuboCop # Returns the array of arguments of the method_node def parameters(method_node) - method_node.method_args if method_node.send_type? || method_node.block_type? + return unless method_node.send_type? + method_node.method_args end # Returns true if the given parameters are present in method call diff --git a/Library/Homebrew/test/rubocops/checksum_cop_spec.rb b/Library/Homebrew/test/rubocops/checksum_cop_spec.rb deleted file mode 100644 index fb21771ff9..0000000000 --- a/Library/Homebrew/test/rubocops/checksum_cop_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -require "rubocop" -require "rubocop/rspec/support" -require_relative "../../extend/string" -require_relative "../../rubocops/checksum_cop" - -describe RuboCop::Cop::FormulaAudit::Checksum do - subject(:cop) { described_class.new } - - context "When auditing spec checksums" do - it "When the checksum is empty" 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 "" - - resource "foo-package" do - url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz" - sha256 "" - end - end - end - EOS - - expected_offenses = [{ message: "Stable: sha256 is empty", - severity: :convention, - line: 5, - column: 4, - source: source }, - { message: "Stable resource \"foo-package\": sha256 is empty", - severity: :convention, - line: 9, - column: 6, - source: source }] - - inspect_source(cop, source) - - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end - end - - it "When the checksum is not 64 characters" 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 "5cf6e1ae0a645b426c0474cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9ad" - - resource "foo-package" do - url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz" - sha256 "5cf6e1ae0a645b426c047aaa4cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9" - end - end - end - EOS - - expected_offenses = [{ message: "Stable: sha256 should be 64 characters", - severity: :convention, - line: 5, - column: 12, - source: source }, - { message: "Stable resource \"foo-package\": sha256 should be 64 characters", - severity: :convention, - line: 9, - column: 14, - source: source }] - - inspect_source(cop, source) - - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end - end - end -end