Class: Cask::Download Private

Inherits:
Object show all
Includes:
Context, Downloadable
Defined in:
cask/download.rb

Overview

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.

A download corresponding to a Cask.

Instance Attribute Summary collapse

Attributes included from Downloadable

#mirrors, #phase

Instance Method Summary collapse

Methods included from Context

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

Methods included from Downloadable

#cached_download, #clear_cache, #download_queue_message, #download_strategy, #downloaded!, #downloaded?, #downloader, #downloading!, #extracting!, #fetched_size, #freeze, #initialize_dup, #total_size, verification_cache, #verified!, #verifying!

Methods included from Utils::Output::Mixin

#issue_reporting_message, #odebug, #odeprecated, #odie, #odisabled, #ofail, #oh1, #oh1_title, #ohai, #ohai_title, #onoe, #opoo, #opoo_outside_github_actions, #opoo_without_github_actions_annotation, #pretty_deprecated, #pretty_disabled, #pretty_duration, #pretty_install_status, #pretty_installed, #pretty_uninstalled, #pretty_unmarked, #pretty_upgradable, #pretty_warning

Constructor Details

#initialize(cask, require_sha: 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:

  • cask (::Cask::Cask)
  • require_sha (Boolean) (defaults to: false)


28
29
30
31
32
33
# File 'cask/download.rb', line 28

def initialize(cask, require_sha: false)
  super()

  @cask = cask
  @require_sha = require_sha
end

Instance Attribute Details

#cask::Cask::Cask (readonly)

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
21
22
# File 'cask/download.rb', line 20

def cask
  @cask
end

Instance Method Details

#basenamePathname

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:



87
88
89
# File 'cask/download.rb', line 87

def basename
  downloader.basename
end

#checksum::Checksum?

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:



43
44
45
# File 'cask/download.rb', line 43

def checksum
  @checksum ||= cask.sha256 if cask.sha256 != :no_check
end

#download_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:



230
# File 'cask/download.rb', line 230

def download_name = cask.token

#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:



224
# File 'cask/download.rb', line 224

def download_queue_name = "#{cask.token} (#{version})"

#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:



227
# File 'cask/download.rb', line 227

def download_queue_type = "Cask"

#downloaded_and_valid?Boolean

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:

  • (Boolean)


206
207
208
209
210
211
# File 'cask/download.rb', line 206

def downloaded_and_valid?
  return false unless super

  quarantine(cached_download)
  true
end

#extract_primary_container(to:, verbose:, container: nil) ⇒ 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:



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
# File 'cask/download.rb', line 103

def extract_primary_container(to:, verbose:, container: nil)
  odebug "Extracting primary container"

  container ||= primary_container
  raise "unexpected nil primary_container" unless container

  odebug "Using container class #{container.class} for #{container.path}"

  if (nested_container = cask.container&.nested)
    Dir.mktmpdir("cask-installer", HOMEBREW_TEMP) do |tmpdir|
      tmpdir = Pathname(tmpdir)
      container.extract(to: tmpdir, basename:, verbose:)

      FileUtils.chmod_R "+rw", tmpdir/nested_container, force: true, verbose: verbose

      UnpackStrategy.detect(tmpdir/nested_container, merge_xattrs: true)
                    .extract_nestedly(to:, verbose:)
    end
  else
    container.extract_nestedly(to:, basename:, verbose:)
  end

  return unless Quarantine.available?

  Quarantine.propagate(from: container.path, to:)
end

#fetch(quiet: nil, verify_download_integrity: true, timeout: nil) ⇒ 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:

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

Returns:



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'cask/download.rb', line 61

def fetch(quiet: nil, verify_download_integrity: true, timeout: nil)
  verify_has_sha if @require_sha
  downloader.quiet! if quiet

  begin
    super(verify_download_integrity: false, timeout:)
  rescue DownloadError => e
    error = CaskError.new("Download failed on Cask '#{cask}' with message: #{e.cause}")
    error.set_backtrace e.backtrace
    raise error
  end

  downloaded_path = cached_download
  quarantine(downloaded_path)
  self.verify_download_integrity(downloaded_path) if verify_download_integrity
  downloaded_path
end

#primary_containerUnpackStrategy

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:



92
93
94
95
96
97
98
99
100
# File 'cask/download.rb', line 92

def primary_container
  @primary_container ||= T.let(
    begin
      downloaded_path = cask.download || fetch(quiet: true)
      UnpackStrategy.detect(downloaded_path, type: cask.container&.type, merge_xattrs: true)
    end,
    T.nilable(UnpackStrategy),
  )
end

#process_rename_operations(target_dir:) ⇒ 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:



131
132
133
134
135
136
137
138
139
140
# File 'cask/download.rb', line 131

def process_rename_operations(target_dir:)
  return if cask.rename.empty?

  odebug "Processing rename operations in #{target_dir}"

  cask.rename.each do |rename_operation|
    odebug "Renaming #{rename_operation.from} to #{rename_operation.to}"
    rename_operation.perform_rename(target_dir)
  end
end

#purge_staged_from_download_queue(command: SystemCommand) ⇒ 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:



153
154
155
156
157
158
159
160
161
162
# File 'cask/download.rb', line 153

def purge_staged_from_download_queue(command: SystemCommand)
  staged_marker = staged_path_from_download_queue_marker
  Utils.gain_permissions_remove(staged_marker, command:) if staged_marker.symlink? || staged_marker.exist?

  staged_path = staged_path_from_download_queue
  Utils.gain_permissions_remove(staged_path, command:) if staged_path.exist?

  staged_path.parent.rmdir_if_possible
  staged_path.parent.parent.rmdir_if_possible
end

#stage_from_download_queue(download, pour:) ⇒ 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:



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'cask/download.rb', line 181

def stage_from_download_queue(download, pour:)
  return unless stage_from_download_queue?(download, pour:)

  purge_staged_from_download_queue
  cask.download ||= download
  extract_primary_container(
    to:        staged_path_from_download_queue,
    verbose:   false,
    container: UnpackStrategy.detect(
      download,
      type:         cask.container&.type,
      merge_xattrs: true,
    ),
  )
  process_rename_operations(target_dir: staged_path_from_download_queue)
  FileUtils.ln_s(staged_path_from_download_queue, staged_path_from_download_queue_marker)
# Catch any exception type here to clean up partial queued extractions.
rescue Exception # rubocop:disable Lint/RescueException
  ignore_interrupts do
    purge_staged_from_download_queue
  end
  raise
end

#stage_from_download_queue?(download, pour:) ⇒ Boolean

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:

Returns:

  • (Boolean)


165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'cask/download.rb', line 165

def stage_from_download_queue?(download, pour:)
  return false unless pour
  return false if cask.staged_path.exist? || staged_path_from_download_queue_marker.exist?

  UnpackStrategy.detect(download, type:         cask.container&.type,
                                  merge_xattrs: true).dependencies.all? do |dependency|
    case dependency
    when Formula
      dependency.any_version_installed? && dependency.optlinked?
    when Cask
      dependency.installed?
    end
  end
end

#staged_path_from_download_queuePathname

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:



143
144
145
# File 'cask/download.rb', line 143

def staged_path_from_download_queue
  HOMEBREW_PREFIX/"var/homebrew/tmp/.caskroom"/cask.staged_path.relative_path_from(Caskroom.path)
end

#staged_path_from_download_queue_markerPathname

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:



148
149
150
# File 'cask/download.rb', line 148

def staged_path_from_download_queue_marker
  Pathname("#{staged_path_from_download_queue}.staged")
end

#time_file_size(timeout: nil) ⇒ Array<([Time, nil], Integer)>

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:

  • timeout (Float, Integer, nil) (defaults to: nil)

Returns:

Raises:

  • (ArgumentError)


80
81
82
83
84
# File 'cask/download.rb', line 80

def time_file_size(timeout: nil)
  raise ArgumentError, "not supported for this download strategy" unless downloader.is_a?(CurlDownloadStrategy)

  T.cast(downloader, CurlDownloadStrategy).resolved_time_file_size(timeout:)
end

#url::URL?

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
37
38
39
40
# File 'cask/download.rb', line 36

def url
  return if (cask_url = cask.url).nil?

  @url ||= ::URL.new(cask_url.to_s, cask_url.specs)
end

#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:



214
215
216
217
218
219
220
221
# File 'cask/download.rb', line 214

def verify_download_integrity(filename)
  if no_checksum_defined? && !official_cask_tap?
    opoo "No checksum defined for cask '#{@cask}', skipping verification."
    return
  end

  super
end

#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:



48
49
50
51
52
# File 'cask/download.rb', line 48

def version
  return if cask.version.nil?

  @version ||= Version.new(cask.version)
end