Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type livecheck.rb. #15279

Merged
merged 1 commit into from May 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Library/Homebrew/cask/dsl.rb
Expand Up @@ -327,7 +327,7 @@ def auto_updates(auto_updates = nil)

# @api public
def livecheck(&block)
@livecheck ||= Livecheck.new(self)
@livecheck ||= Livecheck.new(cask)
return @livecheck unless block

if !@cask.allow_reassignment && @livecheckable
Expand Down
95 changes: 54 additions & 41 deletions Library/Homebrew/livecheck.rb
Expand Up @@ -16,9 +16,10 @@ class Livecheck

# A very brief description of why the formula/cask/resource is skipped (e.g.
# `No longer developed or maintained`).
# @return [String, nil]
sig { returns(T.nilable(String)) }
attr_reader :skip_msg

sig { params(package_or_resource: T.any(Cask::Cask, T.class_of(Formula), Resource)).void }
def initialize(package_or_resource)
@package_or_resource = package_or_resource
@referenced_cask_name = nil
Expand All @@ -27,58 +28,62 @@ def initialize(package_or_resource)
@skip = false
@skip_msg = nil
@strategy = nil
@strategy_block = nil
@url = nil
end

# Sets the `@referenced_cask_name` instance variable to the provided `String`
# or returns the `@referenced_cask_name` instance variable when no argument
# is provided. Inherited livecheck values from the referenced cask
# (e.g. regex) can be overridden in the livecheck block.
#
# @param cask_name [String] name of cask to inherit livecheck info from
# @return [String, nil]
def cask(cask_name = nil)
sig {
params(
# Name of cask to inherit livecheck info from.
cask_name: String,
).returns(T.nilable(String))
}
def cask(cask_name = T.unsafe(nil))
case cask_name
when nil
@referenced_cask_name
when String
@referenced_cask_name = cask_name
else
raise TypeError, "Livecheck#cask expects a String"
end
end

# Sets the `@referenced_formula_name` instance variable to the provided
# `String` or returns the `@referenced_formula_name` instance variable when
# no argument is provided. Inherited livecheck values from the referenced
# formula (e.g. regex) can be overridden in the livecheck block.
#
# @param formula_name [String] name of formula to inherit livecheck info from
# @return [String, nil]
def formula(formula_name = nil)
sig {
params(
# Name of formula to inherit livecheck info from.
formula_name: String,
).returns(T.nilable(String))
}
def formula(formula_name = T.unsafe(nil))
case formula_name
when nil
@referenced_formula_name
when String
@referenced_formula_name = formula_name
else
raise TypeError, "Livecheck#formula expects a String"
end
end

# Sets the `@regex` instance variable to the provided `Regexp` or returns the
# `@regex` instance variable when no argument is provided.
#
# @param pattern [Regexp] regex to use for matching versions in content
# @return [Regexp, nil]
def regex(pattern = nil)
sig {
params(
# Regex to use for matching versions in content.
pattern: Regexp,
).returns(T.nilable(Regexp))
}
def regex(pattern = T.unsafe(nil))
case pattern
when nil
@regex
when Regexp
@regex = pattern
else
raise TypeError, "Livecheck#regex expects a Regexp"
end
end

Expand All @@ -87,20 +92,20 @@ def regex(pattern = nil)
# that the formula/cask/resource should be skipped and the `skip_msg` very
# briefly describes why it is skipped (e.g. "No longer developed or
# maintained").
#
# @param skip_msg [String] string describing why the formula/cask is skipped
# @return [Boolean]
def skip(skip_msg = nil)
if skip_msg.is_a?(String)
@skip_msg = skip_msg
elsif skip_msg.present?
raise TypeError, "Livecheck#skip expects a String"
end
sig {
params(
# String describing why the formula/cask is skipped.
skip_msg: String,
).returns(T::Boolean)
}
def skip(skip_msg = T.unsafe(nil))
@skip_msg = skip_msg if skip_msg.is_a?(String)

@skip = true
end

# Should `livecheck` skip this formula/cask/resource?
sig { returns(T::Boolean) }
def skip?
@skip
end
Expand All @@ -109,38 +114,45 @@ def skip?
# the `@strategy` instance variable when no argument is provided. The strategy
# symbols use snake case (e.g. `:page_match`) and correspond to the strategy
# file name.
#
# @param symbol [Symbol] symbol for the desired strategy
# @return [Symbol, nil]
def strategy(symbol = nil, &block)
sig {
params(
# Symbol for the desired strategy.
symbol: Symbol,
block: T.nilable(Proc),
).returns(T.nilable(Symbol))
}
def strategy(symbol = T.unsafe(nil), &block)
@strategy_block = block if block

case symbol
when nil
@strategy
when Symbol
@strategy = symbol
else
raise TypeError, "Livecheck#strategy expects a Symbol"
end
end

sig { returns(T.nilable(Proc)) }
attr_reader :strategy_block

# Sets the `@url` instance variable to the provided argument or returns the
# `@url` instance variable when no argument is provided. The argument can be
# a `String` (a URL) or a supported `Symbol` corresponding to a URL in the
# formula/cask/resource (e.g. `:stable`, `:homepage`, `:head`, `:url`).
# @param val [String, Symbol] URL to check for version information
# @return [String, nil]
def url(val = nil)
case val
sig {
params(
# URL to check for version information.
url: T.any(String, Symbol),
).returns(T.nilable(T.any(String, Symbol)))
}
def url(url = T.unsafe(nil))
case url
when nil
@url
when String, :head, :homepage, :stable, :url
@url = val
else
raise TypeError, "Livecheck#url expects a String or valid Symbol"
@url = url
when Symbol
reitermarkus marked this conversation as resolved.
Show resolved Hide resolved
raise ArgumentError, "#{url.inspect} is not a valid URL shorthand"
end
end

Expand All @@ -150,6 +162,7 @@ def url(val = nil)

# Returns a `Hash` of all instance variable values.
# @return [Hash]
sig { returns(T::Hash[String, T.untyped]) }
def to_hash
{
"cask" => @referenced_cask_name,
Expand Down
34 changes: 5 additions & 29 deletions Library/Homebrew/test/livecheck_spec.rb
Expand Up @@ -11,7 +11,7 @@
head "https://github.com/Homebrew/brew.git"
end
end
let(:livecheckable_f) { described_class.new(f) }
let(:livecheckable_f) { described_class.new(f.class) }

let(:c) do
Cask::CaskLoader.load(+<<-RUBY)
Expand Down Expand Up @@ -40,7 +40,7 @@
it "raises a TypeError if the argument isn't a String" do
expect do
livecheckable_f.formula(123)
end.to raise_error(TypeError, "Livecheck#formula expects a String")
end.to raise_error TypeError
end
end

Expand All @@ -53,12 +53,6 @@
livecheckable_c.cask("other-cask")
expect(livecheckable_c.cask).to eq("other-cask")
end

it "raises a TypeError if the argument isn't a String" do
expect do
livecheckable_c.cask(123)
end.to raise_error(TypeError, "Livecheck#cask expects a String")
end
end

describe "#regex" do
Expand All @@ -70,12 +64,6 @@
livecheckable_f.regex(/foo/)
expect(livecheckable_f.regex).to eq(/foo/)
end

it "raises a TypeError if the argument isn't a Regexp" do
expect do
livecheckable_f.regex("foo")
end.to raise_error(TypeError, "Livecheck#regex expects a Regexp")
end
end

describe "#skip" do
Expand All @@ -90,12 +78,6 @@
expect(livecheckable_f.instance_variable_get(:@skip)).to be true
expect(livecheckable_f.instance_variable_get(:@skip_msg)).to eq("foo")
end

it "raises a TypeError if the argument isn't a String" do
expect do
livecheckable_f.skip(/foo/)
end.to raise_error(TypeError, "Livecheck#skip expects a String")
end
end

describe "#skip?" do
Expand All @@ -116,12 +98,6 @@
livecheckable_f.strategy(:page_match)
expect(livecheckable_f.strategy).to eq(:page_match)
end

it "raises a TypeError if the argument isn't a Symbol" do
expect do
livecheckable_f.strategy("page_match")
end.to raise_error(TypeError, "Livecheck#strategy expects a Symbol")
end
end

describe "#url" do
Expand Down Expand Up @@ -150,10 +126,10 @@
expect(livecheckable_c.url).to eq(:url)
end

it "raises a TypeError if the argument isn't a String or valid Symbol" do
it "raises an ArgumentError if the argument isn't a valid Symbol" do
expect do
livecheckable_f.url(/foo/)
end.to raise_error(TypeError, "Livecheck#url expects a String or valid Symbol")
livecheckable_f.url(:not_a_valid_symbol)
end.to raise_error ArgumentError
end
end

Expand Down