diff --git a/Library/Homebrew/livecheck.rb b/Library/Homebrew/livecheck.rb index 7fb6c3bb2b..2560b80737 100644 --- a/Library/Homebrew/livecheck.rb +++ b/Library/Homebrew/livecheck.rb @@ -67,7 +67,9 @@ class Livecheck # # @param symbol [Symbol] symbol for the desired strategy # @return [Symbol, nil] - def strategy(symbol = nil) + def strategy(symbol = nil, &block) + @strategy_block = block if block + case symbol when nil @strategy @@ -78,6 +80,8 @@ class Livecheck end end + 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 diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 8bc6b69a09..1b31956e1a 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -480,7 +480,7 @@ module Homebrew next if strategy.blank? - strategy_data = strategy.find_versions(url, livecheck_regex) + strategy_data = strategy.find_versions(url, livecheck_regex, &livecheck.strategy_block) match_version_map = strategy_data[:matches] regex = strategy_data[:regex] diff --git a/Library/Homebrew/livecheck/strategy/sparkle.rb b/Library/Homebrew/livecheck/strategy/sparkle.rb index 5c3015defd..3372008723 100644 --- a/Library/Homebrew/livecheck/strategy/sparkle.rb +++ b/Library/Homebrew/livecheck/strategy/sparkle.rb @@ -1,6 +1,7 @@ # typed: false # frozen_string_literal: true +require "bundle_version" require_relative "page_match" module Homebrew @@ -27,7 +28,7 @@ module Homebrew # Checks the content at the URL for new versions. sig { params(url: String, regex: T.nilable(Regexp)).returns(T::Hash[Symbol, T.untyped]) } - def self.find_versions(url, regex) + def self.find_versions(url, regex, &block) raise ArgumentError, "The #{NICE_NAME} strategy does not support regular expressions." if regex require "nokogiri" @@ -39,14 +40,21 @@ module Homebrew xml = Nokogiri.parse(contents) xml.remove_namespaces! - match = xml.xpath("//rss//channel//item//enclosure") - .map { |enclosure| [*enclosure["shortVersionString"], *enclosure["version"]].uniq } - .reject(&:empty?) - .uniq - .max_by { |versions| versions.map { |v| Version.new(v) } } - &.join(",") + enclosure = + xml.xpath("//rss//channel//item//enclosure") + .map { |e| { url: e["url"], version: BundleVersion.new(e["shortVersionString"], e["version"]) } } + .max_by { |e| e[:version] } - match_data[:matches][match] = Version.new(match) if match + if enclosure + match = if block + enclosure[:version] = Cask::DSL::Version.new(enclosure[:version].nice_version) + block.call(enclosure).to_s + else + enclosure[:version].nice_version + end + + match_data[:matches][match] = Version.new(match) + end match_data end