Module: SharedAudits Private

Defined in:
utils/shared_audits.rb

Overview

This module is part of a private API. This module may only be used in the Homebrew/brew repository. Third parties should avoid using this module if possible, as it may be removed or changed without warning.

Auditing functions for rules common to both casks and formulae.

Constant Summary collapse

URL_TYPE_HOMEPAGE =

This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.

"homepage URL"

Class Method Summary collapse

Class Method Details

.bitbucket(user, repo) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'utils/shared_audits.rb', line 207

def self.bitbucket(user, repo)
  api_url = "https://api.bitbucket.org/2.0/repositories/#{user}/#{repo}"
  result = Utils::Curl.curl_output("--request", "GET", api_url)
  return unless result.status.success?

   = JSON.parse(result.stdout)
  return if .nil?

  return "Uses deprecated Mercurial support in Bitbucket" if ["scm"] == "hg"

  return "Bitbucket fork (not canonical repository)" unless ["parent"].nil?

  return "Bitbucket repository too new (<30 days old)" if Date.parse(["created_on"]) >= (Date.today - 30)

  forks_result = Utils::Curl.curl_output("--request", "GET", "#{api_url}/forks")
  return unless forks_result.status.success?

  watcher_result = Utils::Curl.curl_output("--request", "GET", "#{api_url}/watchers")
  return unless watcher_result.status.success?

   = JSON.parse(forks_result.stdout)
  return if .nil?

   = JSON.parse(watcher_result.stdout)
  return if .nil?

  return if ["size"] >= 30 || ["size"] >= 75

  "Bitbucket repository not notable enough (<30 forks and <75 watchers)"
end

.check_deprecate_disable_reason(formula_or_cask) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'utils/shared_audits.rb', line 272

def self.check_deprecate_disable_reason(formula_or_cask)
  return if !formula_or_cask.deprecated? && !formula_or_cask.disabled?

  reason = formula_or_cask.deprecated? ? formula_or_cask.deprecation_reason : formula_or_cask.disable_reason
  return unless reason.is_a?(Symbol)

  reasons = if formula_or_cask.is_a?(Formula)
    DeprecateDisable::FORMULA_DEPRECATE_DISABLE_REASONS
  else
    DeprecateDisable::CASK_DEPRECATE_DISABLE_REASONS
  end

  "#{reason} is not a valid deprecate! or disable! reason" unless reasons.include?(reason)
end

.eol_data(product, cycle) ⇒ Hash{String => T.untyped}?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'utils/shared_audits.rb', line 12

def self.eol_data(product, cycle)
  @eol_data ||= T.let({}, T.nilable(T::Hash[String, T.untyped]))
  key = "#{product}/#{cycle}"
  return @eol_data[key] if @eol_data.key?(key)

  result = Utils::Curl.curl_output(
    "--location",
    "https://endoflife.date/api/v1/products/#{product}/releases/#{cycle}",
  )
  return unless result.status.success?

  @eol_data[key] = begin
    JSON.parse(result.stdout)
  rescue JSON::ParserError
    nil
  end
end

.forgejo(user, repo) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'utils/shared_audits.rb', line 239

def self.forgejo(user, repo)
   = forgejo_repo_data(user, repo)
  return if .nil?

  return "Forgejo fork (not canonical repository)" if ["fork"]

  if (["forks_count"] < 30) && (["watchers_count"] < 30) &&
     (["stars_count"] < 75)
    return "Forgejo repository not notable enough (<30 forks, <30 watchers and <75 stars)"
  end

  return if Date.parse(["created_at"]) <= (Date.today - 30)

  "Forgejo repository too new (<30 days old)"
end

.forgejo_release(user, repo, tag, formula: nil, cask: nil) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'utils/shared_audits.rb', line 157

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

.forgejo_repo_data(user, repo) ⇒ Hash{String => T.untyped}?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



94
95
96
97
98
99
100
101
# File 'utils/shared_audits.rb', line 94

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

.forgejo_tag_from_url(url) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



267
268
269
# File 'utils/shared_audits.rb', line 267

def self.forgejo_tag_from_url(url)
  url[%r{^https://codeberg\.org/[\w-]+/[\w.-]+/archive/(.+)\.(tar\.gz|zip)$}, 1]
end

.github(user, repo) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'utils/shared_audits.rb', line 173

def self.github(user, repo)
   = github_repo_data(user, repo)

  return if .nil?

  return "GitHub fork (not canonical repository)" if ["fork"]

  if (["forks_count"] < 30) && (["subscribers_count"] < 30) &&
     (["stargazers_count"] < 75)
    return "GitHub repository not notable enough (<30 forks, <30 watchers and <75 stars)"
  end

  return if Date.parse(["created_at"]) <= (Date.today - 30)

  "GitHub repository too new (<30 days old)"
end

.github_release(user, repo, tag, formula: nil, cask: nil) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'utils/shared_audits.rb', line 63

def self.github_release(user, repo, tag, formula: nil, cask: nil)
  release = github_release_data(user, repo, tag)
  return unless release

  exception, name, version = if formula
    [formula.tap&.audit_exception(:github_prerelease_allowlist, formula.name), formula.name, formula.version]
  elsif cask
    [cask.tap&.audit_exception(:github_prerelease_allowlist, cask.token), cask.token, cask.version]
  end

  return "#{tag} is a GitHub pre-release." if release["prerelease"] && [version, "all", "any"].exclude?(exception)

  if !release["prerelease"] && exception && [version, "any"].exclude?(exception)
    return "#{tag} is not a GitHub pre-release but '#{name}' is in the GitHub prerelease allowlist."
  end

  "#{tag} is a GitHub draft." if release["draft"]
end

.github_repo_data(user, repo) ⇒ Hash{String => T.untyped}?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



31
32
33
34
35
36
37
38
39
40
# File 'utils/shared_audits.rb', line 31

def self.github_repo_data(user, repo)
  @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}"]
rescue GitHub::API::HTTPNotFoundError
  nil
rescue GitHub::API::AuthenticationFailedError => e
  raise unless e.message.match?(GitHub::API::GITHUB_IP_ALLOWLIST_ERROR)
end

.github_tag_from_url(url) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



256
257
258
259
# File 'utils/shared_audits.rb', line 256

def self.github_tag_from_url(url)
  tag = url[%r{^https://github\.com/[\w-]+/[\w.-]+/archive/refs/tags/(.+)\.(tar\.gz|zip)$}, 1]
  tag || url[%r{^https://github\.com/[\w-]+/[\w.-]+/releases/download/([^/]+)/}, 1]
end

.gitlab(user, repo) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'utils/shared_audits.rb', line 191

def self.gitlab(user, repo)
   = gitlab_repo_data(user, repo)

  return if .nil?

  return "GitLab fork (not canonical repository)" if ["fork"]
  if (["forks_count"] < 30) && (["star_count"] < 75)
    return "GitLab repository not notable enough (<30 forks and <75 stars)"
  end

  return if Date.parse(["created_at"]) <= (Date.today - 30)

  "GitLab repository too new (<30 days old)"
end

.gitlab_release(user, repo, tag, formula: nil, cask: nil) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'utils/shared_audits.rb', line 122

def self.gitlab_release(user, repo, tag, formula: nil, cask: nil)
  release = gitlab_release_data(user, repo, tag)
  return unless release

  return if DateTime.parse(release["released_at"]) <= DateTime.now

  exception, version = if formula
    [formula.tap&.audit_exception(:gitlab_prerelease_allowlist, formula.name), formula.version]
  elsif cask
    [cask.tap&.audit_exception(:gitlab_prerelease_allowlist, cask.token), cask.version]
  end
  return if [version, "all"].include?(exception)

  "#{tag} is a GitLab pre-release."
end

.gitlab_repo_data(user, repo) ⇒ Hash{String => T.untyped}?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



83
84
85
86
87
88
89
90
91
# File 'utils/shared_audits.rb', line 83

def self.gitlab_repo_data(user, repo)
  @gitlab_repo_data ||= T.let({}, T.nilable(T::Hash[String, T.untyped]))
  @gitlab_repo_data["#{user}/#{repo}"] ||= begin
    result = Utils::Curl.curl_output("https://gitlab.com/api/v4/projects/#{user}%2F#{repo}")
    json = JSON.parse(result.stdout) if result.status.success?
    json = nil if json&.dig("message")&.include?("404 Project Not Found")
    json
  end
end

.gitlab_tag_from_url(url) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



262
263
264
# File 'utils/shared_audits.rb', line 262

def self.gitlab_tag_from_url(url)
  url[%r{^https://gitlab\.com/(?:\w[\w.-]*/){2,}-/archive/([^/]+)/}, 1]
end

.no_autobump_new_package_message(message) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



288
289
290
291
292
# File 'utils/shared_audits.rb', line 288

def self.no_autobump_new_package_message(message)
  return if message.is_a?(String) || message != :requires_manual_review

  "`:requires_manual_review` is a temporary reason intended for existing packages, use a different reason instead."
end