|
| 1 | +require_relative "./extend/formula_cop" |
| 2 | + |
| 3 | +module RuboCop |
| 4 | + module Cop |
| 5 | + module FormulaAudit |
| 6 | + # This cop audits urls and mirrors in Formulae |
| 7 | + class Urls < FormulaCop |
| 8 | + def audit_formula(_node, _class_node, _parent_class_node, body_node) |
| 9 | + urls = find_every_method_call_by_name(body_node, :url) |
| 10 | + mirrors = find_every_method_call_by_name(body_node, :mirror) |
| 11 | + |
| 12 | + # GNU urls; doesn't apply to mirrors |
| 13 | + gnu_pattern = %r{^(?:https?|ftp)://ftpmirror.gnu.org/(.*)} |
| 14 | + audit_urls(urls, gnu_pattern) do |match, url| |
| 15 | + problem "Please use \"https://ftp.gnu.org/gnu/#{match[1]}\" instead of #{url}." |
| 16 | + end |
| 17 | + |
| 18 | + # Fossies upstream requests they aren't used as primary URLs |
| 19 | + # https://github.com/Homebrew/homebrew-core/issues/14486#issuecomment-307753234 |
| 20 | + fossies_pattern = %r{^https?://fossies\.org/} |
| 21 | + audit_urls(urls, fossies_pattern) do |
| 22 | + problem "Please don't use fossies.org in the url (using as a mirror is fine)" |
| 23 | + end |
| 24 | + |
| 25 | + audit_urls(mirrors, /.*/) do |_, mirror| |
| 26 | + urls.each do |url| |
| 27 | + url_string = string_content(parameters(url).first) |
| 28 | + next unless url_string.eql?(mirror) |
| 29 | + problem "URL should not be duplicated as a mirror: #{url_string}" |
| 30 | + end |
| 31 | + end |
| 32 | + |
| 33 | + urls += mirrors |
| 34 | + |
| 35 | + # Check a variety of SSL/TLS URLs that don't consistently auto-redirect |
| 36 | + # or are overly common errors that need to be reduced & fixed over time. |
| 37 | + http_to_https_patterns = Regexp.union([%r{^http://ftp\.gnu\.org/}, |
| 38 | + %r{^http://ftpmirror\.gnu\.org/}, |
| 39 | + %r{^http://download\.savannah\.gnu\.org/}, |
| 40 | + %r{^http://download-mirror\.savannah\.gnu\.org/}, |
| 41 | + %r{^http://[^/]*\.apache\.org/}, |
| 42 | + %r{^http://code\.google\.com/}, |
| 43 | + %r{^http://fossies\.org/}, |
| 44 | + %r{^http://mirrors\.kernel\.org/}, |
| 45 | + %r{^http://(?:[^/]*\.)?bintray\.com/}, |
| 46 | + %r{^http://tools\.ietf\.org/}, |
| 47 | + %r{^http://launchpad\.net/}, |
| 48 | + %r{^http://github\.com/}, |
| 49 | + %r{^http://bitbucket\.org/}, |
| 50 | + %r{^http://anonscm\.debian\.org/}, |
| 51 | + %r{^http://cpan\.metacpan\.org/}, |
| 52 | + %r{^http://hackage\.haskell\.org/}, |
| 53 | + %r{^http://(?:[^/]*\.)?archive\.org}, |
| 54 | + %r{^http://(?:[^/]*\.)?freedesktop\.org}, |
| 55 | + %r{^http://(?:[^/]*\.)?mirrorservice\.org/}]) |
| 56 | + audit_urls(urls, http_to_https_patterns) do |_, url| |
| 57 | + problem "Please use https:// for #{url}" |
| 58 | + end |
| 59 | + |
| 60 | + cpan_pattern = %r{^http://search\.mcpan\.org/CPAN/(.*)}i |
| 61 | + audit_urls(urls, cpan_pattern) do |match, url| |
| 62 | + problem "#{url} should be `https://cpan.metacpan.org/#{match[1]}`" |
| 63 | + end |
| 64 | + |
| 65 | + gnome_pattern = %r{^(http|ftp)://ftp\.gnome\.org/pub/gnome/(.*)}i |
| 66 | + audit_urls(urls, gnome_pattern) do |match, url| |
| 67 | + problem "#{url} should be `https://download.gnome.org/#{match[2]}`" |
| 68 | + end |
| 69 | + |
| 70 | + debian_pattern = %r{^git://anonscm\.debian\.org/users/(.*)}i |
| 71 | + audit_urls(urls, debian_pattern) do |match, url| |
| 72 | + problem "#{url} should be `https://anonscm.debian.org/git/users/#{match[1]}`" |
| 73 | + end |
| 74 | + end |
| 75 | + |
| 76 | + private |
| 77 | + |
| 78 | + def audit_urls(urls, regex) |
| 79 | + urls.each do |url_node| |
| 80 | + url_string_node = parameters(url_node).first |
| 81 | + url_string = string_content(url_string_node) |
| 82 | + match_object = regex_match_group(url_string_node, regex) |
| 83 | + offending_node(url_string_node.parent) if match_object |
| 84 | + yield match_object, url_string if match_object |
| 85 | + end |
| 86 | + end |
| 87 | + end |
| 88 | + end |
| 89 | + end |
| 90 | +end |
0 commit comments