| 
									
										
										
										
											2024-07-14 11:42:22 -04:00
										 |  |  | # typed: true # rubocop:todo Sorbet/StrictSigil | 
					
						
							|  |  |  | # 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 22:51:54 -04:00
										 |  |  |     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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 11:42:22 -04:00
										 |  |  |     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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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_of(AbstractDownloadStrategy)) } | 
					
						
							|  |  |  |     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 |