From 51387287f7fadf41b2844a2c171fdb1497ea46ec Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Sun, 20 Aug 2023 12:20:39 -0700 Subject: [PATCH 1/3] Handle nil urls in cask installer and API cask loader The goal here is to handle the case where a cask might have a nil url stanza because that cask is not available on the current version of macOS or the given architecture. This just moves those checks from the end of the `Cask::Installer#fetch` method to the beginning so that we don't try and download casks that are missing urls. This will now provide a helpful error message like so: ``` Error: This software does not run on macOS versions older than Big Sur. ``` Beyond that it no longer tries to run the url stanza with a nil value when loading casks from the API. --- Library/Homebrew/cask/cask_loader.rb | 2 +- Library/Homebrew/cask/installer.rb | 31 +++++++++++++--------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index c343f491db..7385337812 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -277,7 +277,7 @@ module Cask sha256 json_cask[:sha256] end - url json_cask[:url], **json_cask.fetch(:url_specs, {}) + url json_cask[:url], **json_cask.fetch(:url_specs, {}) if json_cask[:url].present? appcast json_cask[:appcast] if json_cask[:appcast].present? json_cask[:name].each do |cask_name| name cask_name diff --git a/Library/Homebrew/cask/installer.rb b/Library/Homebrew/cask/installer.rb index 5c27a9ed29..5d6e45efab 100644 --- a/Library/Homebrew/cask/installer.rb +++ b/Library/Homebrew/cask/installer.rb @@ -64,12 +64,12 @@ module Cask odebug "Cask::Installer#fetch" load_cask_from_source_api! if @cask.loaded_from_api? && @cask.caskfile_only? - verify_has_sha if require_sha? && !force? + check_requirements download(quiet: quiet, timeout: timeout) - satisfy_dependencies + satisfy_cask_and_formula_dependencies end def stage @@ -253,25 +253,19 @@ on_request: true) end end - # TODO: move dependencies to a separate class, - # dependencies should also apply for `brew cask stage`, - # override dependencies with `--force` or perhaps `--force-deps` - def satisfy_dependencies - return unless @cask.depends_on - - macos_dependencies - arch_dependencies - cask_and_formula_dependencies + def check_requirements + check_macos_requirements + check_arch_requirements end - def macos_dependencies + def check_macos_requirements return unless @cask.depends_on.macos return if @cask.depends_on.macos.satisfied? raise CaskError, @cask.depends_on.macos.message(type: :cask) end - def arch_dependencies + def check_arch_requirements return if @cask.depends_on.arch.nil? @current_arch ||= { type: Hardware::CPU.type, bits: Hardware::CPU.bits } @@ -286,7 +280,7 @@ on_request: true) "but you are running #{@current_arch}." end - def collect_cask_and_formula_dependencies + def cask_and_formula_dependencies return @cask_and_formula_dependencies if @cask_and_formula_dependencies graph = ::Utils::TopologicalHash.graph_package_dependencies(@cask) @@ -305,7 +299,7 @@ on_request: true) end def missing_cask_and_formula_dependencies - collect_cask_and_formula_dependencies.reject do |cask_or_formula| + cask_and_formula_dependencies.reject do |cask_or_formula| installed = if cask_or_formula.respond_to?(:any_version_installed?) cask_or_formula.any_version_installed? else @@ -315,10 +309,13 @@ on_request: true) end end - def cask_and_formula_dependencies + # TODO: move dependencies to a separate class, + # dependencies should also apply for `brew cask stage`, + # override dependencies with `--force` or perhaps `--force-deps` + def satisfy_cask_and_formula_dependencies return if installed_as_dependency? - formulae_and_casks = collect_cask_and_formula_dependencies + formulae_and_casks = cask_and_formula_dependencies return if formulae_and_casks.empty? From 8c2f101138a00a90a410e5a1be1f300ed634e95c Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Sat, 2 Sep 2023 01:33:39 -0700 Subject: [PATCH 2/3] cmd/fetch: handle nil cask urls These urls can be nil if there is an unsatisfied macos version requirement. We check for false here because either the macos requirement can be satisfied and return true or can not be specified and return nil. If it's not specified, it means it can run on any macos version. The change in Cask::Download should provide better error messages in Downloadable but honestly we're better off just checking for the missing url higher up the call stack which is why I made the changes in the fetch command. Either way it seemed like a good idea while I'm here. --- Library/Homebrew/cask/download.rb | 2 ++ Library/Homebrew/cmd/fetch.rb | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/Library/Homebrew/cask/download.rb b/Library/Homebrew/cask/download.rb index 976e440dee..6912edceda 100644 --- a/Library/Homebrew/cask/download.rb +++ b/Library/Homebrew/cask/download.rb @@ -24,6 +24,8 @@ module Cask sig { override.returns(T.nilable(::URL)) } def url + return if cask.url.nil? + @url ||= ::URL.new(cask.url.to_s, cask.url.specs) end diff --git a/Library/Homebrew/cmd/fetch.rb b/Library/Homebrew/cmd/fetch.rb index 569239ad19..de6751ad6c 100644 --- a/Library/Homebrew/cmd/fetch.rb +++ b/Library/Homebrew/cmd/fetch.rb @@ -167,6 +167,11 @@ module Homebrew SimulateSystem.with os: os, arch: arch do cask = Cask::CaskLoader.load(ref) + if cask.depends_on.macos&.satisfied? == false + opoo "#{cask.token}: #{cask.depends_on.macos.message(type: :cask)}" + next + end + quarantine = args.quarantine? quarantine = true if quarantine.nil? From daa175e76025a657a3abfdfee249509ba891f8fe Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Sun, 3 Sep 2023 09:09:14 -0400 Subject: [PATCH 3/3] cask/installer: remove outdated comment. --- Library/Homebrew/cask/installer.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/Library/Homebrew/cask/installer.rb b/Library/Homebrew/cask/installer.rb index 5d6e45efab..2bee5d03aa 100644 --- a/Library/Homebrew/cask/installer.rb +++ b/Library/Homebrew/cask/installer.rb @@ -309,9 +309,6 @@ on_request: true) end end - # TODO: move dependencies to a separate class, - # dependencies should also apply for `brew cask stage`, - # override dependencies with `--force` or perhaps `--force-deps` def satisfy_cask_and_formula_dependencies return if installed_as_dependency?