diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index 1d6fa742e4df8..2c935ae351bb5 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -754,7 +754,7 @@ def cask_plist_min_os def audit_github_prerelease_version odebug "Auditing GitHub prerelease" user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*}) if online? - return if user.nil? + return if user.nil? || repo.nil? tag = SharedAudits.github_tag_from_url(cask.url) tag ||= cask.version @@ -765,7 +765,7 @@ def audit_github_prerelease_version sig { void } def audit_gitlab_prerelease_version user, repo = get_repo_data(%r{https?://gitlab\.com/([^/]+)/([^/]+)/?.*}) if online? - return if user.nil? + return if user.nil? || repo.nil? odebug "Auditing GitLab prerelease" @@ -781,7 +781,7 @@ def audit_github_repository_archived return if cask.deprecated? || cask.disabled? user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*}) if online? - return if user.nil? + return if user.nil? || repo.nil? metadata = SharedAudits.github_repo_data(user, repo) return if metadata.nil? @@ -795,7 +795,7 @@ def audit_gitlab_repository_archived return if cask.deprecated? || cask.disabled? user, repo = get_repo_data(%r{https?://gitlab\.com/([^/]+)/([^/]+)/?.*}) if online? - return if user.nil? + return if user.nil? || repo.nil? odebug "Auditing GitLab repo archived" @@ -810,7 +810,7 @@ def audit_github_repository return unless new_cask? user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*}) - return if user.nil? + return if user.nil? || repo.nil? odebug "Auditing GitHub repo" @@ -823,7 +823,7 @@ def audit_gitlab_repository return unless new_cask? user, repo = get_repo_data(%r{https?://gitlab\.com/([^/]+)/([^/]+)/?.*}) - return if user.nil? + return if user.nil? || repo.nil? odebug "Auditing GitLab repo" @@ -836,7 +836,7 @@ def audit_bitbucket_repository return unless new_cask? user, repo = get_repo_data(%r{https?://bitbucket\.org/([^/]+)/([^/]+)/?.*}) - return if user.nil? + return if user.nil? || repo.nil? odebug "Auditing Bitbucket repo" diff --git a/Library/Homebrew/formula_auditor.rb b/Library/Homebrew/formula_auditor.rb index f0c63a2e51426..371635f967e16 100644 --- a/Library/Homebrew/formula_auditor.rb +++ b/Library/Homebrew/formula_auditor.rb @@ -582,15 +582,13 @@ def audit_eol metadata = SharedAudits.eol_data(name, formula.version.major) metadata ||= SharedAudits.eol_data(name, formula.version.major_minor) - return if metadata.blank? || metadata["eol"] == false + return if metadata.blank? || (eol_date = metadata["eol"]).blank? - see_url = "see #{Formatter.url("https://endoflife.date/#{name}")}" - if metadata["eol"] == true - problem "Product is EOL, #{see_url}" - return - end + message = "Product is EOL" + message += " since #{eol_date}" if Date.parse(eol_date.to_s) <= Date.today + message += ", see #{Formatter.url("https://endoflife.date/#{name}")}" - problem "Product is EOL since #{metadata["eol"]}, #{see_url}" if Date.parse(metadata["eol"]) <= Date.today + problem message end def audit_wayback_url @@ -786,6 +784,8 @@ def audit_specs tag ||= stable.version if @online + return if owner.nil? || repo.nil? + error = SharedAudits.gitlab_release(owner, repo, tag, formula:) problem error if error end @@ -796,6 +796,8 @@ def audit_specs tag ||= formula.stable.specs[:tag] if @online + return if owner.nil? || repo.nil? + error = SharedAudits.github_release(owner, repo, tag, formula:) problem error if error end diff --git a/Library/Homebrew/utils/shared_audits.rb b/Library/Homebrew/utils/shared_audits.rb index 3329ea1797fb4..b7cd07a4c496d 100644 --- a/Library/Homebrew/utils/shared_audits.rb +++ b/Library/Homebrew/utils/shared_audits.rb @@ -1,4 +1,4 @@ -# typed: true +# typed: strict # frozen_string_literal: true require "utils/curl" @@ -10,8 +10,9 @@ module SharedAudits module_function + sig { params(product: String, cycle: String).returns(T.nilable(T::Hash[String, T::Hash[Symbol, T.untyped]])) } def eol_data(product, cycle) - @eol_data ||= {} + @eol_data ||= T.let({}, T.nilable(T::Hash[String, T::Hash[String, T.untyped]])) @eol_data["#{product}/#{cycle}"] ||= begin out, _, status = Utils::Curl.curl_output("--location", "https://endoflife.date/api/#{product}/#{cycle}.json") json = JSON.parse(out) if status.success? @@ -20,8 +21,9 @@ def eol_data(product, cycle) end end + sig { params(user: String, repo: String).returns(T.nilable(T::Hash[String, T.untyped])) } def github_repo_data(user, repo) - @github_repo_data ||= {} + @github_repo_data ||= T.let({}, T.nilable(T::Hash[String, T.untyped])) @github_repo_data["#{user}/#{repo}"] ||= GitHub.repository(user, repo) @github_repo_data["#{user}/#{repo}"] @@ -31,10 +33,11 @@ def github_repo_data(user, repo) raise unless e.message.match?(GitHub::API::GITHUB_IP_ALLOWLIST_ERROR) end + sig { params(user: String, repo: String, tag: String).returns(T.nilable(T::Hash[String, T.untyped])) } def github_release_data(user, repo, tag) id = "#{user}/#{repo}/#{tag}" url = "#{GitHub::API_URL}/repos/#{user}/#{repo}/releases/tags/#{tag}" - @github_release_data ||= {} + @github_release_data ||= T.let({}, T.nilable(T::Hash[String, T.untyped])) @github_release_data[id] ||= GitHub::API.open_rest(url) @github_release_data[id] @@ -44,6 +47,13 @@ def github_release_data(user, repo, tag) raise unless e.message.match?(GitHub::API::GITHUB_IP_ALLOWLIST_ERROR) end + sig { + params( + user: String, repo: String, tag: String, formula: T.nilable(Formula), cask: T.nilable(Cask::Cask), + ).returns( + T.nilable(String), + ) + } def github_release(user, repo, tag, formula: nil, cask: nil) release = github_release_data(user, repo, tag) return unless release @@ -63,8 +73,9 @@ def github_release(user, repo, tag, formula: nil, cask: nil) "#{tag} is a GitHub draft." if release["draft"] end + sig { params(user: String, repo: String).returns(T.nilable(T::Hash[String, T.untyped])) } def gitlab_repo_data(user, repo) - @gitlab_repo_data ||= {} + @gitlab_repo_data ||= T.let({}, T.nilable(T::Hash[String, T.untyped])) @gitlab_repo_data["#{user}/#{repo}"] ||= begin out, _, status = Utils::Curl.curl_output("https://gitlab.com/api/v4/projects/#{user}%2F#{repo}") json = JSON.parse(out) if status.success? @@ -73,9 +84,10 @@ def gitlab_repo_data(user, repo) end end + sig { params(user: String, repo: String, tag: String).returns(T.nilable(T::Hash[String, T.untyped])) } def gitlab_release_data(user, repo, tag) id = "#{user}/#{repo}/#{tag}" - @gitlab_release_data ||= {} + @gitlab_release_data ||= T.let({}, T.nilable(T::Hash[String, T.untyped])) @gitlab_release_data[id] ||= begin out, _, status = Utils::Curl.curl_output( "https://gitlab.com/api/v4/projects/#{user}%2F#{repo}/releases/#{tag}", "--fail" @@ -84,6 +96,13 @@ def gitlab_release_data(user, repo, tag) end end + sig { + params( + user: String, repo: String, tag: String, formula: T.nilable(Formula), cask: T.nilable(Cask::Cask), + ).returns( + T.nilable(String), + ) + } def gitlab_release(user, repo, tag, formula: nil, cask: nil) release = gitlab_release_data(user, repo, tag) return unless release @@ -100,6 +119,7 @@ def gitlab_release(user, repo, tag, formula: nil, cask: nil) "#{tag} is a GitLab pre-release." end + sig { params(user: String, repo: String).returns(T.nilable(String)) } def github(user, repo) metadata = github_repo_data(user, repo) @@ -117,6 +137,7 @@ def github(user, repo) "GitHub repository too new (<30 days old)" end + sig { params(user: String, repo: String).returns(T.nilable(String)) } def gitlab(user, repo) metadata = gitlab_repo_data(user, repo) @@ -132,6 +153,7 @@ def gitlab(user, repo) "GitLab repository too new (<30 days old)" end + sig { params(user: String, repo: String).returns(T.nilable(String)) } def bitbucket(user, repo) api_url = "https://api.bitbucket.org/2.0/repositories/#{user}/#{repo}" out, _, status = Utils::Curl.curl_output("--request", "GET", api_url) @@ -163,6 +185,7 @@ def bitbucket(user, repo) "Bitbucket repository not notable enough (<30 forks and <75 watchers)" end + sig { params(url: String).returns(T.nilable(String)) } def github_tag_from_url(url) url = url.to_s tag = url.match(%r{^https://github\.com/[\w-]+/[\w-]+/archive/refs/tags/([^/]+)\.(tar\.gz|zip)$}) @@ -174,6 +197,7 @@ def github_tag_from_url(url) tag end + sig { params(url: String).returns(T.nilable(String)) } def gitlab_tag_from_url(url) url = url.to_s url.match(%r{^https://gitlab\.com/[\w-]+/[\w-]+/-/archive/([^/]+)/})