diff --git a/Library/Homebrew/api/download.rb b/Library/Homebrew/api/download.rb index a13bfe73ca..947605805a 100644 --- a/Library/Homebrew/api/download.rb +++ b/Library/Homebrew/api/download.rb @@ -6,13 +6,20 @@ require "downloadable" module Homebrew module API class DownloadStrategy < CurlDownloadStrategy + sig { returns(String) } + def name # rubocop:disable Lint/UselessMethodDefinition + super + end + sig { override.returns(Pathname) } def symlink_location cache/name end end - class Download < Downloadable + class Download + include Downloadable + sig { params( url: String, @@ -29,6 +36,21 @@ module Homebrew @cache = cache end + sig { override.returns(API::DownloadStrategy) } + def downloader + T.cast(super, API::DownloadStrategy) + end + + sig { override.returns(String) } + def name + downloader.name + end + + sig { override.returns(String) } + def download_type + "API" + end + sig { override.returns(Pathname) } def cache @cache || super @@ -36,7 +58,7 @@ module Homebrew sig { returns(Pathname) } def symlink_location - T.cast(downloader, API::DownloadStrategy).symlink_location + downloader.symlink_location end end end diff --git a/Library/Homebrew/cask/download.rb b/Library/Homebrew/cask/download.rb index 836825abf5..eb1d9a7087 100644 --- a/Library/Homebrew/cask/download.rb +++ b/Library/Homebrew/cask/download.rb @@ -8,7 +8,9 @@ require "cask/quarantine" module Cask # A download corresponding to a {Cask}. - class Download < Downloadable + class Download + include Downloadable + include Context attr_reader :cask diff --git a/Library/Homebrew/downloadable.rb b/Library/Homebrew/downloadable.rb index b030c60678..d1f6b8a298 100644 --- a/Library/Homebrew/downloadable.rb +++ b/Library/Homebrew/downloadable.rb @@ -5,7 +5,7 @@ require "url" require "checksum" require "download_strategy" -class Downloadable +module Downloadable include Context extend T::Helpers @@ -32,7 +32,7 @@ class Downloadable @version = @version.dup end - sig { override.returns(T.self_type) } + sig { returns(T.self_type) } def freeze @checksum.freeze @mirrors.freeze @@ -40,14 +40,12 @@ class Downloadable super end - sig { returns(String) } - def name - "" - end + sig { abstract.returns(String) } + def name; end sig { returns(String) } def download_type - T.must(T.must(self.class.name).split("::").last).gsub(/([[:lower:]])([[:upper:]])/, '\1 \2').downcase + T.must(self.class.name&.split("::")&.last).gsub(/([[:lower:]])([[:upper:]])/, '\1 \2').downcase end sig { returns(T::Boolean) } @@ -73,16 +71,16 @@ class Downloadable version unless version&.null? end - sig { returns(T.class_of(AbstractDownloadStrategy)) } + sig { overridable.returns(T.class_of(AbstractDownloadStrategy)) } def download_strategy @download_strategy ||= determine_url&.download_strategy end - sig { returns(AbstractDownloadStrategy) } + sig { overridable.returns(AbstractDownloadStrategy) } def downloader @downloader ||= begin primary_url, *mirrors = determine_url_mirrors - raise ArgumentError, "attempted to use a Downloadable without a URL!" if primary_url.blank? + raise ArgumentError, "attempted to use a `Downloadable` without a URL!" if primary_url.blank? download_strategy.new(primary_url, download_name, version, mirrors:, cache:, **T.must(@url).specs) @@ -90,7 +88,7 @@ class Downloadable end sig { - params( + overridable.params( verify_download_integrity: T::Boolean, timeout: T.nilable(T.any(Integer, Float)), quiet: T::Boolean, @@ -111,7 +109,7 @@ class Downloadable download end - sig { params(filename: Pathname).void } + sig { overridable.params(filename: Pathname).void } def verify_download_integrity(filename) if filename.file? ohai "Verifying checksum for '#{filename.basename}'" if verbose? diff --git a/Library/Homebrew/downloadable.rbi b/Library/Homebrew/downloadable.rbi new file mode 100644 index 0000000000..2b50bad576 --- /dev/null +++ b/Library/Homebrew/downloadable.rbi @@ -0,0 +1,5 @@ +# typed: strict + +module Downloadable + requires_ancestor { Kernel } +end diff --git a/Library/Homebrew/resource.rb b/Library/Homebrew/resource.rb index 59607548de..3c4e365aa9 100644 --- a/Library/Homebrew/resource.rb +++ b/Library/Homebrew/resource.rb @@ -9,7 +9,8 @@ require "extend/on_system" # Resource is the fundamental representation of an external resource. The # primary formula download, along with other declared resources, are instances # of this class. -class Resource < Downloadable +class Resource + include Downloadable include FileUtils include OnSystem::MacOSAndLinux diff --git a/Library/Homebrew/retryable_download.rb b/Library/Homebrew/retryable_download.rb index bd9d9e595c..3d38962698 100644 --- a/Library/Homebrew/retryable_download.rb +++ b/Library/Homebrew/retryable_download.rb @@ -2,7 +2,9 @@ # frozen_string_literal: true module Homebrew - class RetryableDownload < Downloadable + class RetryableDownload + include Downloadable + sig { returns(Downloadable) } attr_reader :downloadable private :downloadable diff --git a/Library/Homebrew/software_spec.rb b/Library/Homebrew/software_spec.rb index 305319e88c..81a9b192ee 100644 --- a/Library/Homebrew/software_spec.rb +++ b/Library/Homebrew/software_spec.rb @@ -15,7 +15,9 @@ require "compilers" require "macos_version" require "extend/on_system" -class SoftwareSpec < Downloadable +class SoftwareSpec + include Downloadable + extend Forwardable include OnSystem::MacOSAndLinux @@ -294,7 +296,9 @@ class HeadSoftwareSpec < SoftwareSpec end end -class Bottle < Downloadable +class Bottle + include Downloadable + class Filename attr_reader :name, :version, :tag, :rebuild