Skip to content

Commit

Permalink
livecheck: clarify livecheckable language
Browse files Browse the repository at this point in the history
Formulae, casks, and resources have a `#livecheckable?` method that
indicates whether they contain a `livecheck` block. This is intended
to be read as "has a livecheckable?", not "is livecheckable?".
Unfortunately, correct understanding of this method's behavior relies
on historical knowledge that few people possess, so this is often
confusing to anyone who hasn't been working on livecheck since 2020.

In the olden days, a "livecheckable" was a Ruby file containing a
`livecheck` block (originally a hash) with a filename that
corresponded to a related formula. The `livecheck` blocks in
livecheckable files were integrated into their respective formulae in
August 2020, so [first-party] livecheckables ceased to exist at that
time. From that point forward, we simply referred to these as
`livecheck` blocks.

With that in mind, this clarifies the situation by replacing
"livecheckable" language with "livecheck block". This includes
renaming `#livecheckable?` to `#livecheck_block?`, replacing usage of
"livecheckable" as a noun with "`livecheck` block", and replacing
incorrect usage of "livecheckable" as an adjective with "checkable".
  • Loading branch information
samford committed Nov 27, 2024
1 parent f2719dc commit 8c680ac
Show file tree
Hide file tree
Showing 15 changed files with 258 additions and 190 deletions.
8 changes: 4 additions & 4 deletions Library/Homebrew/cask/audit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def audit_sha256_invalid
sig { void }
def audit_latest_with_livecheck
return unless cask.version&.latest?
return unless cask.livecheckable?
return unless cask.livecheck_block?
return if cask.livecheck.skip?

add_error "Casks with a `livecheck` should not use `version :latest`."
Expand All @@ -299,7 +299,7 @@ def audit_hosting_with_livecheck(livecheck_result: audit_livecheck_version)
return if cask.version&.latest?
return if (url = cask.url).nil?
return if block_url_offline?
return if cask.livecheckable?
return if cask.livecheck_block?
return if livecheck_result == :auto_detected

add_livecheck = "please add a livecheck. See #{Formatter.url(LIVECHECK_REFERENCE_URL)}"
Expand Down Expand Up @@ -693,7 +693,7 @@ def audit_min_os
sig { returns(T.nilable(MacOSVersion)) }
def livecheck_min_os
return unless online?
return unless cask.livecheckable?
return unless cask.livecheck_block?
return if cask.livecheck.strategy != :sparkle

# `Sparkle` strategy blocks that use the `items` argument (instead of
Expand Down Expand Up @@ -924,7 +924,7 @@ def audit_url_https_availability
sig { void }
def audit_livecheck_https_availability
return unless online?
return unless cask.livecheckable?
return unless cask.livecheck_block?
return unless (url = cask.livecheck.url)
return if url.is_a?(Symbol)

Expand Down
2 changes: 2 additions & 0 deletions Library/Homebrew/cask/cask.rbi
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ module Cask

def livecheck; end

def livecheck_block?; end

def livecheckable?; end

def name; end
Expand Down
17 changes: 13 additions & 4 deletions Library/Homebrew/cask/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ class DSL
:disable_replacement,
:discontinued?, # TODO: remove once discontinued? is removed (4.5.0)
:livecheck,
:livecheckable?,
:livecheck_block?,
:livecheckable?, # TODO: remove once `#livecheckable?` is removed
:on_system_blocks_exist?,
:on_system_block_min_os,
:depends_on_set_in_block?,
Expand All @@ -110,7 +111,7 @@ class DSL
attr_reader :cask, :token, :deprecation_date, :deprecation_reason, :deprecation_replacement, :disable_date,
:disable_reason, :disable_replacement, :on_system_block_min_os

attr_predicate :deprecated?, :disabled?, :livecheckable?, :on_system_blocks_exist?, :depends_on_set_in_block?
attr_predicate :deprecated?, :disabled?, :livecheck_block?, :on_system_blocks_exist?, :depends_on_set_in_block?

def initialize(cask)
@cask = cask
Expand Down Expand Up @@ -431,14 +432,22 @@ def livecheck(&block)
@livecheck ||= Livecheck.new(cask)
return @livecheck unless block

if !@cask.allow_reassignment && @livecheckable
if !@cask.allow_reassignment && @livecheck_block
raise CaskInvalidError.new(cask, "'livecheck' stanza may only appear once.")
end

@livecheckable = true
@livecheck_block = true
@livecheck.instance_eval(&block)
end

# Whether the cask contains a `livecheck` block. This is a legacy alias
# for `#livecheck_block?`.
sig { returns(T::Boolean) }
def livecheckable?
odeprecated "`livecheckable?`", "`livecheck_block?`"
@livecheck_block == true
end

# Declare that a cask is no longer functional or supported.
#
# NOTE: A warning will be shown when trying to install this cask.
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/dev-cmd/bump-unversioned-casks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def run
casks = args.named.to_paths(only: :cask, recurse_tap: true).map { |path| Cask::CaskLoader.load(path) }

unversioned_casks = casks.select do |cask|
cask.url&.unversioned? && !cask.livecheckable?
cask.url&.unversioned? && !cask.livecheck_block?
end

ohai "Unversioned Casks: #{unversioned_casks.count} (#{state.size} cached)"
Expand Down
8 changes: 4 additions & 4 deletions Library/Homebrew/dev-cmd/bump.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def run
def skip_repology?(formula_or_cask)
return true unless args.repology?

(ENV["CI"].present? && args.open_pr? && formula_or_cask.livecheckable?) ||
(ENV["CI"].present? && args.open_pr? && formula_or_cask.livecheck_block?) ||
(formula_or_cask.is_a?(Formula) && formula_or_cask.versioned_formula?)
end

Expand Down Expand Up @@ -329,7 +329,7 @@ def retrieve_versions_by_arch(formula_or_cask:, repositories:, name:)
"skipped"
elsif repology_latest.is_a?(Version) &&
repology_latest > current_version_value &&
!loaded_formula_or_cask.livecheckable? &&
!loaded_formula_or_cask.livecheck_block? &&
current_version_value != "latest"
repology_latest
end.presence
Expand Down Expand Up @@ -490,8 +490,8 @@ def retrieve_and_display_info_and_open_pr(formula_or_cask, name, repositories, a
if repology_latest.is_a?(Version) &&
repology_latest > current_version.general &&
repology_latest > new_version.general &&
formula_or_cask.livecheckable?
puts "#{title_name} was not bumped to the Repology version because it's livecheckable."
formula_or_cask.livecheck_block?
puts "#{title_name} was not bumped to the Repology version because it has a `livecheck` block."
end
if new_version.blank? || versions_equal ||
(!new_version.general.is_a?(Version) && !version_info.multiple_versions)
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/dev-cmd/irb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def run
:mpd.f.recursive_dependencies.reject(&:installed?)
'vlc'.c # => instance of the vlc cask
:tsh.c.livecheckable?
:tsh.c.livecheck_block?
EOS
return
end
Expand Down
20 changes: 18 additions & 2 deletions Library/Homebrew/formula.rb
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,11 @@ def bottle_for_tag(tag = nil)
# @see .livecheck=
delegate livecheck: :"self.class"

# Is a livecheck specification defined for the software?
# @!method livecheck_block?
# @see .livecheck_block?
delegate livecheck_block?: :"self.class"

# Is a livecheck specification defined for the software?
# @!method livecheckable?
# @see .livecheckable?
Expand Down Expand Up @@ -3537,8 +3542,19 @@ def network_access_allowed?(phase)
# It returns `true` when a `livecheck` block is present in the {Formula}
# and `false` otherwise.
sig { returns(T::Boolean) }
def livecheck_block?
@livecheck_block == true
end

# Checks whether a `livecheck` specification is defined or not. This is a
# legacy alias for `#livecheck_block?`.
#
# It returns `true` when a `livecheck` block is present in the {Formula}
# and `false` otherwise.
sig { returns(T::Boolean) }
def livecheckable?
@livecheckable == true
odeprecated "`livecheckable?`", "`livecheck_block?`"
@livecheck_block == true
end

# Checks whether a service specification is defined or not.
Expand Down Expand Up @@ -4183,7 +4199,7 @@ def test(&block)
def livecheck(&block)
return @livecheck unless block

@livecheckable = true
@livecheck_block = true
@livecheck.instance_eval(&block)
end

Expand Down
29 changes: 19 additions & 10 deletions Library/Homebrew/livecheck/livecheck.rb
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,9 @@ def self.run_checks(
newer_than_upstream: is_newer_than_upstream,
}.compact
info[:meta] = {
livecheckable: formula_or_cask.livecheckable?,
has_livecheck_block: formula_or_cask.livecheck_block?,
# TODO: Remove `livecheckable` field after aliases are removed
livecheckable: formula_or_cask.livecheck_block?,
}
info[:meta][:head_only] = true if formula&.head_only?
info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta)
Expand Down Expand Up @@ -465,7 +467,9 @@ def self.status_hash(package_or_resource, status_str, messages = nil, full_name:
status_hash[:messages] = messages if messages.is_a?(Array)

status_hash[:meta] = {
livecheckable: package_or_resource.livecheckable?,
has_livecheck_block: package_or_resource.livecheck_block?,
# TODO: Remove `livecheckable` field after aliases are removed
livecheckable: package_or_resource.livecheck_block?,
}
status_hash[:meta][:head_only] = true if formula&.head_only?

Expand All @@ -478,7 +482,7 @@ def self.status_hash(package_or_resource, status_str, messages = nil, full_name:
package_or_resource_s = info[:resource].present? ? " " : ""
package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}"
package_or_resource_s += " (cask)" if ambiguous_cask
package_or_resource_s += " (guessed)" if verbose && !info[:meta][:livecheckable]
package_or_resource_s += " (guessed)" if verbose && !info[:meta][:livecheck_block]

current_s = if info[:version][:newer_than_upstream]
"#{Tty.red}#{info[:version][:current]}#{Tty.reset}"
Expand Down Expand Up @@ -608,7 +612,7 @@ def self.latest_version(
formula = formula_or_cask if formula_or_cask.is_a?(Formula)
cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask)

has_livecheckable = formula_or_cask.livecheckable?
has_livecheck_block = formula_or_cask.livecheck_block?
livecheck = formula_or_cask.livecheck
referenced_livecheck = referenced_formula_or_cask&.livecheck

Expand All @@ -632,7 +636,7 @@ def self.latest_version(
elsif cask
puts "Cask: #{cask_name(formula_or_cask, full_name:)}"
end
puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}"
puts "livecheck block?: #{has_livecheck_block ? "Yes" : "No"}"
puts "Throttle: #{livecheck_throttle}" if livecheck_throttle

livecheck_references.each do |ref_formula_or_cask|
Expand Down Expand Up @@ -736,7 +740,7 @@ def self.latest_version(

match_version_map.delete_if do |_match, version|
next true if version.blank?
next false if has_livecheckable
next false if has_livecheck_block

UNSTABLE_VERSION_KEYWORDS.any? do |rejection|
version.to_s.include?(rejection)
Expand Down Expand Up @@ -839,12 +843,12 @@ def self.resource_version(
quiet: false,
verbose: false
)
has_livecheckable = resource.livecheckable?
has_livecheck_block = resource.livecheck_block?

if debug
puts "\n\n"
puts "Resource: #{resource.name}"
puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}"
puts "livecheck block?: #{has_livecheck_block ? "Yes" : "No"}"
end

resource_version_info = {}
Expand Down Expand Up @@ -939,7 +943,7 @@ def self.resource_version(

match_version_map.delete_if do |_match, version|
next true if version.blank?
next false if has_livecheckable
next false if has_livecheck_block

UNSTABLE_VERSION_KEYWORDS.any? do |rejection|
version.to_s.include?(rejection)
Expand Down Expand Up @@ -978,7 +982,12 @@ def self.resource_version(
},
}

resource_version_info[:meta] = { livecheckable: has_livecheckable, url: {} }
resource_version_info[:meta] = {
has_livecheck_block: has_livecheck_block,
# TODO: Remove `livecheckable` field after aliases are removed
livecheckable: has_livecheck_block,
url: {},
}
if livecheck_url.is_a?(Symbol) && livecheck_url_string
resource_version_info[:meta][:url][:symbol] = livecheck_url
end
Expand Down
Loading

0 comments on commit 8c680ac

Please sign in to comment.