97 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # typed: true # rubocop:todo Sorbet/StrictSigil
 | |
| # frozen_string_literal: true
 | |
| 
 | |
| module Homebrew
 | |
|   class RetryableDownload
 | |
|     include Downloadable
 | |
| 
 | |
|     sig { returns(Downloadable) }
 | |
|     attr_reader :downloadable
 | |
|     private :downloadable
 | |
| 
 | |
|     sig { override.returns(T.nilable(URL)) }
 | |
|     def url = downloadable.url
 | |
| 
 | |
|     sig { override.returns(T.nilable(Checksum)) }
 | |
|     def checksum = downloadable.checksum
 | |
| 
 | |
|     sig { override.returns(T::Array[String]) }
 | |
|     def mirrors = downloadable.mirrors
 | |
| 
 | |
|     sig { params(downloadable: Downloadable, tries: Integer).void }
 | |
|     def initialize(downloadable, tries: 3)
 | |
|       super()
 | |
| 
 | |
|       @downloadable = downloadable
 | |
|       @try = 0
 | |
|       @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
 | |
| 
 | |
|     sig { override.void }
 | |
|     def clear_cache = downloadable.clear_cache
 | |
| 
 | |
|     sig { override.returns(T.nilable(Version)) }
 | |
|     def version = downloadable.version
 | |
| 
 | |
|     sig { override.returns(T.class_of(AbstractDownloadStrategy)) }
 | |
|     def download_strategy = downloadable.download_strategy
 | |
| 
 | |
|     sig { override.returns(AbstractDownloadStrategy) }
 | |
|     def downloader = downloadable.downloader
 | |
| 
 | |
|     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
 | |
| 
 | |
|     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
 | |
|   end
 | |
| end
 | 
