brew/Library/Homebrew/retryable_download.rb

97 lines
2.7 KiB
Ruby
Raw Permalink Normal View History

# typed: strict
2024-07-14 11:42:22 -04:00
# frozen_string_literal: true
module Homebrew
2024-07-14 21:03:08 -04:00
class RetryableDownload
include Downloadable
2024-07-14 11:42:22 -04:00
sig { returns(Downloadable) }
attr_reader :downloadable
private :downloadable
sig { override.returns(T.any(NilClass, String, URL)) }
2024-07-14 22:51:54 -04:00
def url = downloadable.url
sig { override.returns(T.nilable(Checksum)) }
def checksum = downloadable.checksum
sig { override.returns(T::Array[String]) }
def mirrors = downloadable.mirrors
2024-07-14 11:42:22 -04:00
sig { params(downloadable: Downloadable, tries: Integer).void }
def initialize(downloadable, tries: 3)
super()
@downloadable = downloadable
@try = T.let(0, Integer)
2024-07-14 11:42:22 -04:00
@tries = tries
end
sig { override.returns(String) }
def name = downloadable.name
sig { override.returns(String) }
def download_type = downloadable.download_type
sig { override.returns(Pathname) }
def cached_download = downloadable.cached_download
2024-07-14 22:51:54 -04:00
sig { override.void }
def clear_cache = downloadable.clear_cache
sig { override.returns(T.nilable(Version)) }
def version = downloadable.version
sig { override.returns(T::Class[AbstractDownloadStrategy]) }
2024-07-14 22:51:54 -04:00
def download_strategy = downloadable.download_strategy
sig { override.returns(AbstractDownloadStrategy) }
def downloader = downloadable.downloader
2024-07-14 11:42:22 -04:00
sig {
override.params(
verify_download_integrity: T::Boolean,
timeout: T.nilable(T.any(Integer, Float)),
quiet: T::Boolean,
).returns(Pathname)
}
def fetch(verify_download_integrity: true, timeout: nil, quiet: false)
@try += 1
already_downloaded = downloadable.downloaded?
download = downloadable.fetch(verify_download_integrity: false, timeout:, quiet:)
return download unless download.file?
unless quiet
puts "Downloaded to: #{download}" unless already_downloaded
puts "SHA256: #{download.sha256}"
end
downloadable.verify_download_integrity(download) if verify_download_integrity
download
rescue DownloadError, ChecksumMismatchError
tries_remaining = @tries - @try
raise if tries_remaining.zero?
wait = 2 ** @try
unless quiet
what = Utils.pluralize("tr", tries_remaining, plural: "ies", singular: "y")
ohai "Retrying download in #{wait}s... (#{tries_remaining} #{what} left)"
end
sleep wait
downloadable.clear_cache
retry
end
2024-07-14 22:51:54 -04:00
sig { override.params(filename: Pathname).void }
def verify_download_integrity(filename) = downloadable.verify_download_integrity(filename)
sig { override.returns(String) }
def download_name = downloadable.download_name
2024-07-14 11:42:22 -04:00
end
end