2020-10-10 14:16:11 +02:00
|
|
|
# typed: true
|
2020-04-23 21:16:17 +02:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require "utils/curl"
|
|
|
|
|
2020-08-26 09:42:39 +02:00
|
|
|
# Auditing functions for rules common to both casks and formulae.
|
|
|
|
#
|
|
|
|
# @api private
|
2020-04-23 21:16:17 +02:00
|
|
|
module SharedAudits
|
2020-10-10 15:23:03 +02:00
|
|
|
include Utils::Curl
|
|
|
|
extend Utils::Curl
|
|
|
|
|
2020-04-23 21:16:17 +02:00
|
|
|
module_function
|
|
|
|
|
2020-07-20 21:52:35 +02:00
|
|
|
def github_repo_data(user, repo)
|
|
|
|
@github_repo_data ||= {}
|
|
|
|
@github_repo_data["#{user}/#{repo}"] ||= GitHub.repository(user, repo)
|
|
|
|
|
2020-07-22 14:21:06 +02:00
|
|
|
@github_repo_data["#{user}/#{repo}"]
|
2020-07-20 21:52:35 +02:00
|
|
|
rescue GitHub::HTTPNotFoundError
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
2020-08-13 16:17:47 +02:00
|
|
|
def github_release_data(user, repo, tag)
|
|
|
|
id = "#{user}/#{repo}/#{tag}"
|
|
|
|
@github_release_data ||= {}
|
|
|
|
@github_release_data[id] ||= GitHub.open_api("#{GitHub::API_URL}/repos/#{user}/#{repo}/releases/tags/#{tag}")
|
|
|
|
|
|
|
|
@github_release_data[id]
|
|
|
|
rescue GitHub::HTTPNotFoundError
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
2020-09-05 05:41:58 +02:00
|
|
|
GITHUB_PRERELEASE_ALLOWLIST = {
|
2020-09-05 05:50:14 +02:00
|
|
|
"amd-power-gadget" => :all,
|
|
|
|
"elm-format" => "0.8.3",
|
2020-10-19 06:30:00 +08:00
|
|
|
"extraterm" => :all,
|
2020-10-04 16:54:30 +08:00
|
|
|
"freetube" => :all,
|
2020-09-05 05:50:14 +02:00
|
|
|
"gitless" => "0.8.8",
|
2020-10-06 06:05:50 +08:00
|
|
|
"home-assistant" => :all,
|
2020-09-05 05:50:14 +02:00
|
|
|
"infrakit" => "0.5",
|
2020-09-08 12:06:26 +08:00
|
|
|
"pock" => :all,
|
2020-09-05 05:50:14 +02:00
|
|
|
"riff" => "0.5.0",
|
|
|
|
"telegram-cli" => "1.3.1",
|
2020-09-13 01:14:16 +02:00
|
|
|
"toggl-track" => :all,
|
2020-09-05 05:50:14 +02:00
|
|
|
"volta" => "0.8.6",
|
2020-09-05 05:41:58 +02:00
|
|
|
}.freeze
|
|
|
|
|
|
|
|
def github_release(user, repo, tag, formula: nil, cask: nil)
|
|
|
|
release = github_release_data(user, repo, tag)
|
|
|
|
return unless release
|
|
|
|
|
|
|
|
if cask && GITHUB_PRERELEASE_ALLOWLIST[cask.token] == :all
|
|
|
|
return if release["prerelease"]
|
|
|
|
|
|
|
|
return "#{tag} is not a GitHub pre-release but cask '#{cask.token}' is in GITHUB_PRERELEASE_ALLOWLIST."
|
|
|
|
end
|
|
|
|
|
|
|
|
if release["prerelease"]
|
|
|
|
return if formula && GITHUB_PRERELEASE_ALLOWLIST[formula.name] == formula.version
|
|
|
|
|
|
|
|
return "#{tag} is a GitHub pre-release."
|
|
|
|
end
|
|
|
|
|
|
|
|
return "#{tag} is a GitHub draft." if release["draft"]
|
|
|
|
end
|
|
|
|
|
2020-07-20 21:52:35 +02:00
|
|
|
def gitlab_repo_data(user, repo)
|
|
|
|
@gitlab_repo_data ||= {}
|
|
|
|
@gitlab_repo_data["#{user}/#{repo}"] ||= begin
|
|
|
|
out, _, status= curl_output("--request", "GET", "https://gitlab.com/api/v4/projects/#{user}%2F#{repo}")
|
|
|
|
return unless status.success?
|
|
|
|
|
|
|
|
JSON.parse(out)
|
2020-04-23 21:16:17 +02:00
|
|
|
end
|
|
|
|
|
2020-07-22 14:21:06 +02:00
|
|
|
@gitlab_repo_data["#{user}/#{repo}"]
|
2020-07-20 21:52:35 +02:00
|
|
|
end
|
|
|
|
|
2020-08-13 16:17:47 +02:00
|
|
|
def gitlab_release_data(user, repo, tag)
|
|
|
|
id = "#{user}/#{repo}/#{tag}"
|
|
|
|
@gitlab_release_data ||= {}
|
|
|
|
@gitlab_release_data[id] ||= begin
|
|
|
|
out, _, status= curl_output(
|
2020-09-05 13:29:48 -04:00
|
|
|
"https://gitlab.com/api/v4/projects/#{user}%2F#{repo}/releases/#{tag}", "--fail"
|
2020-08-13 16:17:47 +02:00
|
|
|
)
|
|
|
|
return unless status.success?
|
|
|
|
|
|
|
|
JSON.parse(out)
|
|
|
|
end
|
|
|
|
|
|
|
|
@gitlab_release_data[id]
|
|
|
|
end
|
|
|
|
|
2020-09-05 06:07:55 +02:00
|
|
|
GITLAB_PRERELEASE_ALLOWLIST = {}.freeze
|
|
|
|
|
|
|
|
def gitlab_release(user, repo, tag, formula: nil)
|
|
|
|
release = gitlab_release_data(user, repo, tag)
|
|
|
|
return unless release
|
|
|
|
|
|
|
|
return if Date.parse(release["released_at"]) <= Date.today
|
|
|
|
return if formula && GITLAB_PRERELEASE_ALLOWLIST[formula.name] == formula.version
|
|
|
|
|
|
|
|
"#{tag} is a GitLab pre-release."
|
|
|
|
end
|
|
|
|
|
2020-09-05 19:08:44 +02:00
|
|
|
GITHUB_FORK_ALLOWLIST = %w[
|
|
|
|
variar/klogg
|
|
|
|
].freeze
|
|
|
|
|
2020-07-20 21:52:35 +02:00
|
|
|
def github(user, repo)
|
|
|
|
metadata = github_repo_data(user, repo)
|
|
|
|
|
2020-04-23 21:16:17 +02:00
|
|
|
return if metadata.nil?
|
|
|
|
|
2020-09-05 19:08:44 +02:00
|
|
|
if metadata["fork"] && !GITHUB_FORK_ALLOWLIST.include?("#{user}/#{repo}")
|
|
|
|
return "GitHub fork (not canonical repository)"
|
|
|
|
end
|
|
|
|
|
2020-04-23 21:16:17 +02:00
|
|
|
if (metadata["forks_count"] < 30) && (metadata["subscribers_count"] < 30) &&
|
|
|
|
(metadata["stargazers_count"] < 75)
|
|
|
|
return "GitHub repository not notable enough (<30 forks, <30 watchers and <75 stars)"
|
|
|
|
end
|
|
|
|
|
|
|
|
return if Date.parse(metadata["created_at"]) <= (Date.today - 30)
|
|
|
|
|
|
|
|
"GitHub repository too new (<30 days old)"
|
|
|
|
end
|
|
|
|
|
|
|
|
def gitlab(user, repo)
|
2020-07-20 21:52:35 +02:00
|
|
|
metadata = gitlab_repo_data(user, repo)
|
2020-04-23 21:16:17 +02:00
|
|
|
|
|
|
|
return if metadata.nil?
|
|
|
|
|
|
|
|
return "GitLab fork (not canonical repository)" if metadata["fork"]
|
|
|
|
if (metadata["forks_count"] < 30) && (metadata["star_count"] < 75)
|
|
|
|
return "GitLab repository not notable enough (<30 forks and <75 stars)"
|
|
|
|
end
|
|
|
|
|
|
|
|
return if Date.parse(metadata["created_at"]) <= (Date.today - 30)
|
|
|
|
|
|
|
|
"GitLab repository too new (<30 days old)"
|
|
|
|
end
|
|
|
|
|
|
|
|
def bitbucket(user, repo)
|
|
|
|
api_url = "https://api.bitbucket.org/2.0/repositories/#{user}/#{repo}"
|
|
|
|
out, _, status= curl_output("--request", "GET", api_url)
|
|
|
|
return unless status.success?
|
|
|
|
|
|
|
|
metadata = JSON.parse(out)
|
|
|
|
return if metadata.nil?
|
|
|
|
|
|
|
|
return "Uses deprecated mercurial support in Bitbucket" if metadata["scm"] == "hg"
|
|
|
|
|
|
|
|
return "Bitbucket fork (not canonical repository)" unless metadata["parent"].nil?
|
|
|
|
|
|
|
|
return "Bitbucket repository too new (<30 days old)" if Date.parse(metadata["created_on"]) >= (Date.today - 30)
|
|
|
|
|
|
|
|
forks_out, _, forks_status= curl_output("--request", "GET", "#{api_url}/forks")
|
|
|
|
return unless forks_status.success?
|
|
|
|
|
|
|
|
watcher_out, _, watcher_status= curl_output("--request", "GET", "#{api_url}/watchers")
|
|
|
|
return unless watcher_status.success?
|
|
|
|
|
|
|
|
forks_metadata = JSON.parse(forks_out)
|
|
|
|
return if forks_metadata.nil?
|
|
|
|
|
|
|
|
watcher_metadata = JSON.parse(watcher_out)
|
|
|
|
return if watcher_metadata.nil?
|
|
|
|
|
|
|
|
return if (forks_metadata["size"] < 30) && (watcher_metadata["size"] < 75)
|
|
|
|
|
|
|
|
"Bitbucket repository not notable enough (<30 forks and <75 watchers)"
|
|
|
|
end
|
2020-09-09 08:57:56 -07:00
|
|
|
|
|
|
|
def github_tag_from_url(url)
|
|
|
|
url = url.to_s
|
|
|
|
tag = url.match(%r{^https://github\.com/[\w-]+/[\w-]+/archive/([^/]+)\.(tar\.gz|zip)$})
|
|
|
|
.to_a
|
|
|
|
.second
|
|
|
|
tag ||= url.match(%r{^https://github\.com/[\w-]+/[\w-]+/releases/download/([^/]+)/})
|
|
|
|
.to_a
|
|
|
|
.second
|
|
|
|
tag
|
|
|
|
end
|
|
|
|
|
|
|
|
def gitlab_tag_from_url(url)
|
|
|
|
url = url.to_s
|
|
|
|
url.match(%r{^https://gitlab\.com/[\w-]+/[\w-]+/-/archive/([^/]+)/})
|
|
|
|
.to_a
|
|
|
|
.second
|
|
|
|
end
|
2020-04-23 21:16:17 +02:00
|
|
|
end
|