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.
This commit is contained in:
apainintheneck 2023-08-20 12:20:39 -07:00
parent 3cd72905ce
commit 51387287f7
2 changed files with 15 additions and 18 deletions

View File

@ -277,7 +277,7 @@ module Cask
sha256 json_cask[:sha256] sha256 json_cask[:sha256]
end 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? appcast json_cask[:appcast] if json_cask[:appcast].present?
json_cask[:name].each do |cask_name| json_cask[:name].each do |cask_name|
name cask_name name cask_name

View File

@ -64,12 +64,12 @@ module Cask
odebug "Cask::Installer#fetch" odebug "Cask::Installer#fetch"
load_cask_from_source_api! if @cask.loaded_from_api? && @cask.caskfile_only? load_cask_from_source_api! if @cask.loaded_from_api? && @cask.caskfile_only?
verify_has_sha if require_sha? && !force? verify_has_sha if require_sha? && !force?
check_requirements
download(quiet: quiet, timeout: timeout) download(quiet: quiet, timeout: timeout)
satisfy_dependencies satisfy_cask_and_formula_dependencies
end end
def stage def stage
@ -253,25 +253,19 @@ on_request: true)
end end
end end
# TODO: move dependencies to a separate class, def check_requirements
# dependencies should also apply for `brew cask stage`, check_macos_requirements
# override dependencies with `--force` or perhaps `--force-deps` check_arch_requirements
def satisfy_dependencies
return unless @cask.depends_on
macos_dependencies
arch_dependencies
cask_and_formula_dependencies
end end
def macos_dependencies def check_macos_requirements
return unless @cask.depends_on.macos return unless @cask.depends_on.macos
return if @cask.depends_on.macos.satisfied? return if @cask.depends_on.macos.satisfied?
raise CaskError, @cask.depends_on.macos.message(type: :cask) raise CaskError, @cask.depends_on.macos.message(type: :cask)
end end
def arch_dependencies def check_arch_requirements
return if @cask.depends_on.arch.nil? return if @cask.depends_on.arch.nil?
@current_arch ||= { type: Hardware::CPU.type, bits: Hardware::CPU.bits } @current_arch ||= { type: Hardware::CPU.type, bits: Hardware::CPU.bits }
@ -286,7 +280,7 @@ on_request: true)
"but you are running #{@current_arch}." "but you are running #{@current_arch}."
end end
def collect_cask_and_formula_dependencies def cask_and_formula_dependencies
return @cask_and_formula_dependencies if @cask_and_formula_dependencies return @cask_and_formula_dependencies if @cask_and_formula_dependencies
graph = ::Utils::TopologicalHash.graph_package_dependencies(@cask) graph = ::Utils::TopologicalHash.graph_package_dependencies(@cask)
@ -305,7 +299,7 @@ on_request: true)
end end
def missing_cask_and_formula_dependencies 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?) installed = if cask_or_formula.respond_to?(:any_version_installed?)
cask_or_formula.any_version_installed? cask_or_formula.any_version_installed?
else else
@ -315,10 +309,13 @@ on_request: true)
end end
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? 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? return if formulae_and_casks.empty?