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

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

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:



14
15
16
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
# File 'api/cask/cask_struct_generator.rb', line 14

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:



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'api/cask/cask_struct_generator.rb', line 146

def process_artifacts(artifacts)
  artifacts.map do |artifact|
    key = T.must(artifact.keys.first)

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



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
137
138
139
140
141
142
143
# File 'api/cask/cask_struct_generator.rb', line 110

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:



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

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