From 916c9806768b14a6229c9c9c6bee06f90fbcaab2 Mon Sep 17 00:00:00 2001 From: Bevan Kay Date: Mon, 30 May 2022 17:46:45 +1000 Subject: [PATCH 1/4] livecheck: allow custom url in extract_plist strategy --- .../Homebrew/livecheck/strategy/extract_plist.rb | 14 ++++++++++++-- Library/Homebrew/unversioned_cask_checker.rb | 12 +++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/livecheck/strategy/extract_plist.rb b/Library/Homebrew/livecheck/strategy/extract_plist.rb index 0bf114f63d..39f8d8f6c1 100644 --- a/Library/Homebrew/livecheck/strategy/extract_plist.rb +++ b/Library/Homebrew/livecheck/strategy/extract_plist.rb @@ -87,12 +87,13 @@ module Homebrew sig { params( cask: Cask::Cask, + url: T.nilable(String), regex: T.nilable(Regexp), _unused: T.nilable(T::Hash[Symbol, T.untyped]), block: T.untyped, ).returns(T::Hash[Symbol, T.untyped]) } - def self.find_versions(cask:, regex: nil, **_unused, &block) + def self.find_versions(cask:, url: nil, regex: nil, **_unused, &block) if regex.present? && block.blank? raise ArgumentError, "#{T.must(name).demodulize} only supports a regex when using a `strategy` block" end @@ -100,7 +101,16 @@ module Homebrew match_data = { matches: {}, regex: regex } - unversioned_cask_checker = UnversionedCaskChecker.new(cask) + if url && url != cask.url.to_s + cask_object_for_livecheck = Cask::Cask.new("livecheck-cask", config: cask.config) do + url url.to_s + end + + unversioned_cask_checker = UnversionedCaskChecker.new(cask, livecheck_url: cask_object_for_livecheck) + else + unversioned_cask_checker = UnversionedCaskChecker.new(cask) + end + items = unversioned_cask_checker.all_versions.transform_values { |v| Item.new(bundle_version: v) } versions_from_items(items, regex, &block).each do |version_text| diff --git a/Library/Homebrew/unversioned_cask_checker.rb b/Library/Homebrew/unversioned_cask_checker.rb index af6a659573..fa85d4fc4d 100644 --- a/Library/Homebrew/unversioned_cask_checker.rb +++ b/Library/Homebrew/unversioned_cask_checker.rb @@ -15,15 +15,21 @@ module Homebrew sig { returns(Cask::Cask) } attr_reader :cask + attr_reader :livecheck_url - sig { params(cask: Cask::Cask).void } - def initialize(cask) + sig { params(cask: Cask::Cask, livecheck_url: T.nilable(Cask::Cask)).void } + def initialize(cask, livecheck_url: nil) @cask = cask + @livecheck_url = livecheck_url end sig { returns(Cask::Installer) } def installer - @installer ||= Cask::Installer.new(cask, verify_download_integrity: false) + @installer ||= if livecheck_url + Cask::Installer.new(livecheck_url, verify_download_integrity: false) + else + Cask::Installer.new(cask, verify_download_integrity: false) + end end sig { returns(T::Array[Cask::Artifact::App]) } From 077fb350a5c10aad93c3b01a5406dfdd3ad229ce Mon Sep 17 00:00:00 2001 From: Sam Ford <1584702+samford@users.noreply.github.com> Date: Sun, 12 Jun 2022 15:27:01 -0400 Subject: [PATCH 2/4] ExtractPlist: Add url to #find_versions object --- Library/Homebrew/livecheck/strategy/extract_plist.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/strategy/extract_plist.rb b/Library/Homebrew/livecheck/strategy/extract_plist.rb index 39f8d8f6c1..8bb2aeeefc 100644 --- a/Library/Homebrew/livecheck/strategy/extract_plist.rb +++ b/Library/Homebrew/livecheck/strategy/extract_plist.rb @@ -82,6 +82,8 @@ module Homebrew # versions from `plist` files. # # @param cask [Cask::Cask] the cask to check for version information + # @param url [String, nil] an alternative URL to check for version + # information # @param regex [Regexp, nil] a regex for use in a strategy block # @return [Hash] sig { @@ -99,7 +101,7 @@ module Homebrew end raise ArgumentError, "The #{T.must(name).demodulize} strategy only supports casks." unless T.unsafe(cask) - match_data = { matches: {}, regex: regex } + match_data = { matches: {}, regex: regex, url: url } if url && url != cask.url.to_s cask_object_for_livecheck = Cask::Cask.new("livecheck-cask", config: cask.config) do From d7a26cd6d33163c61cd28ef39bd06a555e7a6c34 Mon Sep 17 00:00:00 2001 From: Sam Ford <1584702+samford@users.noreply.github.com> Date: Sun, 12 Jun 2022 15:27:31 -0400 Subject: [PATCH 3/4] ExtractPlist: Modify #find_versions url usage --- Library/Homebrew/cask/cask.rb | 5 +++-- Library/Homebrew/cask/dsl.rb | 8 +++++--- .../Homebrew/livecheck/strategy/extract_plist.rb | 14 +++++++------- Library/Homebrew/unversioned_cask_checker.rb | 12 +++--------- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/Library/Homebrew/cask/cask.rb b/Library/Homebrew/cask/cask.rb index fd23cafada..89a7c19ad9 100644 --- a/Library/Homebrew/cask/cask.rb +++ b/Library/Homebrew/cask/cask.rb @@ -20,7 +20,7 @@ module Cask attr_reader :token, :sourcefile_path, :source, :config, :default_config - attr_accessor :download + attr_accessor :download, :allow_reassignment def self.all Tap.flat_map(&:cask_files).map do |f| @@ -38,11 +38,12 @@ module Cask @tap end - def initialize(token, sourcefile_path: nil, source: nil, tap: nil, config: nil, &block) + def initialize(token, sourcefile_path: nil, source: nil, tap: nil, config: nil, allow_reassignment: false, &block) @token = token @sourcefile_path = sourcefile_path @source = source @tap = tap + @allow_reassignment = allow_reassignment @block = block @default_config = config || Config.new diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb index e56bfc9a18..e4d1ac47a2 100644 --- a/Library/Homebrew/cask/dsl.rb +++ b/Library/Homebrew/cask/dsl.rb @@ -112,7 +112,7 @@ module Cask def set_unique_stanza(stanza, should_return) return instance_variable_get("@#{stanza}") if should_return - if instance_variable_defined?("@#{stanza}") + if !@cask.allow_reassignment && instance_variable_defined?("@#{stanza}") raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only appear once.") end @@ -137,7 +137,7 @@ module Cask return unless default - unless @language_blocks.default.nil? + if !@cask.allow_reassignment && @language_blocks.default.present? raise CaskInvalidError.new(cask, "Only one default language may be defined.") end @@ -294,7 +294,9 @@ module Cask @livecheck ||= Livecheck.new(self) return @livecheck unless block - raise CaskInvalidError.new(cask, "'livecheck' stanza may only appear once.") if @livecheckable + if !@cask.allow_reassignment && @livecheckable + raise CaskInvalidError.new(cask, "'livecheck' stanza may only appear once.") + end @livecheckable = true @livecheck.instance_eval(&block) diff --git a/Library/Homebrew/livecheck/strategy/extract_plist.rb b/Library/Homebrew/livecheck/strategy/extract_plist.rb index 8bb2aeeefc..2486a545bc 100644 --- a/Library/Homebrew/livecheck/strategy/extract_plist.rb +++ b/Library/Homebrew/livecheck/strategy/extract_plist.rb @@ -103,14 +103,14 @@ module Homebrew match_data = { matches: {}, regex: regex, url: url } - if url && url != cask.url.to_s - cask_object_for_livecheck = Cask::Cask.new("livecheck-cask", config: cask.config) do - url url.to_s - end - - unversioned_cask_checker = UnversionedCaskChecker.new(cask, livecheck_url: cask_object_for_livecheck) + unversioned_cask_checker = if url.present? && url != cask.url.to_s + # Create a copy of the `cask` that uses the `livecheck` block URL + cask_copy = Cask::CaskLoader.load(cask.full_name) + cask_copy.allow_reassignment = true + cask_copy.url { url } + UnversionedCaskChecker.new(cask_copy) else - unversioned_cask_checker = UnversionedCaskChecker.new(cask) + UnversionedCaskChecker.new(cask) end items = unversioned_cask_checker.all_versions.transform_values { |v| Item.new(bundle_version: v) } diff --git a/Library/Homebrew/unversioned_cask_checker.rb b/Library/Homebrew/unversioned_cask_checker.rb index fa85d4fc4d..af6a659573 100644 --- a/Library/Homebrew/unversioned_cask_checker.rb +++ b/Library/Homebrew/unversioned_cask_checker.rb @@ -15,21 +15,15 @@ module Homebrew sig { returns(Cask::Cask) } attr_reader :cask - attr_reader :livecheck_url - sig { params(cask: Cask::Cask, livecheck_url: T.nilable(Cask::Cask)).void } - def initialize(cask, livecheck_url: nil) + sig { params(cask: Cask::Cask).void } + def initialize(cask) @cask = cask - @livecheck_url = livecheck_url end sig { returns(Cask::Installer) } def installer - @installer ||= if livecheck_url - Cask::Installer.new(livecheck_url, verify_download_integrity: false) - else - Cask::Installer.new(cask, verify_download_integrity: false) - end + @installer ||= Cask::Installer.new(cask, verify_download_integrity: false) end sig { returns(T::Array[Cask::Artifact::App]) } From 2194f6e12b0854a25150130e6345459a6b2be2e0 Mon Sep 17 00:00:00 2001 From: Sam Ford <1584702+samford@users.noreply.github.com> Date: Fri, 24 Jun 2022 00:08:25 -0400 Subject: [PATCH 4/4] Only require livecheck block URL when appropriate `ExtractPlist` doesn't require a URL like other strategies (it takes a `Cask` instead) but we've had to provide one in existing `livecheck` blocks to get past this requirement in livecheck. This commit makes it so this requirement is only enforced when a strategy's `#find_versions` method has a required `url` parameter (not an optional one, as in `ExtractPlist`). --- Library/Homebrew/livecheck/livecheck.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index f0a2056835..bdc25c3371 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -563,6 +563,7 @@ module Homebrew # 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. + # rubocop:disable Metrics/CyclomaticComplexity sig { params( formula_or_cask: T.any(Formula, Cask::Cask), @@ -657,7 +658,7 @@ module Homebrew end if livecheck_strategy.present? - if livecheck_url.blank? + if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) odebug "#{strategy_name} strategy requires a URL" next elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) @@ -768,6 +769,7 @@ module Homebrew nil end + # rubocop:enable Metrics/CyclomaticComplexity end # rubocop:enable Metrics/ModuleLength end