Class: Homebrew::RetryableDownload Private

Inherits:
Object
  • Object
show all
Includes:
Downloadable, Utils::Output::Mixin
Defined in:
retryable_download.rb

This class is part of a private API. This class may only be used in the Homebrew/brew repository. Third parties should avoid using this class if possible, as it may be removed or changed without warning.

Instance Attribute Summary

Attributes included from Downloadable

#phase

Instance Method Summary collapse

Methods included from Utils::Output::Mixin

#odebug, #odeprecated, #odie, #odisabled, #ofail, #oh1, #oh1_title, #ohai, #ohai_title, #onoe, #opoo, #opoo_outside_github_actions, #pretty_duration, #pretty_installed, #pretty_outdated, #pretty_uninstalled

Methods included from Downloadable

#downloaded!, #downloaded?, #downloading!, #extracting!, #fetched_size, #freeze, #initialize_dup, #total_size, #verified!, #verifying!

Methods included from Context

current, current=, #debug?, #quiet?, #verbose?, #with_context

Constructor Details

#initialize(downloadable, tries:, pour: false) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

  • downloadable (Downloadable)
  • tries (Integer)
  • pour (Boolean) (defaults to: false)


23
24
25
26
27
28
29
30
# File 'retryable_download.rb', line 23

def initialize(downloadable, tries:, pour: false)
  super()

  @downloadable = downloadable
  @try = T.let(0, Integer)
  @tries = tries
  @pour = pour
end

Instance Method Details

#cached_downloadPathname

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



39
# File 'retryable_download.rb', line 39

def cached_download = downloadable.cached_download

#checksumChecksum?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



17
# File 'retryable_download.rb', line 17

def checksum = downloadable.checksum

#clear_cachevoid

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.



42
# File 'retryable_download.rb', line 42

def clear_cache = downloadable.clear_cache

#download_queue_nameString

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



33
# File 'retryable_download.rb', line 33

def download_queue_name = downloadable.download_queue_name

#download_queue_typeString

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



36
# File 'retryable_download.rb', line 36

def download_queue_type = downloadable.download_queue_type

#download_strategyT::Class[AbstractDownloadStrategy]

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



48
# File 'retryable_download.rb', line 48

def download_strategy = downloadable.download_strategy

#downloaderAbstractDownloadStrategy

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



51
# File 'retryable_download.rb', line 51

def downloader = downloadable.downloader

#fetch(verify_download_integrity: true, timeout: nil, quiet: false) ⇒ Pathname

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

  • verify_download_integrity (Boolean) (defaults to: true)
  • timeout (Integer, Float, nil) (defaults to: nil)
  • quiet (Boolean) (defaults to: false)

Returns:



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'retryable_download.rb', line 60

def fetch(verify_download_integrity: true, timeout: nil, quiet: false)
  bottle_tmp_keg = nil

  @try += 1

  downloadable.downloading!

  already_downloaded = downloadable.downloaded?

  download = if downloadable.is_a?(Resource) && (resource = T.cast(downloadable, Resource))
    resource.fetch(verify_download_integrity: false, timeout:, quiet:, skip_patches: true)
  else
    downloadable.fetch(verify_download_integrity: false, timeout:, quiet:)
  end

  downloadable.downloaded!

  return download unless download.file?

  unless quiet
    puts "Downloaded to: #{download}" unless already_downloaded
    puts "SHA-256: #{download.sha256}"
  end

  json_download = downloadable.is_a?(API::JSONDownload)
  downloadable.verify_download_integrity(download) if verify_download_integrity && !json_download

  if pour && downloadable.is_a?(Bottle)
    downloadable.extracting!

    HOMEBREW_TEMP_CELLAR.mkpath

    bottle_filename = T.cast(downloadable, Bottle).filename
    bottle_tmp_keg = HOMEBREW_TEMP_CELLAR/bottle_filename.name/bottle_filename.version.to_s
    bottle_poured_file = Pathname("#{bottle_tmp_keg}.poured")

    unless bottle_poured_file.exist?
      FileUtils.rm(bottle_poured_file) if bottle_poured_file.symlink?
      FileUtils.rm_r(bottle_tmp_keg) if bottle_tmp_keg.directory?

      UnpackStrategy.detect(download, prioritize_extension: true)
                    .extract_nestedly(to: HOMEBREW_TEMP_CELLAR)

      # Create a separate file to mark a completed extraction. This avoids
      # a potential race condition if a user interrupts the install.
      # We use a symlink to easily check that both this extra status file
      # and the real extracted directory exist via `Pathname#exist?`.
      FileUtils.ln_s(bottle_tmp_keg, bottle_poured_file)
    end

    downloadable.downloaded!
  elsif json_download
    FileUtils.touch(download, mtime: Time.now)
  end

  download
rescue DownloadError, ChecksumMismatchError, Resource::BottleManifest::Error
  tries_remaining = @tries - @try
  if tries_remaining.zero?
    cleanup_partial_installation_on_error!(bottle_tmp_keg)
    raise
  end

  wait = 2 ** @try
  unless quiet
    what = Utils.pluralize("try", tries_remaining)
    ohai "Retrying download in #{wait}s... (#{tries_remaining} #{what} left)"
  end
  sleep wait

  downloadable.clear_cache
  retry
# Catch any other types of exceptions as they leave us with partial installations.
rescue Exception # rubocop:disable Lint/RescueException
  cleanup_partial_installation_on_error!(bottle_tmp_keg)
  raise
end

#mirrorsArray<String>

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



20
# File 'retryable_download.rb', line 20

def mirrors = downloadable.mirrors

#urlString, ...

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



14
# File 'retryable_download.rb', line 14

def url = downloadable.url

#verify_download_integrity(filename) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.

Parameters:



139
# File 'retryable_download.rb', line 139

def verify_download_integrity(filename) = downloadable.verify_download_integrity(filename)

#versionVersion?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



45
# File 'retryable_download.rb', line 45

def version = downloadable.version