Merge pull request #20485 from SMillerDev/feat/audit/codeberg_audit
feat: audit codeberg repos
This commit is contained in:
commit
24057cc9a5
@ -928,6 +928,20 @@ module Cask
|
||||
add_error error, location: url.location if error
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def audit_forgejo_prerelease_version
|
||||
return if (url = cask.url).nil?
|
||||
|
||||
odebug "Auditing Forgejo prerelease"
|
||||
user, repo = get_repo_data(%r{https?://codeberg\.org/([^/]+)/([^/]+)/?.*}) if online?
|
||||
return if user.nil? || repo.nil?
|
||||
|
||||
tag = SharedAudits.forgejo_tag_from_url(url.to_s)
|
||||
tag ||= cask.version
|
||||
error = SharedAudits.forgejo_release(user, repo, tag, cask:)
|
||||
add_error error, location: url.location if error
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def audit_github_repository_archived
|
||||
# Deprecated/disabled casks may have an archived repository.
|
||||
@ -960,6 +974,23 @@ module Cask
|
||||
add_error "GitLab repo is archived", location: url.location if metadata["archived"]
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def audit_forgejo_repository_archived
|
||||
return if cask.deprecated? || cask.disabled?
|
||||
return if (url = cask.url).nil?
|
||||
|
||||
user, repo = get_repo_data(%r{https?://codeberg\.org/([^/]+)/([^/]+)/?.*}) if online?
|
||||
return if user.nil? || repo.nil?
|
||||
|
||||
metadata = SharedAudits.forgejo_repo_data(user, repo)
|
||||
return if metadata.nil?
|
||||
|
||||
return unless metadata["archived"]
|
||||
|
||||
add_error "Forgejo repository is archived since #{metadata["archived_at"]}",
|
||||
location: url.location
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def audit_github_repository
|
||||
return unless new_cask?
|
||||
@ -1002,6 +1033,20 @@ module Cask
|
||||
add_error error, location: url.location if error
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def audit_forgejo_repository
|
||||
return unless new_cask?
|
||||
return if (url = cask.url).nil?
|
||||
|
||||
user, repo = get_repo_data(%r{https?://codeberg\.org/([^/]+)/([^/]+)/?.*})
|
||||
return if user.nil? || repo.nil?
|
||||
|
||||
odebug "Auditing Forgejo repo"
|
||||
|
||||
error = SharedAudits.forgejo(user, repo)
|
||||
add_error error, location: url.location if error
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def audit_denylist
|
||||
return unless cask.tap
|
||||
|
@ -677,6 +677,19 @@ module Homebrew
|
||||
problem "GitLab repository is archived" if metadata["archived"]
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def audit_forgejo_repository_archived
|
||||
return if formula.deprecated? || formula.disabled?
|
||||
|
||||
user, repo = get_repo_data(%r{https?://codeberg\.org/([^/]+)/([^/]+)/?.*}) if @online
|
||||
return if user.blank?
|
||||
|
||||
metadata = SharedAudits.forgejo_repo_data(user, repo)
|
||||
return if metadata.nil?
|
||||
|
||||
problem "Forgejo repository is archived since #{metadata["archived_at"]}" if metadata["archived"]
|
||||
end
|
||||
|
||||
def audit_github_repository
|
||||
user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*}) if @new_formula
|
||||
|
||||
@ -708,6 +721,17 @@ module Homebrew
|
||||
new_formula_problem warning
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def audit_forgejo_repository
|
||||
user, repo = get_repo_data(%r{https?://codeberg\.org/([^/]+)/([^/]+)/?.*}) if @new_formula
|
||||
return if user.blank?
|
||||
|
||||
warning = SharedAudits.forgejo(user, repo)
|
||||
return if warning.nil?
|
||||
|
||||
new_formula_problem warning
|
||||
end
|
||||
|
||||
def get_repo_data(regex)
|
||||
return unless @core_tap
|
||||
return unless @online
|
||||
@ -839,6 +863,16 @@ module Homebrew
|
||||
error = SharedAudits.github_release(owner, repo, tag, formula:)
|
||||
problem error if error
|
||||
end
|
||||
when %r{^https://codeberg\.org/([\w-]+)/([\w-]+)}
|
||||
owner = T.must(Regexp.last_match(1))
|
||||
repo = T.must(Regexp.last_match(2))
|
||||
tag = SharedAudits.forgejo_tag_from_url(url)
|
||||
tag ||= formula.stable.specs[:tag]
|
||||
|
||||
if @online && !tag.nil?
|
||||
error = SharedAudits.forgejo_release(owner, repo, tag, formula:)
|
||||
problem error if error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -96,4 +96,21 @@ RSpec.describe SharedAudits do
|
||||
expect(described_class.gitlab_tag_from_url(url)).to eq("2.5")
|
||||
end
|
||||
end
|
||||
|
||||
describe "::forgejo_tag_from_url" do
|
||||
it "finds tags in basic urls" do
|
||||
url = "https://codeberg.org/Aviac/codeberg-cli/archive/v0.4.11.tar.gz"
|
||||
expect(described_class.forgejo_tag_from_url(url)).to eq("v0.4.11")
|
||||
end
|
||||
|
||||
it "finds tags in urls with subgroups" do
|
||||
url = "https://codeberg.org/Aviac/codeberg-cli/archive/some/test/1.2.3.tar.gz"
|
||||
expect(described_class.forgejo_tag_from_url(url)).to eq("some/test/1.2.3")
|
||||
end
|
||||
|
||||
it "finds tags in orgs/repos with special characters" do
|
||||
url = "https://codeberg.org/Aviaca-b_cv/codeberg-cli/archive/v0.4.11.tar.gz"
|
||||
expect(described_class.forgejo_tag_from_url(url)).to eq("v0.4.11")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -90,6 +90,16 @@ module SharedAudits
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(user: String, repo: String).returns(T.nilable(T::Hash[String, T.untyped])) }
|
||||
def self.forgejo_repo_data(user, repo)
|
||||
@forgejo_repo_data ||= T.let({}, T.nilable(T::Hash[String, T.untyped]))
|
||||
@forgejo_repo_data["#{user}/#{repo}"] ||= begin
|
||||
result = Utils::Curl.curl_output("https://codeberg.org/api/v1/repos/#{user}/#{repo}")
|
||||
|
||||
JSON.parse(result.stdout) if result.status.success?
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(user: String, repo: String, tag: String).returns(T.nilable(T::Hash[String, T.untyped])) }
|
||||
private_class_method def self.gitlab_release_data(user, repo, tag)
|
||||
id = "#{user}/#{repo}/#{tag}"
|
||||
@ -125,6 +135,40 @@ module SharedAudits
|
||||
"#{tag} is a GitLab pre-release."
|
||||
end
|
||||
|
||||
sig { params(user: String, repo: String, tag: String).returns(T.nilable(T::Hash[String, T.untyped])) }
|
||||
private_class_method def self.forgejo_release_data(user, repo, tag)
|
||||
id = "#{user}/#{repo}/#{tag}"
|
||||
@forgejo_release_data ||= T.let({}, T.nilable(T::Hash[String, T.untyped]))
|
||||
@forgejo_release_data[id] ||= begin
|
||||
result = Utils::Curl.curl_output(
|
||||
"https://codeberg.org/api/v1/repos/#{user}/#{repo}/releases/tags/#{tag}", "--fail"
|
||||
)
|
||||
JSON.parse(result.stdout) if result.status.success?
|
||||
end
|
||||
end
|
||||
|
||||
sig {
|
||||
params(
|
||||
user: String, repo: String, tag: String, formula: T.nilable(Formula), cask: T.nilable(Cask::Cask),
|
||||
).returns(
|
||||
T.nilable(String),
|
||||
)
|
||||
}
|
||||
def self.forgejo_release(user, repo, tag, formula: nil, cask: nil)
|
||||
release = forgejo_release_data(user, repo, tag)
|
||||
return unless release
|
||||
return unless release["prerelease"]
|
||||
|
||||
exception, version = if formula
|
||||
[formula.tap&.audit_exception(:forgejo_prerelease_allowlist, formula.name), formula.version]
|
||||
elsif cask
|
||||
[cask.tap&.audit_exception(:forgejo_prerelease_allowlist, cask.token), cask.version]
|
||||
end
|
||||
return if [version, "all"].include?(exception)
|
||||
|
||||
"#{tag} is a Forgejo pre-release."
|
||||
end
|
||||
|
||||
sig { params(user: String, repo: String).returns(T.nilable(String)) }
|
||||
def self.github(user, repo)
|
||||
metadata = github_repo_data(user, repo)
|
||||
@ -191,6 +235,23 @@ module SharedAudits
|
||||
"Bitbucket repository not notable enough (<30 forks and <75 watchers)"
|
||||
end
|
||||
|
||||
sig { params(user: String, repo: String).returns(T.nilable(String)) }
|
||||
def self.forgejo(user, repo)
|
||||
metadata = forgejo_repo_data(user, repo)
|
||||
return if metadata.nil?
|
||||
|
||||
return "Forgejo fork (not canonical repository)" if metadata["fork"]
|
||||
|
||||
if (metadata["forks_count"] < 30) && (metadata["watchers_count"] < 30) &&
|
||||
(metadata["stars_count"] < 75)
|
||||
return "Forgejo repository not notable enough (<30 forks, <30 watchers and <75 stars)"
|
||||
end
|
||||
|
||||
return if Date.parse(metadata["created_at"]) <= (Date.today - 30)
|
||||
|
||||
"Forgejo repository too new (<30 days old)"
|
||||
end
|
||||
|
||||
sig { params(url: String).returns(T.nilable(String)) }
|
||||
def self.github_tag_from_url(url)
|
||||
tag = url[%r{^https://github\.com/[\w-]+/[\w.-]+/archive/refs/tags/(.+)\.(tar\.gz|zip)$}, 1]
|
||||
@ -202,6 +263,11 @@ module SharedAudits
|
||||
url[%r{^https://gitlab\.com/(?:\w[\w.-]*/){2,}-/archive/([^/]+)/}, 1]
|
||||
end
|
||||
|
||||
sig { params(url: String).returns(T.nilable(String)) }
|
||||
def self.forgejo_tag_from_url(url)
|
||||
url[%r{^https://codeberg\.org/[\w-]+/[\w.-]+/archive/(.+)\.(tar\.gz|zip)$}, 1]
|
||||
end
|
||||
|
||||
sig { params(formula_or_cask: T.any(Formula, Cask::Cask)).returns(T.nilable(String)) }
|
||||
def self.check_deprecate_disable_reason(formula_or_cask)
|
||||
return if !formula_or_cask.deprecated? && !formula_or_cask.disabled?
|
||||
|
Loading…
x
Reference in New Issue
Block a user