Skip to content

Commit

Permalink
livecheck: expand typed: strict usage
Browse files Browse the repository at this point in the history
This updates livecheck files to use `typed: script` where feasible.

The remaining exception is `livecheck/strategy.rb`, as I wasn't
able to figure out how to resolve the typing issues around the
`@strategies` variable (I tried a couple of approaches but couldn't
find a working solution). This includes changes to resolve the other
type errors in `strategy.rb` but leaves the file as `typed: true`
for now.
  • Loading branch information
samford committed Jul 5, 2024
1 parent 82a6fd2 commit e2e2b89
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 40 deletions.
40 changes: 20 additions & 20 deletions Library/Homebrew/livecheck/skip_conditions.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# typed: true
# typed: strict
# frozen_string_literal: true

module Homebrew
Expand All @@ -14,7 +14,7 @@ module SkipConditions
livecheckable: T::Boolean,
full_name: T::Boolean,
verbose: T::Boolean,
).returns(Hash)
).returns(T::Hash[Symbol, T.untyped])
}
def package_or_resource_skip(package_or_resource, livecheckable, full_name: false, verbose: false)
formula = package_or_resource if package_or_resource.is_a?(Formula)
Expand Down Expand Up @@ -51,7 +51,7 @@ def package_or_resource_skip(package_or_resource, livecheckable, full_name: fals
_livecheckable: T::Boolean,
full_name: T::Boolean,
verbose: T::Boolean,
).returns(Hash)
).returns(T::Hash[Symbol, T.untyped])
}
def formula_head_only(formula, _livecheckable, full_name: false, verbose: false)
return {} if !formula.head_only? || formula.any_version_installed?
Expand All @@ -71,7 +71,7 @@ def formula_head_only(formula, _livecheckable, full_name: false, verbose: false)
livecheckable: T::Boolean,
full_name: T::Boolean,
verbose: T::Boolean,
).returns(Hash)
).returns(T::Hash[Symbol, T.untyped])
}
def formula_deprecated(formula, livecheckable, full_name: false, verbose: false)
return {} if !formula.deprecated? || livecheckable
Expand All @@ -85,7 +85,7 @@ def formula_deprecated(formula, livecheckable, full_name: false, verbose: false)
livecheckable: T::Boolean,
full_name: T::Boolean,
verbose: T::Boolean,
).returns(Hash)
).returns(T::Hash[Symbol, T.untyped])
}
def formula_disabled(formula, livecheckable, full_name: false, verbose: false)
return {} if !formula.disabled? || livecheckable
Expand All @@ -99,7 +99,7 @@ def formula_disabled(formula, livecheckable, full_name: false, verbose: false)
livecheckable: T::Boolean,
full_name: T::Boolean,
verbose: T::Boolean,
).returns(Hash)
).returns(T::Hash[Symbol, T.untyped])
}
def formula_versioned(formula, livecheckable, full_name: false, verbose: false)
return {} if !formula.versioned_formula? || livecheckable
Expand All @@ -113,7 +113,7 @@ def formula_versioned(formula, livecheckable, full_name: false, verbose: false)
livecheckable: T::Boolean,
full_name: T::Boolean,
verbose: T::Boolean,
).returns(Hash)
).returns(T::Hash[Symbol, T.untyped])
}
def cask_deprecated(cask, livecheckable, full_name: false, verbose: false)
return {} if !cask.deprecated? || livecheckable
Expand All @@ -127,7 +127,7 @@ def cask_deprecated(cask, livecheckable, full_name: false, verbose: false)
livecheckable: T::Boolean,
full_name: T::Boolean,
verbose: T::Boolean,
).returns(Hash)
).returns(T::Hash[Symbol, T.untyped])
}
def cask_disabled(cask, livecheckable, full_name: false, verbose: false)
return {} if !cask.disabled? || livecheckable
Expand All @@ -142,7 +142,7 @@ def cask_disabled(cask, livecheckable, full_name: false, verbose: false)
full_name: T::Boolean,
verbose: T::Boolean,
extract_plist: T::Boolean,
).returns(Hash)
).returns(T::Hash[Symbol, T.untyped])
}
def cask_extract_plist(cask, _livecheckable, full_name: false, verbose: false, extract_plist: false)
return {} if extract_plist || cask.livecheck.strategy != :extract_plist
Expand All @@ -162,7 +162,7 @@ def cask_extract_plist(cask, _livecheckable, full_name: false, verbose: false, e
livecheckable: T::Boolean,
full_name: T::Boolean,
verbose: T::Boolean,
).returns(Hash)
).returns(T::Hash[Symbol, T.untyped])
}
def cask_version_latest(cask, livecheckable, full_name: false, verbose: false)
return {} if !(cask.present? && cask.version&.latest?) || livecheckable
Expand All @@ -176,7 +176,7 @@ def cask_version_latest(cask, livecheckable, full_name: false, verbose: false)
livecheckable: T::Boolean,
full_name: T::Boolean,
verbose: T::Boolean,
).returns(Hash)
).returns(T::Hash[Symbol, T.untyped])
}
def cask_url_unversioned(cask, livecheckable, full_name: false, verbose: false)
return {} if !(cask.present? && cask.url&.unversioned?) || livecheckable
Expand All @@ -185,28 +185,28 @@ def cask_url_unversioned(cask, livecheckable, full_name: false, verbose: false)
end

# Skip conditions for formulae.
FORMULA_CHECKS = [
FORMULA_CHECKS = T.let([
:package_or_resource_skip,
:formula_head_only,
:formula_deprecated,
:formula_disabled,
:formula_versioned,
].freeze
].freeze, T::Array[Symbol])

# Skip conditions for casks.
CASK_CHECKS = [
CASK_CHECKS = T.let([
:package_or_resource_skip,
:cask_deprecated,
:cask_disabled,
:cask_extract_plist,
:cask_version_latest,
:cask_url_unversioned,
].freeze
].freeze, T::Array[Symbol])

# Skip conditions for resources.
RESOURCE_CHECKS = [
RESOURCE_CHECKS = T.let([
:package_or_resource_skip,
].freeze
].freeze, T::Array[Symbol])

# If a formula/cask/resource should be skipped, we return a hash from
# `Livecheck#status_hash`, which contains a `status` type and sometimes
Expand All @@ -217,7 +217,7 @@ def cask_url_unversioned(cask, livecheckable, full_name: false, verbose: false)
full_name: T::Boolean,
verbose: T::Boolean,
extract_plist: T::Boolean,
).returns(Hash)
).returns(T::Hash[Symbol, T.untyped])
}
def skip_information(package_or_resource, full_name: false, verbose: false, extract_plist: true)
livecheckable = package_or_resource.livecheckable?
Expand Down Expand Up @@ -255,7 +255,7 @@ def skip_information(package_or_resource, full_name: false, verbose: false, extr
full_name: T::Boolean,
verbose: T::Boolean,
extract_plist: T::Boolean,
).returns(T.nilable(Hash))
).returns(T.nilable(T::Hash[Symbol, T.untyped]))
}
def referenced_skip_information(
livecheck_package_or_resource,
Expand Down Expand Up @@ -298,7 +298,7 @@ def referenced_skip_information(
end

# Prints default livecheck output in relation to skip conditions.
sig { params(skip_hash: Hash).void }
sig { params(skip_hash: T::Hash[Symbol, T.untyped]).void }
def print_skip_information(skip_hash)
return unless skip_hash.is_a?(Hash)

Expand Down
18 changes: 9 additions & 9 deletions Library/Homebrew/livecheck/strategy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ module Strategy

# cURL does not set a default `--max-time` value, so we provide a value
# to ensure cURL will time out in a reasonable amount of time.
CURL_MAX_TIME = CURL_CONNECT_TIMEOUT + 5
CURL_MAX_TIME = T.let(CURL_CONNECT_TIMEOUT + 5, Integer)

# The `curl` process will sometimes hang indefinitely (despite setting
# the `--max-time` argument) and it needs to be quit for livecheck to
# continue. This value is used to set the `timeout` argument on
# `Utils::Curl` method calls in {Strategy}.
CURL_PROCESS_TIMEOUT = CURL_MAX_TIME + 5
CURL_PROCESS_TIMEOUT = T.let(CURL_MAX_TIME + 5, Integer)

# The maximum number of redirections that `curl` should allow.
MAX_REDIRECTIONS = 5
Expand All @@ -41,31 +41,31 @@ module Strategy
# number of responses in this context. The `+ 1` here accounts for the
# situation where there are exactly `MAX_REDIRECTIONS` number of
# redirections, followed by a final `200 OK` response.
MAX_PARSE_ITERATIONS = MAX_REDIRECTIONS + 1
MAX_PARSE_ITERATIONS = T.let(MAX_REDIRECTIONS + 1, Integer)

# Baseline `curl` arguments used in {Strategy} methods.
DEFAULT_CURL_ARGS = [
DEFAULT_CURL_ARGS = T.let([
# Follow redirections to handle mirrors, relocations, etc.
"--location",
"--max-redirs", MAX_REDIRECTIONS.to_s,
# Avoid progress bar text, so we can reliably identify `curl` error
# messages in output
"--silent"
].freeze
].freeze, T::Array[String])

# `curl` arguments used in `Strategy#page_content` method.
PAGE_CONTENT_CURL_ARGS = ([
PAGE_CONTENT_CURL_ARGS = T.let(([
"--compressed",
# Return an error when the HTTP response code is 400 or greater but
# continue to return body content
"--fail-with-body",
# Include HTTP response headers in output, so we can identify the
# final URL after any redirections
"--include",
] + DEFAULT_CURL_ARGS).freeze
] + DEFAULT_CURL_ARGS).freeze, T::Array[String])

# Baseline `curl` options used in {Strategy} methods.
DEFAULT_CURL_OPTIONS = {
DEFAULT_CURL_OPTIONS = T.let({
print_stdout: false,
print_stderr: false,
debug: false,
Expand All @@ -74,7 +74,7 @@ module Strategy
connect_timeout: CURL_CONNECT_TIMEOUT,
max_time: CURL_MAX_TIME,
retries: 0,
}.freeze
}.freeze, T::Hash[Symbol, T.untyped])

# A regex used to identify a tarball extension at the end of a string.
TARBALL_EXTENSION_REGEX = /
Expand Down
9 changes: 6 additions & 3 deletions Library/Homebrew/livecheck/strategy/crate.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# typed: true
# typed: strict
# frozen_string_literal: true

module Homebrew
Expand All @@ -23,14 +23,17 @@ class Crate

# The default `strategy` block used to extract version information when
# a `strategy` block isn't provided.
DEFAULT_BLOCK = proc do |json, regex|
DEFAULT_BLOCK = T.let(proc do |json, regex|
json["versions"]&.map do |version|
next if version["yanked"]
next unless (match = version["num"]&.match(regex))

match[1]
end
end.freeze
end.freeze, T.proc.params(
arg0: T::Hash[String, T.untyped],
arg1: Regexp,
).returns(T.any(String, T::Array[String])))

# The `Regexp` used to determine if the strategy applies to the URL.
URL_MATCH_REGEX = %r{
Expand Down
4 changes: 2 additions & 2 deletions Library/Homebrew/livecheck/strategy/github_releases.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# typed: true
# typed: strict
# frozen_string_literal: true

module Homebrew
Expand Down Expand Up @@ -50,7 +50,7 @@ class GithubReleases
# Keys in the release JSON that could contain the version.
# The tag name is checked first, to better align with the {Git}
# strategy.
VERSION_KEYS = ["tag_name", "name"].freeze
VERSION_KEYS = T.let(["tag_name", "name"].freeze, T::Array[String])

# Whether the strategy can be applied to the provided URL.
#
Expand Down
4 changes: 2 additions & 2 deletions Library/Homebrew/livecheck/strategy/header_match.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# typed: true
# typed: strict
# frozen_string_literal: true

module Homebrew
Expand All @@ -20,7 +20,7 @@ class HeaderMatch
URL_MATCH_REGEX = %r{^https?://}i

# The header fields to check when a `strategy` block isn't provided.
DEFAULT_HEADERS_TO_CHECK = ["content-disposition", "location"].freeze
DEFAULT_HEADERS_TO_CHECK = T.let(["content-disposition", "location"].freeze, T::Array[String])

# Whether the strategy can be applied to the provided URL.
#
Expand Down
4 changes: 2 additions & 2 deletions Library/Homebrew/livecheck/strategy/sparkle.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# typed: true
# typed: strict
# frozen_string_literal: true

require "bundle_version"
Expand All @@ -20,7 +20,7 @@ class Sparkle
URL_MATCH_REGEX = %r{^https?://}i

# Common `os` values used in appcasts to refer to macOS.
APPCAST_MACOS_STRINGS = ["macos", "osx"].freeze
APPCAST_MACOS_STRINGS = T.let(["macos", "osx"].freeze, T::Array[String])

# Whether the strategy can be applied to the provided URL.
#
Expand Down
4 changes: 2 additions & 2 deletions Library/Homebrew/livecheck/strategy/xorg.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# typed: true
# typed: strict
# frozen_string_literal: true

module Homebrew
Expand Down Expand Up @@ -56,7 +56,7 @@ class Xorg

# Used to cache page content, so we don't fetch the same pages
# repeatedly.
@page_data = {}
@page_data = T.let({}, T::Hash[String, String])

# Whether the strategy can be applied to the provided URL.
#
Expand Down

0 comments on commit e2e2b89

Please sign in to comment.