Module: Homebrew::API::Cask::CaskStructGenerator Private

Extended by:
Utils::Output::Mixin
Includes:
Utils::Output::Mixin
Defined in:
api/cask/cask_struct_generator.rb

Overview

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

Methods for generating CaskStruct instances from API data.

Class 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_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

Class Method Details

.generate_cask_struct_hash(hash, bottle_tag: Homebrew::SimulateSystem.current_tag, ignore_types: false) ⇒ CaskStruct

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.

Note:

this will be used to load installed cask JSON files,

so it must never fail with older JSON API versions

Parameters:

  • hash (Hash{String => T.untyped})
  • bottle_tag (Utils::Bottles::Tag) (defaults to: Homebrew::SimulateSystem.current_tag)
  • ignore_types (Boolean) (defaults to: false)

Returns:



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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
# File 'api/cask/cask_struct_generator.rb', line 17

def generate_cask_struct_hash(hash, bottle_tag: Homebrew::SimulateSystem.current_tag, ignore_types: false)
  hash = Homebrew::API.merge_variations(hash, bottle_tag:).dup.deep_symbolize_keys.transform_keys(&:to_s)
  language_variations = T.cast(
    hash.delete("language_variations"),
    T.nilable(T::Array[T::Hash[Symbol, T.untyped]]),
  )
  language_structs = language_variations&.map do |variation|
    language_hash = hash.merge(variation.except(:languages, :default, :value).transform_keys(&:to_s))
    [variation, generate_cask_struct_hash(language_hash, bottle_tag:, ignore_types:)]
  end

  hash["conflicts_with_args"] = hash["conflicts_with"]&.to_h

  hash["container_args"] = hash["container"]&.to_h do |key, value|
    next [key, value.to_sym] if key == :type

    [key, value]
  end

  if (depends_on = hash["depends_on"])
    hash["depends_on_args"] = process_depends_on(depends_on)
  end

  if (deprecate_args = hash["deprecate_args"])
    deprecate_args = deprecate_args.dup
    deprecate_args[:because] =
      DeprecateDisable.to_reason_string_or_symbol(deprecate_args[:because], type: :cask)
    hash["deprecate_args"] = deprecate_args
  end

  if (disable_args = hash["disable_args"])
    disable_args = disable_args.dup
    disable_args[:because] = DeprecateDisable.to_reason_string_or_symbol(disable_args[:because], type: :cask)
    hash["disable_args"] = disable_args
  end

  hash["names"] = hash["name"]

  if (artifacts = hash["artifacts"])
    hash["raw_artifacts"] = process_artifacts(artifacts)
  end

  hash["raw_caveats"] = hash["caveats"]

  hash["renames"] = hash["rename"]&.map do |operation|
    [operation[:from], operation[:to]]
  end

  hash["ruby_source_checksum"] = {
    sha256: hash.dig("ruby_source_checksum", :sha256),
  }.compact

  hash["ruby_source_path"] = hash["ruby_source_path"]&.to_s

  hash["sha256"] = hash["sha256"].to_s
  hash["sha256"] = :no_check if hash["sha256"] == "no_check"

  hash["tap_string"] = hash["tap"]

  hash["url_args"] = [hash["url"].to_s]

  if (url_specs = hash["url_specs"])
    hash["url_kwargs"] = process_url_specs(url_specs)
  end

  # Should match CaskStruct::PREDICATES
  hash["auto_updates_present"] = hash["auto_updates"].present?
  hash["caveats_present"] = hash["caveats"].present?
  hash["conflicts_present"] = hash["conflicts_with"].present?
  hash["container_present"] = hash["container"].present?
  hash["depends_on_present"] = hash["depends_on_args"].present?
  hash["deprecate_present"] = hash["deprecate_args"].present?
  hash["desc_present"] = hash["desc"].present?
  hash["disable_present"] = hash["disable_args"].present?
  hash["homepage_present"] = hash["homepage"].present?

  cask_struct = CaskStruct.from_hash(hash, ignore_types:)
  return cask_struct if language_structs.blank?

  serialised_cask = cask_struct.serialize
  processed_language_variations = language_structs.map do |variation, language_struct|
    language_data = language_struct.serialize.reject do |key, value|
      serialised_cask[key] == value
    end
    {
      languages: T.cast(variation[:languages], T::Array[String]),
      default:   variation[:default] == true,
      value:     T.cast(variation[:value], T.nilable(String)),
      overrides: language_data,
    }
  end

  CaskStruct.deserialize(serialised_cask.merge("language_variations" => processed_language_variations))
end

.process_artifacts(artifacts) ⇒ Array<CaskStruct::ArtifactArgs>

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:



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'api/cask/cask_struct_generator.rb', line 149

def process_artifacts(artifacts)
  artifacts.filter_map do |artifact|
    key = artifact.keys.find { |artifact_key| artifact_key != :target }
    if key.nil?
      odebug "Ignoring cask artifact without a stanza key: #{artifact.keys.inspect}"
      next
    end
    unless ::Cask::DSL::ARTIFACT_DSL_METHODS.include?(key)
      odebug "Ignoring unsupported cask artifact stanza: #{key}"
      next
    end

    # Pass an empty block to artifacts like postflight that can't be loaded from the API,
    # but need to be set to something.
    next [key, [], {}, Homebrew::API::CaskStruct::EMPTY_BLOCK] if artifact[key].nil?

    args = artifact[key]
    kwargs = if args.last.is_a?(Hash)
      args.pop
    else
      {}
    end
    [key, args, kwargs, nil]
  end
end

.process_depends_on(depends_on) ⇒ CaskStruct::DependsOnArgs

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:



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'api/cask/cask_struct_generator.rb', line 113

def process_depends_on(depends_on)
  depends_on.to_h do |key, value|
    # Arch dependencies are encoded like `{ type: :intel, bits: 64 }`
    # but `depends_on arch:` only accepts `:intel` or `:arm64`
    if key == :arch
      next [:arch, :intel] if value.first[:type].to_sym == :intel

      next [:arch, :arm64]
    end
    next [key, :any] if key == :linux

    next [key, value] unless [:macos, :maximum_macos].include?(key)

    value = value.to_h if value.is_a?(MacOSRequirement)
    dep_type = value.keys.first
    next [key, :any] unless dep_type

    if dep_type.to_sym == :==
      version_symbols = value[dep_type].filter_map do |version|
        MacOSVersion::SYMBOLS.key(version)
      end
      next [key, version_symbols.presence]
    end

    version_symbol = value[dep_type].first
    next [key, :any] if version_symbol.blank?

    version_symbol = MacOSVersion::SYMBOLS.key(version_symbol)
    next [key, version_symbol] if [:>=, :<=].include?(dep_type.to_sym) && version_symbol

    version_dep = "#{dep_type} :#{version_symbol}" if version_symbol
    [key, version_dep]
  end.compact
end

.process_url_specs(url_specs) ⇒ Hash{Symbol => 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.

Parameters:

Returns:



176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'api/cask/cask_struct_generator.rb', line 176

def process_url_specs(url_specs)
  url_specs.to_h do |key, value|
    value = case key
    when :user_agent
      Utils.convert_to_string_or_symbol(value)
    when :using
      value.to_sym
    else
      value
    end

    [key, value]
  end.compact_blank
end