| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  | # typed: strict | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | require "utils/curl" | 
					
						
							| 
									
										
										
										
											2023-09-04 22:17:57 -04:00
										 |  |  | require "utils/github/api" | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 09:42:39 +02:00
										 |  |  | # Auditing functions for rules common to both casks and formulae. | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  | module SharedAudits | 
					
						
							| 
									
										
										
										
											2022-09-18 23:29:15 -05:00
										 |  |  |   URL_TYPE_HOMEPAGE = "homepage URL" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-12 18:40:31 -04:00
										 |  |  |   sig { params(product: String, cycle: String).returns(T.nilable(T::Hash[String, T.untyped])) } | 
					
						
							| 
									
										
										
										
											2024-08-23 03:34:48 +01:00
										 |  |  |   def self.eol_data(product, cycle) | 
					
						
							| 
									
										
										
										
											2024-08-12 18:40:31 -04:00
										 |  |  |     @eol_data ||= T.let({}, T.nilable(T::Hash[String, T.untyped])) | 
					
						
							| 
									
										
										
										
											2024-01-01 23:14:40 +02:00
										 |  |  |     @eol_data["#{product}/#{cycle}"] ||= begin | 
					
						
							| 
									
										
											  
											
												Curl: use `typed: strict`
This upgrades `utils/curl.rb` to `typed: strict`, which requires
a number of changes to pass `brew typecheck`. The most
straightforward are adding type signatures to methods, adding type
annotations (e.g., `T.let`) to variables that need them, and ensuring
that methods always use the expected return type.
I had to refactor areas where we call a `Utils::Curl` method and use
array destructuring on a `SystemCommand::Result` return value
(e.g., `output, errors, status = curl_output(...)`), as Sorbet
doesn't understand implicit array conversion. As suggested by Markus,
I've switched these areas to use `#stdout`, `#stderr`, and `#status`.
This requires the use of an intermediate variable (`result`) in some
cases but this was a fairly straightforward substitution.
I also had to refactor how `Cask::URL::BlockDSL::PageWithURL` works.
It currently uses `page.extend PageWithURL` to add a `url` attribute
but this reworks it to subclass `SimpleDelegator` and use an
`initialize` method instead. This achieves the same goal but in a way
that Sorbet can understand.
											
										 
											2025-01-10 21:37:20 -05:00
										 |  |  |       result = Utils::Curl.curl_output("--location", "https://endoflife.date/api/#{product}/#{cycle}.json") | 
					
						
							|  |  |  |       json = JSON.parse(result.stdout) if result.status.success? | 
					
						
							| 
									
										
										
										
											2024-01-01 23:14:40 +02:00
										 |  |  |       json = nil if json&.dig("message")&.include?("Product not found") | 
					
						
							|  |  |  |       json | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |   sig { params(user: String, repo: String).returns(T.nilable(T::Hash[String, T.untyped])) } | 
					
						
							| 
									
										
										
										
											2024-08-23 03:34:48 +01:00
										 |  |  |   def self.github_repo_data(user, repo) | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |     @github_repo_data ||= T.let({}, T.nilable(T::Hash[String, T.untyped])) | 
					
						
							| 
									
										
										
										
											2020-07-20 21:52:35 +02:00
										 |  |  |     @github_repo_data["#{user}/#{repo}"] ||= GitHub.repository(user, repo) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-22 14:21:06 +02:00
										 |  |  |     @github_repo_data["#{user}/#{repo}"] | 
					
						
							| 
									
										
										
										
											2021-02-15 21:48:21 +05:30
										 |  |  |   rescue GitHub::API::HTTPNotFoundError | 
					
						
							| 
									
										
										
										
											2020-07-20 21:52:35 +02:00
										 |  |  |     nil | 
					
						
							| 
									
										
										
										
											2023-08-25 13:58:51 +01:00
										 |  |  |   rescue GitHub::API::AuthenticationFailedError => e | 
					
						
							| 
									
										
										
										
											2023-08-26 17:16:43 +01:00
										 |  |  |     raise unless e.message.match?(GitHub::API::GITHUB_IP_ALLOWLIST_ERROR) | 
					
						
							| 
									
										
										
										
											2020-07-20 21:52:35 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |   sig { params(user: String, repo: String, tag: String).returns(T.nilable(T::Hash[String, T.untyped])) } | 
					
						
							| 
									
										
										
										
											2024-08-23 03:34:48 +01:00
										 |  |  |   private_class_method def self.github_release_data(user, repo, tag) | 
					
						
							| 
									
										
										
										
											2020-08-13 16:17:47 +02:00
										 |  |  |     id = "#{user}/#{repo}/#{tag}" | 
					
						
							| 
									
										
										
										
											2021-02-17 23:22:26 +05:30
										 |  |  |     url = "#{GitHub::API_URL}/repos/#{user}/#{repo}/releases/tags/#{tag}" | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |     @github_release_data ||= T.let({}, T.nilable(T::Hash[String, T.untyped])) | 
					
						
							| 
									
										
										
										
											2021-02-17 23:22:26 +05:30
										 |  |  |     @github_release_data[id] ||= GitHub::API.open_rest(url) | 
					
						
							| 
									
										
										
										
											2020-08-13 16:17:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @github_release_data[id] | 
					
						
							| 
									
										
										
										
											2021-02-15 21:48:21 +05:30
										 |  |  |   rescue GitHub::API::HTTPNotFoundError | 
					
						
							| 
									
										
										
										
											2020-08-13 16:17:47 +02:00
										 |  |  |     nil | 
					
						
							| 
									
										
										
										
											2023-08-25 13:58:51 +01:00
										 |  |  |   rescue GitHub::API::AuthenticationFailedError => e | 
					
						
							| 
									
										
										
										
											2023-08-26 17:16:43 +01:00
										 |  |  |     raise unless e.message.match?(GitHub::API::GITHUB_IP_ALLOWLIST_ERROR) | 
					
						
							| 
									
										
										
										
											2020-08-13 16:17:47 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |   sig { | 
					
						
							|  |  |  |     params( | 
					
						
							|  |  |  |       user: String, repo: String, tag: String, formula: T.nilable(Formula), cask: T.nilable(Cask::Cask), | 
					
						
							|  |  |  |     ).returns( | 
					
						
							|  |  |  |       T.nilable(String), | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-08-23 03:34:48 +01:00
										 |  |  |   def self.github_release(user, repo, tag, formula: nil, cask: nil) | 
					
						
							| 
									
										
										
										
											2020-09-05 05:41:58 +02:00
										 |  |  |     release = github_release_data(user, repo, tag) | 
					
						
							|  |  |  |     return unless release | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-25 18:53:28 +09:00
										 |  |  |     exception, name, version = if formula | 
					
						
							|  |  |  |       [formula.tap&.audit_exception(:github_prerelease_allowlist, formula.name), formula.name, formula.version] | 
					
						
							| 
									
										
										
										
											2020-12-22 10:51:29 -05:00
										 |  |  |     elsif cask | 
					
						
							| 
									
										
										
										
											2024-12-25 18:53:28 +09:00
										 |  |  |       [cask.tap&.audit_exception(:github_prerelease_allowlist, cask.token), cask.token, cask.version] | 
					
						
							| 
									
										
										
										
											2020-09-05 05:41:58 +02:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-25 18:53:28 +09:00
										 |  |  |     return "#{tag} is a GitHub pre-release." if release["prerelease"] && [version, "all", "any"].exclude?(exception) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-27 19:10:45 +09:00
										 |  |  |     if !release["prerelease"] && exception && [version, "any"].exclude?(exception) | 
					
						
							| 
									
										
										
										
											2024-12-25 18:53:28 +09:00
										 |  |  |       return "#{tag} is not a GitHub pre-release but '#{name}' is in the GitHub prerelease allowlist." | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2020-12-22 10:51:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-14 02:52:30 +00:00
										 |  |  |     "#{tag} is a GitHub draft." if release["draft"] | 
					
						
							| 
									
										
										
										
											2020-09-05 05:41:58 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |   sig { params(user: String, repo: String).returns(T.nilable(T::Hash[String, T.untyped])) } | 
					
						
							| 
									
										
										
										
											2024-08-23 03:34:48 +01:00
										 |  |  |   def self.gitlab_repo_data(user, repo) | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |     @gitlab_repo_data ||= T.let({}, T.nilable(T::Hash[String, T.untyped])) | 
					
						
							| 
									
										
										
										
											2020-07-20 21:52:35 +02:00
										 |  |  |     @gitlab_repo_data["#{user}/#{repo}"] ||= begin | 
					
						
							| 
									
										
											  
											
												Curl: use `typed: strict`
This upgrades `utils/curl.rb` to `typed: strict`, which requires
a number of changes to pass `brew typecheck`. The most
straightforward are adding type signatures to methods, adding type
annotations (e.g., `T.let`) to variables that need them, and ensuring
that methods always use the expected return type.
I had to refactor areas where we call a `Utils::Curl` method and use
array destructuring on a `SystemCommand::Result` return value
(e.g., `output, errors, status = curl_output(...)`), as Sorbet
doesn't understand implicit array conversion. As suggested by Markus,
I've switched these areas to use `#stdout`, `#stderr`, and `#status`.
This requires the use of an intermediate variable (`result`) in some
cases but this was a fairly straightforward substitution.
I also had to refactor how `Cask::URL::BlockDSL::PageWithURL` works.
It currently uses `page.extend PageWithURL` to add a `url` attribute
but this reworks it to subclass `SimpleDelegator` and use an
`initialize` method instead. This achieves the same goal but in a way
that Sorbet can understand.
											
										 
											2025-01-10 21:37:20 -05:00
										 |  |  |       result = Utils::Curl.curl_output("https://gitlab.com/api/v4/projects/#{user}%2F#{repo}") | 
					
						
							|  |  |  |       json = JSON.parse(result.stdout) if result.status.success? | 
					
						
							| 
									
										
										
										
											2023-09-13 09:31:34 +01:00
										 |  |  |       json = nil if json&.dig("message")&.include?("404 Project Not Found") | 
					
						
							|  |  |  |       json | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2020-07-20 21:52:35 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |   sig { params(user: String, repo: String, tag: String).returns(T.nilable(T::Hash[String, T.untyped])) } | 
					
						
							| 
									
										
										
										
											2024-08-23 03:34:48 +01:00
										 |  |  |   private_class_method def self.gitlab_release_data(user, repo, tag) | 
					
						
							| 
									
										
										
										
											2020-08-13 16:17:47 +02:00
										 |  |  |     id = "#{user}/#{repo}/#{tag}" | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |     @gitlab_release_data ||= T.let({}, T.nilable(T::Hash[String, T.untyped])) | 
					
						
							| 
									
										
										
										
											2020-08-13 16:17:47 +02:00
										 |  |  |     @gitlab_release_data[id] ||= begin | 
					
						
							| 
									
										
											  
											
												Curl: use `typed: strict`
This upgrades `utils/curl.rb` to `typed: strict`, which requires
a number of changes to pass `brew typecheck`. The most
straightforward are adding type signatures to methods, adding type
annotations (e.g., `T.let`) to variables that need them, and ensuring
that methods always use the expected return type.
I had to refactor areas where we call a `Utils::Curl` method and use
array destructuring on a `SystemCommand::Result` return value
(e.g., `output, errors, status = curl_output(...)`), as Sorbet
doesn't understand implicit array conversion. As suggested by Markus,
I've switched these areas to use `#stdout`, `#stderr`, and `#status`.
This requires the use of an intermediate variable (`result`) in some
cases but this was a fairly straightforward substitution.
I also had to refactor how `Cask::URL::BlockDSL::PageWithURL` works.
It currently uses `page.extend PageWithURL` to add a `url` attribute
but this reworks it to subclass `SimpleDelegator` and use an
`initialize` method instead. This achieves the same goal but in a way
that Sorbet can understand.
											
										 
											2025-01-10 21:37:20 -05:00
										 |  |  |       result = Utils::Curl.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
										 |  |  |       ) | 
					
						
							| 
									
										
											  
											
												Curl: use `typed: strict`
This upgrades `utils/curl.rb` to `typed: strict`, which requires
a number of changes to pass `brew typecheck`. The most
straightforward are adding type signatures to methods, adding type
annotations (e.g., `T.let`) to variables that need them, and ensuring
that methods always use the expected return type.
I had to refactor areas where we call a `Utils::Curl` method and use
array destructuring on a `SystemCommand::Result` return value
(e.g., `output, errors, status = curl_output(...)`), as Sorbet
doesn't understand implicit array conversion. As suggested by Markus,
I've switched these areas to use `#stdout`, `#stderr`, and `#status`.
This requires the use of an intermediate variable (`result`) in some
cases but this was a fairly straightforward substitution.
I also had to refactor how `Cask::URL::BlockDSL::PageWithURL` works.
It currently uses `page.extend PageWithURL` to add a `url` attribute
but this reworks it to subclass `SimpleDelegator` and use an
`initialize` method instead. This achieves the same goal but in a way
that Sorbet can understand.
											
										 
											2025-01-10 21:37:20 -05:00
										 |  |  |       JSON.parse(result.stdout) if result.status.success? | 
					
						
							| 
									
										
										
										
											2020-08-13 16:17:47 +02:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |   sig { | 
					
						
							|  |  |  |     params( | 
					
						
							|  |  |  |       user: String, repo: String, tag: String, formula: T.nilable(Formula), cask: T.nilable(Cask::Cask), | 
					
						
							|  |  |  |     ).returns( | 
					
						
							|  |  |  |       T.nilable(String), | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-08-23 03:34:48 +01:00
										 |  |  |   def self.gitlab_release(user, repo, tag, formula: nil, cask: nil) | 
					
						
							| 
									
										
										
										
											2020-09-05 06:07:55 +02:00
										 |  |  |     release = gitlab_release_data(user, repo, tag) | 
					
						
							|  |  |  |     return unless release | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-24 20:10:01 -07:00
										 |  |  |     return if DateTime.parse(release["released_at"]) <= DateTime.now | 
					
						
							| 
									
										
										
										
											2020-12-21 12:53:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 10:51:29 -05:00
										 |  |  |     exception, version = if formula | 
					
						
							| 
									
										
										
										
											2021-10-04 21:45:20 -04:00
										 |  |  |       [formula.tap&.audit_exception(:gitlab_prerelease_allowlist, formula.name), formula.version] | 
					
						
							| 
									
										
										
										
											2020-12-21 12:53:12 -05:00
										 |  |  |     elsif cask | 
					
						
							| 
									
										
										
										
											2021-10-04 21:45:20 -04:00
										 |  |  |       [cask.tap&.audit_exception(:gitlab_prerelease_allowlist, cask.token), cask.version] | 
					
						
							| 
									
										
										
										
											2020-12-21 12:53:12 -05:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2020-12-22 10:51:29 -05:00
										 |  |  |     return if [version, "all"].include?(exception) | 
					
						
							| 
									
										
										
										
											2020-09-05 06:07:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     "#{tag} is a GitLab pre-release." | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |   sig { params(user: String, repo: String).returns(T.nilable(String)) } | 
					
						
							| 
									
										
										
										
											2024-08-23 03:34:48 +01:00
										 |  |  |   def self.github(user, repo) | 
					
						
							| 
									
										
										
										
											2020-07-20 21:52:35 +02:00
										 |  |  |     metadata = github_repo_data(user, repo) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  |     return if metadata.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-21 12:53:12 -05:00
										 |  |  |     return "GitHub fork (not canonical repository)" if metadata["fork"] | 
					
						
							| 
									
										
										
										
											2020-09-05 19:08:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |   sig { params(user: String, repo: String).returns(T.nilable(String)) } | 
					
						
							| 
									
										
										
										
											2024-08-23 03:34:48 +01:00
										 |  |  |   def self.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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |   sig { params(user: String, repo: String).returns(T.nilable(String)) } | 
					
						
							| 
									
										
										
										
											2024-08-23 03:34:48 +01:00
										 |  |  |   def self.bitbucket(user, repo) | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  |     api_url = "https://api.bitbucket.org/2.0/repositories/#{user}/#{repo}" | 
					
						
							| 
									
										
											  
											
												Curl: use `typed: strict`
This upgrades `utils/curl.rb` to `typed: strict`, which requires
a number of changes to pass `brew typecheck`. The most
straightforward are adding type signatures to methods, adding type
annotations (e.g., `T.let`) to variables that need them, and ensuring
that methods always use the expected return type.
I had to refactor areas where we call a `Utils::Curl` method and use
array destructuring on a `SystemCommand::Result` return value
(e.g., `output, errors, status = curl_output(...)`), as Sorbet
doesn't understand implicit array conversion. As suggested by Markus,
I've switched these areas to use `#stdout`, `#stderr`, and `#status`.
This requires the use of an intermediate variable (`result`) in some
cases but this was a fairly straightforward substitution.
I also had to refactor how `Cask::URL::BlockDSL::PageWithURL` works.
It currently uses `page.extend PageWithURL` to add a `url` attribute
but this reworks it to subclass `SimpleDelegator` and use an
`initialize` method instead. This achieves the same goal but in a way
that Sorbet can understand.
											
										 
											2025-01-10 21:37:20 -05:00
										 |  |  |     result = Utils::Curl.curl_output("--request", "GET", api_url) | 
					
						
							|  |  |  |     return unless result.status.success? | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Curl: use `typed: strict`
This upgrades `utils/curl.rb` to `typed: strict`, which requires
a number of changes to pass `brew typecheck`. The most
straightforward are adding type signatures to methods, adding type
annotations (e.g., `T.let`) to variables that need them, and ensuring
that methods always use the expected return type.
I had to refactor areas where we call a `Utils::Curl` method and use
array destructuring on a `SystemCommand::Result` return value
(e.g., `output, errors, status = curl_output(...)`), as Sorbet
doesn't understand implicit array conversion. As suggested by Markus,
I've switched these areas to use `#stdout`, `#stderr`, and `#status`.
This requires the use of an intermediate variable (`result`) in some
cases but this was a fairly straightforward substitution.
I also had to refactor how `Cask::URL::BlockDSL::PageWithURL` works.
It currently uses `page.extend PageWithURL` to add a `url` attribute
but this reworks it to subclass `SimpleDelegator` and use an
`initialize` method instead. This achieves the same goal but in a way
that Sorbet can understand.
											
										 
											2025-01-10 21:37:20 -05:00
										 |  |  |     metadata = JSON.parse(result.stdout) | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  |     return if metadata.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-04 15:10:14 +01:00
										 |  |  |     return "Uses deprecated Mercurial support in Bitbucket" if metadata["scm"] == "hg" | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Curl: use `typed: strict`
This upgrades `utils/curl.rb` to `typed: strict`, which requires
a number of changes to pass `brew typecheck`. The most
straightforward are adding type signatures to methods, adding type
annotations (e.g., `T.let`) to variables that need them, and ensuring
that methods always use the expected return type.
I had to refactor areas where we call a `Utils::Curl` method and use
array destructuring on a `SystemCommand::Result` return value
(e.g., `output, errors, status = curl_output(...)`), as Sorbet
doesn't understand implicit array conversion. As suggested by Markus,
I've switched these areas to use `#stdout`, `#stderr`, and `#status`.
This requires the use of an intermediate variable (`result`) in some
cases but this was a fairly straightforward substitution.
I also had to refactor how `Cask::URL::BlockDSL::PageWithURL` works.
It currently uses `page.extend PageWithURL` to add a `url` attribute
but this reworks it to subclass `SimpleDelegator` and use an
`initialize` method instead. This achieves the same goal but in a way
that Sorbet can understand.
											
										 
											2025-01-10 21:37:20 -05:00
										 |  |  |     forks_result = Utils::Curl.curl_output("--request", "GET", "#{api_url}/forks") | 
					
						
							|  |  |  |     return unless forks_result.status.success? | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Curl: use `typed: strict`
This upgrades `utils/curl.rb` to `typed: strict`, which requires
a number of changes to pass `brew typecheck`. The most
straightforward are adding type signatures to methods, adding type
annotations (e.g., `T.let`) to variables that need them, and ensuring
that methods always use the expected return type.
I had to refactor areas where we call a `Utils::Curl` method and use
array destructuring on a `SystemCommand::Result` return value
(e.g., `output, errors, status = curl_output(...)`), as Sorbet
doesn't understand implicit array conversion. As suggested by Markus,
I've switched these areas to use `#stdout`, `#stderr`, and `#status`.
This requires the use of an intermediate variable (`result`) in some
cases but this was a fairly straightforward substitution.
I also had to refactor how `Cask::URL::BlockDSL::PageWithURL` works.
It currently uses `page.extend PageWithURL` to add a `url` attribute
but this reworks it to subclass `SimpleDelegator` and use an
`initialize` method instead. This achieves the same goal but in a way
that Sorbet can understand.
											
										 
											2025-01-10 21:37:20 -05:00
										 |  |  |     watcher_result = Utils::Curl.curl_output("--request", "GET", "#{api_url}/watchers") | 
					
						
							|  |  |  |     return unless watcher_result.status.success? | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Curl: use `typed: strict`
This upgrades `utils/curl.rb` to `typed: strict`, which requires
a number of changes to pass `brew typecheck`. The most
straightforward are adding type signatures to methods, adding type
annotations (e.g., `T.let`) to variables that need them, and ensuring
that methods always use the expected return type.
I had to refactor areas where we call a `Utils::Curl` method and use
array destructuring on a `SystemCommand::Result` return value
(e.g., `output, errors, status = curl_output(...)`), as Sorbet
doesn't understand implicit array conversion. As suggested by Markus,
I've switched these areas to use `#stdout`, `#stderr`, and `#status`.
This requires the use of an intermediate variable (`result`) in some
cases but this was a fairly straightforward substitution.
I also had to refactor how `Cask::URL::BlockDSL::PageWithURL` works.
It currently uses `page.extend PageWithURL` to add a `url` attribute
but this reworks it to subclass `SimpleDelegator` and use an
`initialize` method instead. This achieves the same goal but in a way
that Sorbet can understand.
											
										 
											2025-01-10 21:37:20 -05:00
										 |  |  |     forks_metadata = JSON.parse(forks_result.stdout) | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  |     return if forks_metadata.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Curl: use `typed: strict`
This upgrades `utils/curl.rb` to `typed: strict`, which requires
a number of changes to pass `brew typecheck`. The most
straightforward are adding type signatures to methods, adding type
annotations (e.g., `T.let`) to variables that need them, and ensuring
that methods always use the expected return type.
I had to refactor areas where we call a `Utils::Curl` method and use
array destructuring on a `SystemCommand::Result` return value
(e.g., `output, errors, status = curl_output(...)`), as Sorbet
doesn't understand implicit array conversion. As suggested by Markus,
I've switched these areas to use `#stdout`, `#stderr`, and `#status`.
This requires the use of an intermediate variable (`result`) in some
cases but this was a fairly straightforward substitution.
I also had to refactor how `Cask::URL::BlockDSL::PageWithURL` works.
It currently uses `page.extend PageWithURL` to add a `url` attribute
but this reworks it to subclass `SimpleDelegator` and use an
`initialize` method instead. This achieves the same goal but in a way
that Sorbet can understand.
											
										 
											2025-01-10 21:37:20 -05:00
										 |  |  |     watcher_metadata = JSON.parse(watcher_result.stdout) | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  |     return if watcher_metadata.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-19 12:02:59 -04:00
										 |  |  |     return if forks_metadata["size"] >= 30 || watcher_metadata["size"] >= 75
 | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     "Bitbucket repository not notable enough (<30 forks and <75 watchers)" | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2020-09-09 08:57:56 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |   sig { params(url: String).returns(T.nilable(String)) } | 
					
						
							| 
									
										
										
										
											2024-08-23 03:34:48 +01:00
										 |  |  |   def self.github_tag_from_url(url) | 
					
						
							| 
									
										
										
										
											2024-08-27 11:39:50 -04:00
										 |  |  |     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] | 
					
						
							| 
									
										
										
										
											2020-09-09 08:57:56 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 15:54:49 +01:00
										 |  |  |   sig { params(url: String).returns(T.nilable(String)) } | 
					
						
							| 
									
										
										
										
											2024-08-23 03:34:48 +01:00
										 |  |  |   def self.gitlab_tag_from_url(url) | 
					
						
							| 
									
										
										
										
											2024-08-26 23:06:18 -04:00
										 |  |  |     url[%r{^https://gitlab\.com/(?:\w[\w.-]*/){2,}-/archive/([^/]+)/}, 1] | 
					
						
							| 
									
										
										
										
											2020-09-09 08:57:56 -07:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2024-09-30 23:11:00 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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 | 
					
						
							| 
									
										
										
										
											2020-04-23 21:16:17 +02:00
										 |  |  | end |