Handle variable strategy block arguments

There are times where a regex isn't needed in a `strategy` block and
these changes explicitly handle that situation.

This allows the Symbol Proc format used in some `Sparkle` `livecheck`
blocks (e.g., `strategy :sparkle, &:version`) to continue working
instead of failing with a "wrong number of arguments (given 1,
expected 0)" error. This error would occur because a Symbol Proc only
only expects one argument (e.g., an `Item`, not an `Item` and a
regex/nil).

There's an argument to be made for avoiding the Symbol Proc format
for `strategy` blocks but I haven't found a way of selectively
disabling the Style/SymbolProc cop only for a `strategy` DSL method
call. That is to say, if we don't use the Symbol Proc format, `brew
style` will give a "Pass &:version as an argument to strategy instead
of a block." offense.

Besides that, this also replaces the `block` type signatures in
livecheck strategies with `T.untyped`. Sorbet doesn't know how to
handle a `Proc` with a variable number of arguments and can't be
taught how (i.e., `T.any` with a `Proc` signature for each variation
doesn't work). The aforementioned changes cause Sorbet to complain
about there being both too many and too few arguments, so the only
way to win is not to play the game. Hopefully we can restore the
`block` type signatures in the future (if upstream resolves this
years-old issue) but `T.untyped` seems to be our only option for now.
This commit is contained in:
Sam Ford 2021-11-19 22:42:15 -05:00
parent e73524b093
commit 085827f605
No known key found for this signature in database
GPG Key ID: 95209E46C7FFDEFE
18 changed files with 55 additions and 95 deletions

View File

@ -93,9 +93,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
unused: T.nilable(T::Hash[Symbol, T.untyped]), unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: Regexp).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **unused, &block) def self.find_versions(url:, regex: nil, **unused, &block)

View File

@ -96,9 +96,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
unused: T.nilable(T::Hash[Symbol, T.untyped]), unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: Regexp).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **unused, &block) def self.find_versions(url:, regex: nil, **unused, &block)

View File

@ -80,9 +80,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
unused: T.nilable(T::Hash[Symbol, T.untyped]), unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: Regexp).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **unused, &block) def self.find_versions(url:, regex: nil, **unused, &block)

View File

@ -40,12 +40,7 @@ module Homebrew
params( params(
content: String, content: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
block: T.nilable( block: T.untyped,
T.proc.params(
arg0: T::Hash[String, T.untyped],
arg1: T.nilable(Regexp),
).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Array[String]) ).returns(T::Array[String])
} }
def self.versions_from_content(content, regex = nil, &block) def self.versions_from_content(content, regex = nil, &block)
@ -54,7 +49,10 @@ module Homebrew
yaml = YAML.safe_load(content) yaml = YAML.safe_load(content)
return [] if yaml.blank? return [] if yaml.blank?
return Strategy.handle_block_return(yield(yaml, regex)) if block if block
block_return_value = regex.present? ? yield(yaml, regex) : yield(yaml)
return Strategy.handle_block_return(block_return_value)
end
version = yaml["version"] version = yaml["version"]
version.present? ? [version] : [] version.present? ? [version] : []
@ -69,12 +67,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
_unused: T.nilable(T::Hash[Symbol, T.untyped]), _unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(
arg0: T::Hash[String, T.untyped],
arg1: T.nilable(Regexp),
).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **_unused, &block) def self.find_versions(url:, regex: nil, **_unused, &block)

View File

@ -63,16 +63,14 @@ module Homebrew
params( params(
items: T::Hash[String, Item], items: T::Hash[String, Item],
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
block: T.nilable( block: T.untyped,
T.proc.params(
arg0: T::Hash[String, Item],
arg1: T.nilable(Regexp),
).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Array[String]) ).returns(T::Array[String])
} }
def self.versions_from_items(items, regex = nil, &block) def self.versions_from_items(items, regex = nil, &block)
return Strategy.handle_block_return(yield(items, regex)) if block if block
block_return_value = regex.present? ? yield(items, regex) : yield(items)
return Strategy.handle_block_return(block_return_value)
end
items.map do |_key, item| items.map do |_key, item|
item.bundle_version.nice_version item.bundle_version.nice_version
@ -89,12 +87,7 @@ module Homebrew
cask: Cask::Cask, cask: Cask::Cask,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
_unused: T.nilable(T::Hash[Symbol, T.untyped]), _unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(
arg0: T::Hash[String, Item],
arg1: T.nilable(Regexp),
).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(cask:, regex: nil, **_unused, &block) def self.find_versions(cask:, regex: nil, **_unused, &block)

View File

@ -86,14 +86,20 @@ module Homebrew
params( params(
tags: T::Array[String], tags: T::Array[String],
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: T::Array[String], arg1: T.nilable(Regexp))
.returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Array[String]) ).returns(T::Array[String])
} }
def self.versions_from_tags(tags, regex = nil, &block) def self.versions_from_tags(tags, regex = nil, &block)
return Strategy.handle_block_return(yield(tags, regex || DEFAULT_REGEX)) if block if block
block_return_value = if regex.present?
yield(tags, regex)
elsif block.arity == 2
yield(tags, DEFAULT_REGEX)
else
yield(tags)
end
return Strategy.handle_block_return(block_return_value)
end
tags_only_debian = tags.all? { |tag| tag.start_with?("debian/") } tags_only_debian = tags.all? { |tag| tag.start_with?("debian/") }
@ -125,10 +131,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
_unused: T.nilable(T::Hash[Symbol, T.untyped]), _unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: T::Array[String], arg1: T.nilable(Regexp))
.returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **_unused, &block) def self.find_versions(url:, regex: nil, **_unused, &block)

View File

@ -92,9 +92,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
unused: T.nilable(T::Hash[Symbol, T.untyped]), unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: Regexp).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **unused, &block) def self.find_versions(url:, regex: nil, **unused, &block)

View File

@ -82,9 +82,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
unused: T.nilable(T::Hash[Symbol, T.untyped]), unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: Regexp).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **unused, &block) def self.find_versions(url:, regex: nil, **unused, &block)

View File

@ -92,9 +92,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
unused: T.nilable(T::Hash[Symbol, T.untyped]), unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: Regexp).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **unused, &block) def self.find_versions(url:, regex: nil, **unused, &block)

View File

@ -78,9 +78,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
unused: T.nilable(T::Hash[Symbol, T.untyped]), unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: Regexp).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **unused, &block) def self.find_versions(url:, regex: nil, **unused, &block)

View File

@ -44,16 +44,14 @@ module Homebrew
params( params(
headers: T::Hash[String, String], headers: T::Hash[String, String],
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
block: T.nilable( block: T.untyped,
T.proc.params(
arg0: T::Hash[String, String],
arg1: T.nilable(Regexp),
).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Array[String]) ).returns(T::Array[String])
} }
def self.versions_from_headers(headers, regex = nil, &block) def self.versions_from_headers(headers, regex = nil, &block)
return Strategy.handle_block_return(yield(headers, regex)) if block if block
block_return_value = regex.present? ? yield(headers, regex) : yield(headers)
return Strategy.handle_block_return(block_return_value)
end
DEFAULT_HEADERS_TO_CHECK.map do |header_name| DEFAULT_HEADERS_TO_CHECK.map do |header_name|
header_value = headers[header_name] header_value = headers[header_name]
@ -79,9 +77,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
_unused: T.nilable(T::Hash[Symbol, T.untyped]), _unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: T::Hash[String, String], arg1: T.nilable(Regexp)).returns(T.nilable(String)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **_unused, &block) def self.find_versions(url:, regex: nil, **_unused, &block)

View File

@ -75,9 +75,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
unused: T.nilable(T::Hash[Symbol, T.untyped]), unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: Regexp).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **unused, &block) def self.find_versions(url:, regex: nil, **unused, &block)

View File

@ -73,9 +73,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
unused: T.nilable(T::Hash[Symbol, T.untyped]), unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: Regexp).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **unused, &block) def self.find_versions(url:, regex: nil, **unused, &block)

View File

@ -51,13 +51,15 @@ module Homebrew
params( params(
content: String, content: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: T.nilable(Regexp)).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Array[String]) ).returns(T::Array[String])
} }
def self.versions_from_content(content, regex, &block) def self.versions_from_content(content, regex, &block)
return Strategy.handle_block_return(yield(content, regex)) if block if block
block_return_value = regex.present? ? yield(content, regex) : yield(content)
return Strategy.handle_block_return(block_return_value)
end
return [] if regex.blank? return [] if regex.blank?
content.scan(regex).map do |match| content.scan(regex).map do |match|
@ -84,9 +86,7 @@ module Homebrew
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
provided_content: T.nilable(String), provided_content: T.nilable(String),
_unused: T.nilable(T::Hash[Symbol, T.untyped]), _unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: T.nilable(Regexp)).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, provided_content: nil, **_unused, &block) def self.find_versions(url:, regex: nil, provided_content: nil, **_unused, &block)

View File

@ -87,9 +87,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
unused: T.nilable(T::Hash[Symbol, T.untyped]), unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: Regexp).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **unused, &block) def self.find_versions(url:, regex: nil, **unused, &block)

View File

@ -92,9 +92,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
unused: T.nilable(T::Hash[Symbol, T.untyped]), unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: Regexp).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **unused, &block) def self.find_versions(url:, regex: nil, **unused, &block)

View File

@ -151,16 +151,17 @@ module Homebrew
params( params(
content: String, content: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: Item, arg1: T.nilable(Regexp)).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Array[String]) ).returns(T::Array[String])
} }
def self.versions_from_content(content, regex = nil, &block) def self.versions_from_content(content, regex = nil, &block)
item = item_from_content(content) item = item_from_content(content)
return [] if item.blank? return [] if item.blank?
return Strategy.handle_block_return(yield(item, regex)) if block if block
block_return_value = regex.present? ? yield(item, regex) : yield(item)
return Strategy.handle_block_return(block_return_value)
end
version = item.bundle_version&.nice_version version = item.bundle_version&.nice_version
version.present? ? [version] : [] version.present? ? [version] : []
@ -172,9 +173,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
_unused: T.nilable(T::Hash[Symbol, T.untyped]), _unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: Item, arg1: T.nilable(Regexp)).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **_unused, &block) def self.find_versions(url:, regex: nil, **_unused, &block)

View File

@ -114,9 +114,7 @@ module Homebrew
url: String, url: String,
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
unused: T.nilable(T::Hash[Symbol, T.untyped]), unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.nilable( block: T.untyped,
T.proc.params(arg0: String, arg1: Regexp).returns(T.any(String, T::Array[String], NilClass)),
),
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(url:, regex: nil, **unused, &block) def self.find_versions(url:, regex: nil, **unused, &block)