From b293acc89bc1dbc1c8bde6c40cd7dd0bc0cc745c Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sat, 12 Dec 2020 21:56:33 +0100 Subject: [PATCH] Add `FollowRedirection` livecheck strategy. --- Library/Homebrew/livecheck/strategy.rb | 1 + .../livecheck/strategy/follow_redirection.rb | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 Library/Homebrew/livecheck/strategy/follow_redirection.rb diff --git a/Library/Homebrew/livecheck/strategy.rb b/Library/Homebrew/livecheck/strategy.rb index f368479843..158fede7bd 100644 --- a/Library/Homebrew/livecheck/strategy.rb +++ b/Library/Homebrew/livecheck/strategy.rb @@ -110,5 +110,6 @@ require_relative "strategy/launchpad" require_relative "strategy/npm" require_relative "strategy/page_match" require_relative "strategy/pypi" +require_relative "strategy/follow_redirection" require_relative "strategy/sourceforge" require_relative "strategy/xorg" diff --git a/Library/Homebrew/livecheck/strategy/follow_redirection.rb b/Library/Homebrew/livecheck/strategy/follow_redirection.rb new file mode 100644 index 0000000000..f27e6176d3 --- /dev/null +++ b/Library/Homebrew/livecheck/strategy/follow_redirection.rb @@ -0,0 +1,47 @@ +# typed: false +# frozen_string_literal: true + +require_relative "page_match" + +module Homebrew + module Livecheck + module Strategy + # The {FollowRedirection} strategy follows all URL redirections and scans + # the final URL for matching text using the provided regex. + # + # @api private + class FollowRedirection + extend T::Sig + + NICE_NAME = "Follow HTTP Redirection" + + # We set the priority to zero since this cannot + # be detected automatically. + PRIORITY = 0 + + # Whether the strategy can be applied to the provided URL. + # FollowRedirection will technically match any HTTP URL but is + # only usable with a `livecheck` block containing a regex. + sig { params(url: String).returns(T::Boolean) } + def self.match?(url) + url.match?(%r{^https?://}) + end + + # Checks the final URL for new versions after following all redirections, + # using the provided regex for matching. + sig { params(url: String, regex: T.nilable(Regexp)).returns(T::Hash[Symbol, T.untyped]) } + def self.find_versions(url, regex) + raise ArgumentError, "A regular expression is required for the #{NICE_NAME} strategy." if regex.nil? + + match_data = { matches: {}, regex: regex, url: url } + + if (location = Strategy.page_headers(url)["location"]) && (match = location[regex, 1]) + match_data[:matches][match] = Version.new(match) + end + + match_data + end + end + end + end +end