Class: Cask::Artifact::AbstractArtifact Abstract Private

Inherits:
Object
  • Object
show all
Extended by:
T::Helpers, Utils::Output::Mixin
Includes:
Comparable, Utils::Output::Mixin
Defined in:
cask/artifact/abstract_artifact.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.

This class is abstract.

It cannot be directly instantiated. Subclasses must implement the abstract methods below.

Abstract superclass for all artifacts.

Constant Summary collapse

DirectivesType =

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

T.anything or the union of all possible argument types would be better choice, but it's convenient to be able to invoke .inspect, .to_s, etc. without the overhead of type guards.

T.type_alias { Object }

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils::Output::Mixin

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

Constructor Details

#initialize(cask, *dsl_args) ⇒ 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)
  • dsl_args (T.anything)


195
196
197
198
199
200
201
202
203
# File 'cask/artifact/abstract_artifact.rb', line 195

def initialize(cask, *dsl_args)
  @cask = cask
  @dirmethod = T.let(nil, T.nilable(Symbol))
  @dsl_args = T.let(dsl_args.deep_dup, T::Array[T.anything])
  @dsl_key = T.let(nil, T.nilable(Symbol))
  @english_article = T.let(nil, T.nilable(String))
  @english_name = T.let(nil, T.nilable(String))
  @sort_order = T.let(nil, T.nilable(T::Hash[T.class_of(AbstractArtifact), Integer]))
end

Instance Attribute Details

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



192
193
194
# File 'cask/artifact/abstract_artifact.rb', line 192

def cask
  @cask
end

Class Method Details

.dirmethod ⇒ Symbol

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:



44
45
46
# File 'cask/artifact/abstract_artifact.rb', line 44

def self.dirmethod
  @dirmethod ||= T.let(:"#{dsl_key}dir", T.nilable(Symbol))
end

.dsl_key ⇒ Symbol

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
40
41
# File 'cask/artifact/abstract_artifact.rb', line 39

def self.dsl_key
  @dsl_key ||= T.let(to_s.sub(/^.*:/, "").gsub(/(.)([A-Z])/, '\1_\2').downcase.to_sym, T.nilable(Symbol))
end

.english_article ⇒ 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:



34
35
36
# File 'cask/artifact/abstract_artifact.rb', line 34

def self.english_article
  @english_article ||= T.let(/^[aeiou]/i.match?(english_name) ? "an" : "a", T.nilable(String))
end

.english_name ⇒ 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:



29
30
31
# File 'cask/artifact/abstract_artifact.rb', line 29

def self.english_name
  @english_name ||= T.let(to_s.sub(/^.*:/, "").gsub(/(.)([A-Z])/, '\1 \2'), T.nilable(String))
end

.read_script_arguments(arguments, stanza, default_arguments = {}, override_arguments = {}, key = nil) ⇒ Array<([String, nil], Hash{Symbol => T.untyped})>

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.

TODO:

this sort of logic would make more sense in dsl.rb, or a constructor called from dsl.rb, so long as that isn't slow.

Parameters:

Returns:



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'cask/artifact/abstract_artifact.rb', line 154

def self.read_script_arguments(arguments, stanza, default_arguments = {}, override_arguments = {}, key = nil)
  # TODO: when stanza names are harmonized with class names,
  #       stanza may not be needed as an explicit argument
  description = key ? "#{stanza} #{key.inspect}" : stanza.to_s

  arguments = case arguments
  when String then { executable: arguments } # backward-compatible string value
  when Hash then arguments.dup # Avoid mutating the original argument
  else odie "Unsupported arguments type #{arguments.class}"
  end

  # key sanity
  permitted_keys = [:args, :input, :executable, :must_succeed, :sudo, :print_stdout, :print_stderr]
  unknown_keys = arguments.keys - permitted_keys
  unless unknown_keys.empty?
    opoo "Unknown arguments to #{description} -- " \
         "#{unknown_keys.inspect} (ignored). Running " \
         "`brew update; brew cleanup` will likely fix it."
  end
  arguments.select! { |k| permitted_keys.include?(k) }

  # key warnings
  override_keys = override_arguments.keys
  ignored_keys = arguments.keys & override_keys
  unless ignored_keys.empty?
    onoe "Some arguments to #{description} will be ignored -- :#{unknown_keys.inspect} (overridden)."
  end

  # extract executable
  executable = arguments.key?(:executable) ? arguments.delete(:executable) : nil

  arguments = default_arguments.merge arguments
  arguments.merge! override_arguments

  [executable, arguments]
end

Instance Method Details

#cask_sandbox(network_access_allowed: false) ⇒ Sandbox?

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:

  • network_access_allowed (Boolean) (defaults to: false)

Returns:



211
212
213
214
215
216
217
218
# File 'cask/artifact/abstract_artifact.rb', line 211

def cask_sandbox(network_access_allowed: false)
  return unless Sandbox.use_for?("running cask artifact operations")

  Sandbox.new.tap do |sandbox|
    sandbox.allow_read(path: cask.staged_path, type: :subpath)
    sandbox.add_install_hook_rules(network_access_allowed:)
  end
end

#config ⇒ Config

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:



206
207
208
# File 'cask/artifact/abstract_artifact.rb', line 206

def config
  cask.config
end

#requires_sudo? ⇒ 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.

Whether installation always requires elevated privileges.

Returns:

  • (Boolean)


53
# File 'cask/artifact/abstract_artifact.rb', line 53

def requires_sudo? = false

#run_cask_sandbox(sandbox, payload, passthrough_stdin: true, child_message_handler: 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:

  • sandbox (Sandbox)
  • payload (Hash{String => T.untyped})
  • passthrough_stdin (Boolean) (defaults to: true)
  • child_message_handler (T.proc.params(message: String).returns(T.nilable(String)), nil) (defaults to: nil)


228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'cask/artifact/abstract_artifact.rb', line 228

def run_cask_sandbox(sandbox, payload, passthrough_stdin: true, child_message_handler: nil)
  # Formulae sandbox the complete `postinstall.rb` process. Do the same
  # for cask operations so Ruby file changes and every command share one
  # profile, instead of forwarding command input and output through files.
  sandbox_root = HOMEBREW_PREFIX/"var/homebrew/sandbox"
  sandbox_root.mkpath
  Dir.mktmpdir("cask-", sandbox_root) do |temporary_directory|
    temporary_path = Pathname(temporary_directory)
    home = temporary_path/"home"
    home.mkpath
    sandbox.allow_write_path(home)
    payload_json = JSON.generate(payload)
    payload_path = temporary_path/"payload.json"
    payload_path.write(payload_json, mode: "wx")
    sandbox.allow_read(path: payload_path)

    # The payload carries only structured data, not a cask `.rb` file.
    # Set HOME before starting this child so its boot process and any
    # commands it runs cannot discover the user's real home directory.
    Sandbox.with_preserved_brew_file do
      sandbox.run(
        "/usr/bin/env",
        "HOME=#{home}",
        "nice",
        *Sandbox.ruby_command("cask_artifact.rb", payload_path, Digest::SHA256.hexdigest(payload_json)),
        passthrough_stdin:,
        child_message_handler:,
      )
    end
  end
end

#sort_order ⇒ Hash{T.class_of(AbstractArtifact) => 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.

Returns:



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
# File 'cask/artifact/abstract_artifact.rb', line 76

def sort_order
  @sort_order ||= T.let(
    [
      PreflightSteps,
      UninstallPreflightSteps,
      PreflightBlock,
      # The `uninstall` stanza should be run first, as it may
      # depend on other artifacts still being installed.
      Uninstall,
      GeneratedScript,
      Installer,
      # `pkg` should be run before `binary`, so
      # targets are created prior to linking.
      # `pkg` should be run before `app`, since an `app` could
      # contain a nested installer (e.g. `wireshark`).
      Pkg,
      [
        App,
        AppImage,
        Suite,
        Artifact,
        Colorpicker,
        Prefpane,
        Qlplugin,
        Mdimporter,
        Dictionary,
        Font,
        Service,
        InputMethod,
        InternetPlugin,
        KeyboardLayout,
        AudioUnitPlugin,
        VstPlugin,
        Vst3Plugin,
        ScreenSaver,
      ],
      [
        Binary,
        CommandWrapper,
      ],
      Manpage,
      [
        BashCompletion,
        ZshCompletion,
        FishCompletion,
        PwshCompletion,
      ],
      GeneratedCompletion,
      PostflightSteps,
      UninstallPostflightSteps,
      PostflightBlock,
      Zap,
    ].each_with_index.flat_map { |classes, i| Array(classes).map { |c| [c, i] } }.to_h,
    T.nilable(T::Hash[T.class_of(AbstractArtifact), Integer]),
  )
end

#staged_path_join_executable(path) ⇒ 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:

Returns:



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'cask/artifact/abstract_artifact.rb', line 56

def staged_path_join_executable(path)
  path = Pathname(path)
  path = path.expand_path if path.to_s.start_with?("~")

  absolute_path = if path.absolute?
    path
  else
    cask.staged_path.join(path)
  end

  FileUtils.chmod "+x", absolute_path if absolute_path.exist? && !absolute_path.executable?

  if absolute_path.exist?
    absolute_path
  else
    path
  end
end

#summarize ⇒ 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.

This method is abstract.

Returns:



49
# File 'cask/artifact/abstract_artifact.rb', line 49

def summarize; end

#to_args ⇒ Array<T.anything>

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:



266
267
268
# File 'cask/artifact/abstract_artifact.rb', line 266

def to_args
  @dsl_args.compact_blank
end