mirror of
https://github.com/Homebrew/brew.git
synced 2026-10-28 09:34:42 +08:00
Merge pull request #21494 from Homebrew/livecheck/extract_plist-add-content-parameter-expand-tests
ExtractPlist: add content parameter
This commit is contained in:
4 files changed
+110
-30
No files matched your search
@@ -116,5 +116,13 @@ module Homebrew
|
||||
[short_version, version].compact
|
||||
end
|
||||
private :nice_parts
|
||||
|
||||
sig { returns(T::Hash[Symbol, String]) }
|
||||
def to_h
|
||||
{
|
||||
short_version:,
|
||||
version:,
|
||||
}.compact
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -27,15 +27,6 @@ module Homebrew
|
||||
# The `Regexp` used to determine if the strategy applies to the URL.
|
||||
URL_MATCH_REGEX = %r{^https?://}i
|
||||
|
||||
# Whether the strategy can be applied to the provided URL.
|
||||
#
|
||||
# @param url [String] the URL to match against
|
||||
# @return [Boolean]
|
||||
sig { override.params(url: String).returns(T::Boolean) }
|
||||
def self.match?(url)
|
||||
URL_MATCH_REGEX.match?(url)
|
||||
end
|
||||
|
||||
Item = Struct.new(
|
||||
:bundle_version,
|
||||
keyword_init: true,
|
||||
@@ -49,6 +40,22 @@ module Homebrew
|
||||
# @!attribute [r] short_version
|
||||
# @api public
|
||||
delegate short_version: :bundle_version
|
||||
|
||||
sig { returns(T::Hash[Symbol, T::Hash[Symbol, String]]) }
|
||||
def to_h
|
||||
{
|
||||
bundle_version: bundle_version&.to_h,
|
||||
}.compact
|
||||
end
|
||||
end
|
||||
|
||||
# Whether the strategy can be applied to the provided URL.
|
||||
#
|
||||
# @param url [String] the URL to match against
|
||||
# @return [Boolean]
|
||||
sig { override.params(url: String).returns(T::Boolean) }
|
||||
def self.match?(url)
|
||||
URL_MATCH_REGEX.match?(url)
|
||||
end
|
||||
|
||||
# Identify versions from `Item`s produced using
|
||||
@@ -64,7 +71,7 @@ module Homebrew
|
||||
block: T.nilable(Proc),
|
||||
).returns(T::Array[String])
|
||||
}
|
||||
def self.versions_from_items(items, regex = nil, &block)
|
||||
def self.versions_from_content(items, regex = nil, &block)
|
||||
if block
|
||||
block_return_value = regex.present? ? yield(items, regex) : yield(items)
|
||||
return Strategy.handle_block_return(block_return_value)
|
||||
@@ -134,6 +141,7 @@ module Homebrew
|
||||
# @param cask [Cask::Cask] the cask to check for version information
|
||||
# @param url [String, nil] an alternative URL to check for version
|
||||
# information
|
||||
# @param content [String, nil] content to check instead of fetching
|
||||
# @param regex [Regexp, nil] a regex for use in a strategy block
|
||||
# @param options [Options] options to modify behavior
|
||||
# @return [Hash]
|
||||
@@ -142,30 +150,43 @@ module Homebrew
|
||||
cask: Cask::Cask,
|
||||
url: T.nilable(String),
|
||||
regex: T.nilable(Regexp),
|
||||
content: T.nilable(String),
|
||||
options: Options,
|
||||
block: T.nilable(Proc),
|
||||
).returns(T::Hash[Symbol, T.anything])
|
||||
}
|
||||
def self.find_versions(cask:, url: nil, regex: nil, options: Options.new, &block)
|
||||
def self.find_versions(cask:, url: nil, regex: nil, content: nil, options: Options.new, &block)
|
||||
if regex.present? && !block_given?
|
||||
raise ArgumentError,
|
||||
"#{Utils.demodulize(name)} only supports a regex when using a `strategy` block"
|
||||
end
|
||||
|
||||
match_data = { matches: {}, regex:, url: }
|
||||
match_data[:cached] = true if content
|
||||
|
||||
unversioned_cask_checker = if url.present? && url != cask.url.to_s
|
||||
UnversionedCaskChecker.new(cask_with_url(cask, url, options.url_options))
|
||||
if match_data[:cached]
|
||||
items = Json.parse_json(T.must(content)).transform_values do |obj|
|
||||
short_version = obj.dig("bundle_version", "short_version")
|
||||
version = obj.dig("bundle_version", "version")
|
||||
Item.new(bundle_version: BundleVersion.new(short_version, version))
|
||||
end
|
||||
else
|
||||
UnversionedCaskChecker.new(cask)
|
||||
unversioned_cask_checker = if url.present? && url != cask.url.to_s
|
||||
UnversionedCaskChecker.new(cask_with_url(cask, url, options.url_options))
|
||||
else
|
||||
UnversionedCaskChecker.new(cask)
|
||||
end
|
||||
|
||||
items = unversioned_cask_checker.all_versions.transform_values { |v| Item.new(bundle_version: v) }
|
||||
end
|
||||
return match_data if items.blank?
|
||||
|
||||
items = unversioned_cask_checker.all_versions.transform_values { |v| Item.new(bundle_version: v) }
|
||||
|
||||
versions_from_items(items, regex, &block).each do |version_text|
|
||||
versions_from_content(items, regex, &block).each do |version_text|
|
||||
match_data[:matches][version_text] = Version.new(version_text)
|
||||
end
|
||||
|
||||
require "json"
|
||||
match_data[:content] = JSON.generate(items.transform_values(&:to_h)) unless match_data[:cached]
|
||||
match_data
|
||||
end
|
||||
end
|
||||
|
||||
@@ -47,4 +47,15 @@ RSpec.describe Homebrew::BundleVersion do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_h" do
|
||||
it "returns a hash containing non-nil instance variables" do
|
||||
expect(described_class.new("1.2.3", "3000").to_h)
|
||||
.to eq({ short_version: "1.2.3", version: "3000" })
|
||||
expect(described_class.new(nil, "3000").to_h)
|
||||
.to eq({ version: "3000" })
|
||||
expect(described_class.new("1.2.3", nil).to_h)
|
||||
.to eq({ short_version: "1.2.3" })
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -35,6 +35,17 @@ RSpec.describe Homebrew::Livecheck::Strategy::ExtractPlist do
|
||||
let(:versions) { ["1.2", "1.2.3"] }
|
||||
let(:multipart_versions) { ["1.2.3,45", "1.2.3,45,abcdef"] }
|
||||
|
||||
describe "Item" do
|
||||
describe "#to_h" do
|
||||
it "returns a hash containing non-nil values" do
|
||||
expect(items["first"].to_h).to eq({
|
||||
bundle_version: { version: "1.2" },
|
||||
})
|
||||
expect(extract_plist::Item.new.to_h).to eq({})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "::match?" do
|
||||
it "returns true for an HTTP URL" do
|
||||
expect(extract_plist.match?(http_url)).to be true
|
||||
@@ -45,26 +56,26 @@ RSpec.describe Homebrew::Livecheck::Strategy::ExtractPlist do
|
||||
end
|
||||
end
|
||||
|
||||
describe "::versions_from_items" do
|
||||
describe "::versions_from_content" do
|
||||
it "returns an empty array if Items hash is empty" do
|
||||
expect(extract_plist.versions_from_items({})).to eq([])
|
||||
expect(extract_plist.versions_from_content({})).to eq([])
|
||||
end
|
||||
|
||||
it "returns an array of version strings when given Items" do
|
||||
expect(extract_plist.versions_from_items(items)).to eq(versions)
|
||||
expect(extract_plist.versions_from_content(items)).to eq(versions)
|
||||
end
|
||||
|
||||
it "returns an array of version strings when given Items and a block" do
|
||||
# Returning a string from block
|
||||
expect(
|
||||
extract_plist.versions_from_items(items) do |items|
|
||||
extract_plist.versions_from_content(items) do |items|
|
||||
items["first"].version
|
||||
end,
|
||||
).to eq(["1.2"])
|
||||
|
||||
# Returning an array of strings from block
|
||||
expect(
|
||||
extract_plist.versions_from_items(items) do |items|
|
||||
extract_plist.versions_from_content(items) do |items|
|
||||
items.map do |_key, item|
|
||||
item.bundle_version.nice_version
|
||||
end
|
||||
@@ -75,7 +86,7 @@ RSpec.describe Homebrew::Livecheck::Strategy::ExtractPlist do
|
||||
it "returns an array of version strings when given `Item`s, a regex and a block" do
|
||||
# Returning a string from block
|
||||
expect(
|
||||
extract_plist.versions_from_items(multipart_items, multipart_regex) do |items, regex|
|
||||
extract_plist.versions_from_content(multipart_items, multipart_regex) do |items, regex|
|
||||
match = items["first"].version.match(regex)
|
||||
next if match.blank?
|
||||
|
||||
@@ -85,7 +96,7 @@ RSpec.describe Homebrew::Livecheck::Strategy::ExtractPlist do
|
||||
|
||||
# Returning an array of strings from block
|
||||
expect(
|
||||
extract_plist.versions_from_items(multipart_items, multipart_regex) do |items, regex|
|
||||
extract_plist.versions_from_content(multipart_items, multipart_regex) do |items, regex|
|
||||
items.map do |_key, item|
|
||||
match = item.version.match(regex)
|
||||
next if match.blank?
|
||||
@@ -97,11 +108,11 @@ RSpec.describe Homebrew::Livecheck::Strategy::ExtractPlist do
|
||||
end
|
||||
|
||||
it "allows a nil return from a block" do
|
||||
expect(extract_plist.versions_from_items(items) { next }).to eq([])
|
||||
expect(extract_plist.versions_from_content(items) { next }).to eq([])
|
||||
end
|
||||
|
||||
it "errors on an invalid return type from a block" do
|
||||
expect { extract_plist.versions_from_items(items) { 123 } }
|
||||
expect { extract_plist.versions_from_content(items) { 123 } }
|
||||
.to raise_error(TypeError, Homebrew::Livecheck::Strategy::INVALID_BLOCK_RETURN_VALUE_MSG)
|
||||
end
|
||||
end
|
||||
@@ -160,7 +171,20 @@ RSpec.describe Homebrew::Livecheck::Strategy::ExtractPlist do
|
||||
|
||||
describe "::find_versions" do
|
||||
let(:cask) { Cask::CaskLoader.load(cask_path("livecheck/livecheck-extract-plist")) }
|
||||
let(:matches) { { "1.2.3" => Version.new("1.2.3") } }
|
||||
let(:content) { '{"com.caffeine":{"bundle_version":{"version":"1.2.3"}}}' }
|
||||
let(:match_data) do
|
||||
base = {
|
||||
matches: { "1.2.3" => Version.new("1.2.3") },
|
||||
regex: nil,
|
||||
url: nil,
|
||||
}
|
||||
|
||||
{
|
||||
uncached: base.merge({ content: }),
|
||||
cached: base.merge({ cached: true }),
|
||||
cached_default: base.merge({ matches: {}, cached: true }),
|
||||
}
|
||||
end
|
||||
|
||||
it "raises an error if a regex is provided with no block" do
|
||||
expect do
|
||||
@@ -168,24 +192,40 @@ RSpec.describe Homebrew::Livecheck::Strategy::ExtractPlist do
|
||||
end.to raise_error(ArgumentError, "ExtractPlist only supports a regex when using a `strategy` block")
|
||||
end
|
||||
|
||||
it "finds versions using provided content" do
|
||||
expect(extract_plist.find_versions(cask:, content:))
|
||||
.to eq(match_data[:cached])
|
||||
|
||||
# This `strategy` block is unnecessary but it's intended to test using a
|
||||
# regex in a `strategy` block.
|
||||
expect(extract_plist.find_versions(cask:, content:) do |items|
|
||||
items["com.caffeine"]&.version
|
||||
end).to eq(match_data[:cached])
|
||||
end
|
||||
|
||||
it "returns default match_data when provided content is blank" do
|
||||
expect(extract_plist.find_versions(cask:, content: "{}"))
|
||||
.to eq(match_data[:cached_default])
|
||||
end
|
||||
|
||||
it "checks the cask using the livecheck URL string", :needs_macos do
|
||||
cask_with_url = Cask::CaskLoader.load(cask_path("livecheck/livecheck-extract-plist-with-url"))
|
||||
livecheck_url = cask_with_url.livecheck.url
|
||||
|
||||
expect(
|
||||
extract_plist.find_versions(cask: cask_with_url, url: livecheck_url),
|
||||
).to eq({ matches:, regex: nil, url: livecheck_url })
|
||||
).to eq(match_data[:uncached].merge({ url: livecheck_url }))
|
||||
end
|
||||
|
||||
it "checks the original cask if the provided URL is the same as the artifact URL", :needs_macos do
|
||||
cask_url = cask.url.to_s
|
||||
|
||||
expect(extract_plist.find_versions(cask:, url: cask_url))
|
||||
.to eq({ matches:, regex: nil, url: cask_url })
|
||||
.to eq(match_data[:uncached].merge({ url: cask_url }))
|
||||
end
|
||||
|
||||
it "checks the original cask if a URL is not provided", :needs_macos do
|
||||
expect(extract_plist.find_versions(cask:)).to eq({ matches:, regex: nil, url: nil })
|
||||
expect(extract_plist.find_versions(cask:)).to eq(match_data[:uncached])
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user