From ed3042c37a66b5dddcdd426221dbb38f88272f41 Mon Sep 17 00:00:00 2001 From: EricFromCanada Date: Tue, 23 Nov 2021 23:22:41 -0500 Subject: [PATCH] livecheck: use brewed curl if called for by download URL --- Library/Homebrew/livecheck/livecheck.rb | 34 +++++++++++++++++-- Library/Homebrew/livecheck/strategy.rb | 16 +++++---- .../livecheck/strategy/header_match.rb | 14 ++++---- .../Homebrew/livecheck/strategy/page_match.rb | 6 ++-- .../Homebrew/test/livecheck/livecheck_spec.rb | 15 ++++++-- 5 files changed, 66 insertions(+), 19 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index bccbf45c51..63019e7d3a 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -529,6 +529,28 @@ module Homebrew url end + # Fetch with brewed curl if using the download or homepage URL + # and the download URL specifies `using: :homebrew_curl`. + sig { params(formula_or_cask: T.any(Formula, Cask::Cask), url: String).returns(T::Boolean) } + def use_homebrew_curl?(formula_or_cask, url) + if checkable_urls(formula_or_cask).include?(url) + case formula_or_cask + when Formula + [:stable, :head].any? do |spec_name| + next false unless (spec = formula_or_cask.send(spec_name)) + + spec.using == :homebrew_curl + end + when Cask::Cask + formula_or_cask.url.using == :homebrew_curl + else + T.absurd(formula_or_cask) + end + else + false + end + end + # Identifies the latest version of the formula and returns a Hash containing # the version information. Returns nil if a latest version couldn't be found. sig { @@ -637,10 +659,16 @@ module Homebrew next if strategy.blank? + homebrew_curl = case strategy_name + when "PageMatch", "HeaderMatch" + use_homebrew_curl?((referenced_formula_or_cask || formula_or_cask), url) + end + strategy_data = strategy.find_versions( - url: url, - regex: livecheck_regex, - cask: cask, + url: url, + regex: livecheck_regex, + homebrew_curl: homebrew_curl, + cask: cask, &livecheck_strategy_block ) match_version_map = strategy_data[:matches] diff --git a/Library/Homebrew/livecheck/strategy.rb b/Library/Homebrew/livecheck/strategy.rb index 148824e245..ff1f41905b 100644 --- a/Library/Homebrew/livecheck/strategy.rb +++ b/Library/Homebrew/livecheck/strategy.rb @@ -171,16 +171,18 @@ module Homebrew # collected into an array of hashes. # # @param url [String] the URL to fetch + # @param homebrew_curl [Boolean] whether to use brewed curl with the URL # @return [Array] - sig { params(url: String).returns(T::Array[T::Hash[String, String]]) } - def self.page_headers(url) + sig { params(url: String, homebrew_curl: T::Boolean).returns(T::Array[T::Hash[String, String]]) } + def self.page_headers(url, homebrew_curl: false) headers = [] [:default, :browser].each do |user_agent| stdout, _, status = curl_with_workarounds( *PAGE_HEADERS_CURL_ARGS, url, **DEFAULT_CURL_OPTIONS, - user_agent: user_agent + use_homebrew_curl: homebrew_curl, + user_agent: user_agent ) while stdout.match?(/\AHTTP.*\r$/) @@ -203,9 +205,10 @@ module Homebrew # array with the error message instead. # # @param url [String] the URL of the content to check + # @param homebrew_curl [Boolean] whether to use brewed curl with the URL # @return [Hash] - sig { params(url: String).returns(T::Hash[Symbol, T.untyped]) } - def self.page_content(url) + sig { params(url: String, homebrew_curl: T::Boolean).returns(T::Hash[Symbol, T.untyped]) } + def self.page_content(url, homebrew_curl: false) original_url = url stderr = nil @@ -213,7 +216,8 @@ module Homebrew stdout, stderr, status = curl_with_workarounds( *PAGE_CONTENT_CURL_ARGS, url, **DEFAULT_CURL_OPTIONS, - user_agent: user_agent + use_homebrew_curl: homebrew_curl, + user_agent: user_agent ) next unless status.success? diff --git a/Library/Homebrew/livecheck/strategy/header_match.rb b/Library/Homebrew/livecheck/strategy/header_match.rb index 9bd68b991e..a54c19abb4 100644 --- a/Library/Homebrew/livecheck/strategy/header_match.rb +++ b/Library/Homebrew/livecheck/strategy/header_match.rb @@ -71,19 +71,21 @@ module Homebrew # # @param url [String] the URL to fetch # @param regex [Regexp, nil] a regex used for matching versions + # @param homebrew_curl [Boolean] whether to use brewed curl with the URL # @return [Hash] sig { params( - url: String, - regex: T.nilable(Regexp), - _unused: T.nilable(T::Hash[Symbol, T.untyped]), - block: T.untyped, + url: String, + regex: T.nilable(Regexp), + homebrew_curl: T::Boolean, + _unused: T.nilable(T::Hash[Symbol, T.untyped]), + block: T.untyped, ).returns(T::Hash[Symbol, T.untyped]) } - def self.find_versions(url:, regex: nil, **_unused, &block) + def self.find_versions(url:, regex: nil, homebrew_curl: false, **_unused, &block) match_data = { matches: {}, regex: regex, url: url } - headers = Strategy.page_headers(url) + headers = Strategy.page_headers(url, homebrew_curl: homebrew_curl) # Merge the headers from all responses into one hash merged_headers = headers.reduce(&:merge) diff --git a/Library/Homebrew/livecheck/strategy/page_match.rb b/Library/Homebrew/livecheck/strategy/page_match.rb index 7ef3735636..d18a924cae 100644 --- a/Library/Homebrew/livecheck/strategy/page_match.rb +++ b/Library/Homebrew/livecheck/strategy/page_match.rb @@ -79,17 +79,19 @@ module Homebrew # @param regex [Regexp, nil] a regex used for matching versions # @param provided_content [String, nil] page content to use in place of # fetching via Strategy#page_content + # @param homebrew_curl [Boolean] whether to use brewed curl with the URL # @return [Hash] sig { params( url: String, regex: T.nilable(Regexp), provided_content: T.nilable(String), + homebrew_curl: T::Boolean, _unused: T.nilable(T::Hash[Symbol, T.untyped]), block: 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, homebrew_curl: false, **_unused, &block) if regex.blank? && block.blank? raise ArgumentError, "#{T.must(name).demodulize} requires a regex or `strategy` block" end @@ -101,7 +103,7 @@ module Homebrew match_data[:cached] = true provided_content else - match_data.merge!(Strategy.page_content(url)) + match_data.merge!(Strategy.page_content(url, homebrew_curl: homebrew_curl)) match_data[:content] end return match_data if content.blank? diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index d6d6e4d6d2..b3a11abdd8 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -16,7 +16,7 @@ describe Homebrew::Livecheck do formula("test") do desc "Test formula" homepage "https://brew.sh" - url "https://brew.sh/test-0.0.1.tgz" + url "https://brew.sh/test-0.0.1.tgz", using: :homebrew_curl head "https://github.com/Homebrew/brew.git" livecheck do @@ -31,7 +31,7 @@ describe Homebrew::Livecheck do cask "test" do version "0.0.1,2" - url "https://brew.sh/test-0.0.1.dmg" + url "https://brew.sh/test-0.0.1.dmg", using: :homebrew_curl name "Test" desc "Test cask" homepage "https://brew.sh" @@ -147,6 +147,17 @@ describe Homebrew::Livecheck do end end + describe "::use_homebrew_curl?" do + it "uses brewed curl if called for by the download URL" do + expect(livecheck.use_homebrew_curl?(f, livecheck_url)).to be(false) + expect(livecheck.use_homebrew_curl?(f, homepage_url)).to be(true) + expect(livecheck.use_homebrew_curl?(f, stable_url)).to be(true) + expect(livecheck.use_homebrew_curl?(c, livecheck_url)).to be(false) + expect(livecheck.use_homebrew_curl?(c, homepage_url)).to be(true) + expect(livecheck.use_homebrew_curl?(c, cask_url)).to be(true) + end + end + describe "::preprocess_url" do let(:github_git_url_with_extension) { "https://github.com/Homebrew/brew.git" }