2021-01-07 15:30:22 -05:00
|
|
|
# typed: true
|
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Homebrew
|
|
|
|
module Livecheck
|
|
|
|
# The `Livecheck::SkipConditions` module primarily contains methods that
|
2022-09-14 03:42:12 +02:00
|
|
|
# check for various formula/cask/resource conditions where a check should be skipped.
|
2021-01-07 15:30:22 -05:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
module SkipConditions
|
|
|
|
module_function
|
|
|
|
|
2021-01-17 22:45:55 -08:00
|
|
|
sig {
|
2021-01-07 15:30:22 -05:00
|
|
|
params(
|
2022-09-14 03:42:12 +02:00
|
|
|
package_or_resource: T.any(Formula, Cask::Cask, Resource),
|
|
|
|
livecheckable: T::Boolean,
|
|
|
|
full_name: T::Boolean,
|
|
|
|
verbose: T::Boolean,
|
2021-01-07 15:30:22 -05:00
|
|
|
).returns(Hash)
|
2021-01-17 22:45:55 -08:00
|
|
|
}
|
2022-09-14 03:42:12 +02:00
|
|
|
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)
|
2021-01-07 15:30:22 -05:00
|
|
|
|
2021-02-12 18:33:37 +05:30
|
|
|
if (stable_url = formula&.stable&.url)
|
2021-01-07 15:30:22 -05:00
|
|
|
stable_is_gist = stable_url.match?(%r{https?://gist\.github(?:usercontent)?\.com/}i)
|
|
|
|
stable_from_google_code_archive = stable_url.match?(
|
|
|
|
%r{https?://storage\.googleapis\.com/google-code-archive-downloads/}i,
|
|
|
|
)
|
|
|
|
stable_from_internet_archive = stable_url.match?(%r{https?://web\.archive\.org/}i)
|
|
|
|
end
|
|
|
|
|
2022-09-25 02:06:23 +02:00
|
|
|
skip_message = if package_or_resource.livecheck.skip_msg.present?
|
2022-09-14 03:42:12 +02:00
|
|
|
package_or_resource.livecheck.skip_msg
|
2021-01-07 15:30:22 -05:00
|
|
|
elsif !livecheckable
|
|
|
|
if stable_from_google_code_archive
|
|
|
|
"Stable URL is from Google Code Archive"
|
|
|
|
elsif stable_from_internet_archive
|
|
|
|
"Stable URL is from Internet Archive"
|
|
|
|
elsif stable_is_gist
|
|
|
|
"Stable URL is a GitHub Gist"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-09-25 02:06:23 +02:00
|
|
|
return {} if !package_or_resource.livecheck.skip? && skip_message.blank?
|
2021-01-07 15:30:22 -05:00
|
|
|
|
|
|
|
skip_messages = skip_message ? [skip_message] : nil
|
2024-03-07 16:20:20 +00:00
|
|
|
Livecheck.status_hash(package_or_resource, "skipped", skip_messages, full_name:, verbose:)
|
2021-01-07 15:30:22 -05:00
|
|
|
end
|
|
|
|
|
2021-01-17 22:45:55 -08:00
|
|
|
sig {
|
2021-01-07 15:30:22 -05:00
|
|
|
params(
|
|
|
|
formula: Formula,
|
|
|
|
_livecheckable: T::Boolean,
|
|
|
|
full_name: T::Boolean,
|
|
|
|
verbose: T::Boolean,
|
|
|
|
).returns(Hash)
|
2021-01-17 22:45:55 -08:00
|
|
|
}
|
2021-01-07 15:30:22 -05:00
|
|
|
def formula_head_only(formula, _livecheckable, full_name: false, verbose: false)
|
|
|
|
return {} if !formula.head_only? || formula.any_version_installed?
|
|
|
|
|
|
|
|
Livecheck.status_hash(
|
|
|
|
formula,
|
|
|
|
"error",
|
|
|
|
["HEAD only formula must be installed to be livecheckable"],
|
2024-03-07 16:20:20 +00:00
|
|
|
full_name:,
|
|
|
|
verbose:,
|
2021-01-07 15:30:22 -05:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2021-01-17 22:45:55 -08:00
|
|
|
sig {
|
2021-01-07 15:30:22 -05:00
|
|
|
params(
|
|
|
|
formula: Formula,
|
|
|
|
livecheckable: T::Boolean,
|
|
|
|
full_name: T::Boolean,
|
|
|
|
verbose: T::Boolean,
|
|
|
|
).returns(Hash)
|
2021-01-17 22:45:55 -08:00
|
|
|
}
|
2021-01-07 15:30:22 -05:00
|
|
|
def formula_deprecated(formula, livecheckable, full_name: false, verbose: false)
|
|
|
|
return {} if !formula.deprecated? || livecheckable
|
|
|
|
|
2024-03-07 16:20:20 +00:00
|
|
|
Livecheck.status_hash(formula, "deprecated", full_name:, verbose:)
|
2021-01-07 15:30:22 -05:00
|
|
|
end
|
|
|
|
|
2021-01-17 22:45:55 -08:00
|
|
|
sig {
|
2021-01-07 15:30:22 -05:00
|
|
|
params(
|
|
|
|
formula: Formula,
|
|
|
|
livecheckable: T::Boolean,
|
|
|
|
full_name: T::Boolean,
|
|
|
|
verbose: T::Boolean,
|
|
|
|
).returns(Hash)
|
2021-01-17 22:45:55 -08:00
|
|
|
}
|
2021-01-07 15:30:22 -05:00
|
|
|
def formula_disabled(formula, livecheckable, full_name: false, verbose: false)
|
|
|
|
return {} if !formula.disabled? || livecheckable
|
|
|
|
|
2024-03-07 16:20:20 +00:00
|
|
|
Livecheck.status_hash(formula, "disabled", full_name:, verbose:)
|
2021-01-07 15:30:22 -05:00
|
|
|
end
|
|
|
|
|
2021-01-17 22:45:55 -08:00
|
|
|
sig {
|
2021-01-07 15:30:22 -05:00
|
|
|
params(
|
|
|
|
formula: Formula,
|
|
|
|
livecheckable: T::Boolean,
|
|
|
|
full_name: T::Boolean,
|
|
|
|
verbose: T::Boolean,
|
|
|
|
).returns(Hash)
|
2021-01-17 22:45:55 -08:00
|
|
|
}
|
2021-01-07 15:30:22 -05:00
|
|
|
def formula_versioned(formula, livecheckable, full_name: false, verbose: false)
|
|
|
|
return {} if !formula.versioned_formula? || livecheckable
|
|
|
|
|
2024-03-07 16:20:20 +00:00
|
|
|
Livecheck.status_hash(formula, "versioned", full_name:, verbose:)
|
2021-01-07 15:30:22 -05:00
|
|
|
end
|
|
|
|
|
2023-12-17 18:07:51 -05:00
|
|
|
sig {
|
|
|
|
params(
|
|
|
|
cask: Cask::Cask,
|
|
|
|
livecheckable: T::Boolean,
|
|
|
|
full_name: T::Boolean,
|
|
|
|
verbose: T::Boolean,
|
|
|
|
).returns(Hash)
|
|
|
|
}
|
|
|
|
def cask_discontinued(cask, livecheckable, full_name: false, verbose: false)
|
|
|
|
return {} if !cask.discontinued? || livecheckable
|
|
|
|
|
2024-03-07 16:20:20 +00:00
|
|
|
Livecheck.status_hash(cask, "discontinued", full_name:, verbose:)
|
2023-12-17 18:07:51 -05:00
|
|
|
end
|
|
|
|
|
2021-01-17 22:45:55 -08:00
|
|
|
sig {
|
2021-01-07 15:30:22 -05:00
|
|
|
params(
|
|
|
|
cask: Cask::Cask,
|
|
|
|
livecheckable: T::Boolean,
|
|
|
|
full_name: T::Boolean,
|
|
|
|
verbose: T::Boolean,
|
|
|
|
).returns(Hash)
|
2021-01-17 22:45:55 -08:00
|
|
|
}
|
2023-12-04 13:43:33 -05:00
|
|
|
def cask_deprecated(cask, livecheckable, full_name: false, verbose: false)
|
|
|
|
return {} if !cask.deprecated? || livecheckable
|
2021-01-07 15:30:22 -05:00
|
|
|
|
2024-03-07 16:20:20 +00:00
|
|
|
Livecheck.status_hash(cask, "deprecated", full_name:, verbose:)
|
2023-12-04 13:43:33 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
sig {
|
|
|
|
params(
|
|
|
|
cask: Cask::Cask,
|
|
|
|
livecheckable: T::Boolean,
|
|
|
|
full_name: T::Boolean,
|
|
|
|
verbose: T::Boolean,
|
|
|
|
).returns(Hash)
|
|
|
|
}
|
|
|
|
def cask_disabled(cask, livecheckable, full_name: false, verbose: false)
|
|
|
|
return {} if !cask.disabled? || livecheckable
|
|
|
|
|
2024-03-07 16:20:20 +00:00
|
|
|
Livecheck.status_hash(cask, "disabled", full_name:, verbose:)
|
2021-01-07 15:30:22 -05:00
|
|
|
end
|
|
|
|
|
2021-01-17 22:45:55 -08:00
|
|
|
sig {
|
2021-01-07 15:30:22 -05:00
|
|
|
params(
|
|
|
|
cask: Cask::Cask,
|
|
|
|
livecheckable: T::Boolean,
|
|
|
|
full_name: T::Boolean,
|
|
|
|
verbose: T::Boolean,
|
|
|
|
).returns(Hash)
|
2021-01-17 22:45:55 -08:00
|
|
|
}
|
2021-01-07 15:30:22 -05:00
|
|
|
def cask_version_latest(cask, livecheckable, full_name: false, verbose: false)
|
|
|
|
return {} if !(cask.present? && cask.version&.latest?) || livecheckable
|
|
|
|
|
2024-03-07 16:20:20 +00:00
|
|
|
Livecheck.status_hash(cask, "latest", full_name:, verbose:)
|
2021-01-07 15:30:22 -05:00
|
|
|
end
|
|
|
|
|
2021-01-17 22:45:55 -08:00
|
|
|
sig {
|
2021-01-07 15:30:22 -05:00
|
|
|
params(
|
|
|
|
cask: Cask::Cask,
|
|
|
|
livecheckable: T::Boolean,
|
|
|
|
full_name: T::Boolean,
|
|
|
|
verbose: T::Boolean,
|
|
|
|
).returns(Hash)
|
2021-01-17 22:45:55 -08:00
|
|
|
}
|
2021-01-07 15:30:22 -05:00
|
|
|
def cask_url_unversioned(cask, livecheckable, full_name: false, verbose: false)
|
|
|
|
return {} if !(cask.present? && cask.url&.unversioned?) || livecheckable
|
|
|
|
|
2024-03-07 16:20:20 +00:00
|
|
|
Livecheck.status_hash(cask, "unversioned", full_name:, verbose:)
|
2021-01-07 15:30:22 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# Skip conditions for formulae.
|
|
|
|
FORMULA_CHECKS = [
|
2022-09-14 03:42:12 +02:00
|
|
|
:package_or_resource_skip,
|
2021-01-07 15:30:22 -05:00
|
|
|
:formula_head_only,
|
|
|
|
:formula_deprecated,
|
|
|
|
:formula_disabled,
|
|
|
|
:formula_versioned,
|
|
|
|
].freeze
|
|
|
|
|
|
|
|
# Skip conditions for casks.
|
|
|
|
CASK_CHECKS = [
|
2022-09-14 03:42:12 +02:00
|
|
|
:package_or_resource_skip,
|
2023-12-17 18:07:51 -05:00
|
|
|
:cask_discontinued,
|
2023-12-04 13:43:33 -05:00
|
|
|
:cask_deprecated,
|
|
|
|
:cask_disabled,
|
2021-01-07 15:30:22 -05:00
|
|
|
:cask_version_latest,
|
|
|
|
:cask_url_unversioned,
|
|
|
|
].freeze
|
|
|
|
|
2022-09-27 00:18:20 -04:00
|
|
|
# Skip conditions for resources.
|
2022-09-14 03:42:12 +02:00
|
|
|
RESOURCE_CHECKS = [
|
|
|
|
:package_or_resource_skip,
|
|
|
|
].freeze
|
|
|
|
|
|
|
|
# If a formula/cask/resource should be skipped, we return a hash from
|
2021-01-07 15:30:22 -05:00
|
|
|
# `Livecheck#status_hash`, which contains a `status` type and sometimes
|
|
|
|
# error `messages`.
|
2021-01-17 22:45:55 -08:00
|
|
|
sig {
|
2021-01-07 15:30:22 -05:00
|
|
|
params(
|
2022-09-14 03:42:12 +02:00
|
|
|
package_or_resource: T.any(Formula, Cask::Cask, Resource),
|
|
|
|
full_name: T::Boolean,
|
|
|
|
verbose: T::Boolean,
|
2021-01-07 15:30:22 -05:00
|
|
|
).returns(Hash)
|
2021-01-17 22:45:55 -08:00
|
|
|
}
|
2022-09-14 03:42:12 +02:00
|
|
|
def skip_information(package_or_resource, full_name: false, verbose: false)
|
|
|
|
livecheckable = package_or_resource.livecheckable?
|
2021-01-07 15:30:22 -05:00
|
|
|
|
2022-09-14 03:42:12 +02:00
|
|
|
checks = case package_or_resource
|
2021-01-07 15:30:22 -05:00
|
|
|
when Formula
|
|
|
|
FORMULA_CHECKS
|
|
|
|
when Cask::Cask
|
|
|
|
CASK_CHECKS
|
2022-09-14 03:42:12 +02:00
|
|
|
when Resource
|
|
|
|
RESOURCE_CHECKS
|
2021-01-07 15:30:22 -05:00
|
|
|
end
|
|
|
|
return {} unless checks
|
|
|
|
|
|
|
|
checks.each do |method_name|
|
2024-03-07 16:20:20 +00:00
|
|
|
skip_hash = send(method_name, package_or_resource, livecheckable, full_name:, verbose:)
|
2021-01-07 15:30:22 -05:00
|
|
|
return skip_hash if skip_hash.present?
|
|
|
|
end
|
|
|
|
|
|
|
|
{}
|
|
|
|
end
|
|
|
|
|
2022-09-14 03:42:12 +02:00
|
|
|
# Skip conditions for formulae/casks/resources referenced in a `livecheck` block
|
2021-07-19 11:21:29 -04:00
|
|
|
# are treated differently than normal. We only respect certain skip
|
|
|
|
# conditions (returning the related hash) and others are treated as
|
|
|
|
# errors.
|
|
|
|
sig {
|
|
|
|
params(
|
2022-09-14 03:42:12 +02:00
|
|
|
livecheck_package_or_resource: T.any(Formula, Cask::Cask, Resource),
|
|
|
|
original_package_or_resource_name: String,
|
|
|
|
full_name: T::Boolean,
|
|
|
|
verbose: T::Boolean,
|
2021-07-19 11:21:29 -04:00
|
|
|
).returns(T.nilable(Hash))
|
|
|
|
}
|
|
|
|
def referenced_skip_information(
|
2022-09-14 03:42:12 +02:00
|
|
|
livecheck_package_or_resource,
|
|
|
|
original_package_or_resource_name,
|
2021-07-19 11:21:29 -04:00
|
|
|
full_name: false,
|
|
|
|
verbose: false
|
|
|
|
)
|
|
|
|
skip_info = SkipConditions.skip_information(
|
2022-09-14 03:42:12 +02:00
|
|
|
livecheck_package_or_resource,
|
2024-03-07 16:20:20 +00:00
|
|
|
full_name:,
|
|
|
|
verbose:,
|
2021-07-19 11:21:29 -04:00
|
|
|
)
|
|
|
|
return if skip_info.blank?
|
|
|
|
|
2024-03-07 16:20:20 +00:00
|
|
|
referenced_name = Livecheck.package_or_resource_name(livecheck_package_or_resource, full_name:)
|
2022-09-14 03:42:12 +02:00
|
|
|
referenced_type = case livecheck_package_or_resource
|
2021-07-19 11:21:29 -04:00
|
|
|
when Formula
|
|
|
|
:formula
|
|
|
|
when Cask::Cask
|
|
|
|
:cask
|
2022-09-14 03:42:12 +02:00
|
|
|
when Resource
|
|
|
|
:resource
|
2021-07-19 11:21:29 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
if skip_info[:status] != "error" &&
|
2022-09-14 03:42:12 +02:00
|
|
|
!(skip_info[:status] == "skipped" && livecheck_package_or_resource.livecheck.skip?)
|
2021-07-19 11:21:29 -04:00
|
|
|
error_msg_end = if skip_info[:status] == "skipped"
|
|
|
|
"automatically skipped"
|
|
|
|
else
|
|
|
|
"skipped as #{skip_info[:status]}"
|
|
|
|
end
|
|
|
|
|
|
|
|
raise "Referenced #{referenced_type} (#{referenced_name}) is #{error_msg_end}"
|
|
|
|
end
|
|
|
|
|
2022-09-14 03:42:12 +02:00
|
|
|
skip_info[referenced_type] = original_package_or_resource_name
|
2021-07-19 11:21:29 -04:00
|
|
|
skip_info
|
|
|
|
end
|
|
|
|
|
2021-01-07 15:30:22 -05:00
|
|
|
# Prints default livecheck output in relation to skip conditions.
|
|
|
|
sig { params(skip_hash: Hash).void }
|
|
|
|
def print_skip_information(skip_hash)
|
|
|
|
return unless skip_hash.is_a?(Hash)
|
|
|
|
|
|
|
|
name = if skip_hash[:formula].is_a?(String)
|
|
|
|
skip_hash[:formula]
|
|
|
|
elsif skip_hash[:cask].is_a?(String)
|
|
|
|
skip_hash[:cask]
|
2022-09-14 03:42:12 +02:00
|
|
|
elsif skip_hash[:resource].is_a?(String)
|
2022-09-14 04:54:52 +02:00
|
|
|
" #{skip_hash[:resource]}"
|
2021-01-07 15:30:22 -05:00
|
|
|
end
|
|
|
|
return unless name
|
|
|
|
|
|
|
|
if skip_hash[:messages].is_a?(Array) && skip_hash[:messages].count.positive?
|
|
|
|
# TODO: Handle multiple messages, only if needed in the future
|
|
|
|
if skip_hash[:status] == "skipped"
|
2022-04-26 20:44:43 +03:00
|
|
|
puts "#{Tty.red}#{name}#{Tty.reset}: skipped - #{skip_hash[:messages][0]}"
|
2021-01-07 15:30:22 -05:00
|
|
|
else
|
2022-04-26 20:44:43 +03:00
|
|
|
puts "#{Tty.red}#{name}#{Tty.reset}: #{skip_hash[:messages][0]}"
|
2021-01-07 15:30:22 -05:00
|
|
|
end
|
|
|
|
elsif skip_hash[:status].present?
|
2022-04-26 20:44:43 +03:00
|
|
|
puts "#{Tty.red}#{name}#{Tty.reset}: #{skip_hash[:status]}"
|
2021-01-07 15:30:22 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|