Class: BottleSpecification Private

Inherits:
Object show all
Includes:
OS::Linux::BottleSpecification, Utils::Output::Mixin
Defined in:
bottle_specification.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.

Constant Summary collapse

ANY_CELLAR =

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.

Relocatable cellar using placeholders, e.g. @@HOMEBREW_PREFIX@@. Requires relocating text files and binaries.

:any
ANY_SKIP_RELOCATION_CELLAR =

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.

Relocatable cellar using placeholders, e.g. @@HOMEBREW_PREFIX@@. Does not need to relocate binaries but still relocates text files.

:any_skip_relocation
RELOCATABLE_CELLARS =

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.let([ANY_CELLAR, ANY_SKIP_RELOCATION_CELLAR].freeze, T::Array[Symbol])

Instance Attribute 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_outside_github_actions, #opoo_without_github_actions_annotation, #pretty_deprecated, #pretty_disabled, #pretty_duration, #pretty_install_status, #pretty_installed, #pretty_uninstalled, #pretty_upgradable, #pretty_warning

Constructor Details

#initializevoid

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.



30
31
32
33
34
35
36
# File 'bottle_specification.rb', line 30

def initialize
  @rebuild = T.let(0, Integer)
  @repository = T.let(Homebrew::DEFAULT_REPOSITORY, String)
  @collector = T.let(Utils::Bottles::Collector.new, Utils::Bottles::Collector)
  @root_url_specs = T.let({}, T::Hash[Symbol, T.untyped])
  @root_url = T.let(nil, T.nilable(String))
end

Instance Attribute Details

#collectorUtils::Bottles::Collector (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.



21
22
23
# File 'bottle_specification.rb', line 21

def collector
  @collector
end

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



27
28
29
# File 'bottle_specification.rb', line 27

def repository
  @repository
end

#root_url_specsHash{Symbol => T.untyped} (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:



24
25
26
# File 'bottle_specification.rb', line 24

def root_url_specs
  @root_url_specs
end

#tapTap?

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:



18
19
20
# File 'bottle_specification.rb', line 18

def tap
  @tap
end

Instance Method Details

#checksumsArray<Hash>

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:



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'bottle_specification.rb', line 154

def checksums
  tags = collector.tags.sort_by do |tag|
    version = tag.to_macos_version
    # Give `arm64` bottles a higher priority so they are first.
    priority = (tag.arch == :arm64) ? 3 : 2
    "#{priority}.#{version}_#{tag}"
  rescue MacOSVersion::Error
    # Sort non-macOS tags below macOS tags, and arm64 tags before other tags.
    priority = (tag.arch == :arm64) ? 1 : 0
    "#{priority}.#{tag}"
  end
  tags.reverse.map do |tag|
    spec = collector.specification_for(tag)
    odie "Specification for tag #{tag} is nil" if spec.nil?
    {
      "tag"    => spec.tag.to_sym,
      "digest" => spec.checksum,
      "cellar" => spec.cellar,
    }
  end
end

#compatible_locations?(tag: Utils::Bottles.tag) ⇒ 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)


84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'bottle_specification.rb', line 84

def compatible_locations?(tag: Utils::Bottles.tag)
  cellar = tag_to_cellar(tag)

  return true if RELOCATABLE_CELLARS.include?(cellar)

  prefix = Pathname(cellar.to_s).parent.to_s

  cellar_relocatable = cellar.size >= HOMEBREW_CELLAR.to_s.size && ENV["HOMEBREW_RELOCATE_BUILD_PREFIX"].present?
  prefix_relocatable = prefix.size >= HOMEBREW_PREFIX.to_s.size && ENV["HOMEBREW_RELOCATE_BUILD_PREFIX"].present?

  compatible_cellar = cellar == HOMEBREW_CELLAR.to_s || cellar_relocatable
  compatible_prefix = prefix == HOMEBREW_PREFIX.to_s || prefix_relocatable

  compatible_cellar && compatible_prefix
end

#rebuild(val = T.unsafe(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:

  • val (Integer) (defaults to: T.unsafe(nil))

Returns:



39
40
41
# File 'bottle_specification.rb', line 39

def rebuild(val = T.unsafe(nil))
  val.nil? ? @rebuild : @rebuild = val
end

#root_url(var = nil, specs = {}) ⇒ 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.

Parameters:

  • var (String, nil) (defaults to: nil)
  • specs (Hash{Symbol => T.untyped}) (defaults to: {})

Returns:



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'bottle_specification.rb', line 44

def root_url(var = nil, specs = {})
  if var.nil?
    @root_url ||= if (github_packages_url = GitHubPackages.root_url_if_match(Homebrew::EnvConfig.bottle_domain))
      github_packages_url
    else
      Homebrew::EnvConfig.bottle_domain
    end
  else
    @root_url = if (github_packages_url = GitHubPackages.root_url_if_match(var))
      github_packages_url
    else
      var
    end
    @root_url_specs.merge!(specs)
    @root_url
  end
end

#sha256(hash) ⇒ 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.

Checksum methods in the DSL's bottle block take a Hash, which indicates the platform the checksum applies on. Example bottle block syntax: bottle do sha256 cellar: :any_skip_relocation, big_sur: "69489ae397e4645..." sha256 cellar: :any, catalina: "449de5ea35d0e94..." end

Parameters:



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'bottle_specification.rb', line 124

def sha256(hash)
  sha256_regex = /^[a-f0-9]{64}$/i

  # find new `sha256 big_sur: "69489ae397e4645..."` format
  tag, digest = hash.find do |key, value|
    # Don't use `odie` in this case. We want to be able to catch this exception
    # in runtime when getting committed version info in formula auditor
    raise LegacyDSLError.new(:sha256, hash) if key.is_a?(String) && key.match?(sha256_regex) && value.is_a?(Symbol)

    key.is_a?(Symbol) && value.is_a?(String) && value.match?(sha256_regex)
  end

  odie "Invalid sha256 hash: #{digest}" if !tag || !digest

  tag = Utils::Bottles::Tag.from_symbol(T.cast(tag, Symbol))

  cellar = hash[:cellar] || tag.default_cellar

  collector.add(tag, checksum: Checksum.new(digest.to_s), cellar:)
end

#skip_relocation?(tag: Utils::Bottles.tag, tab: nil) ⇒ 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.

Does the Bottle this BottleSpecification belongs to need to be relocated?

This will always return false on Linux unless a tab is provided that reports the bottle was built with Homebrew 5.1.15 or newer. The caller must make sure that the provided tab is for the requested tag.

Parameters:

Returns:

  • (Boolean)


106
107
108
109
# File 'bottle_specification.rb', line 106

def skip_relocation?(tag: Utils::Bottles.tag, tab: nil)
  spec = collector.specification_for(tag)
  spec&.cellar == ANY_SKIP_RELOCATION_CELLAR
end

#tag?(tag, no_older_versions: false) ⇒ 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)


112
113
114
# File 'bottle_specification.rb', line 112

def tag?(tag, no_older_versions: false)
  collector.tag?(tag, no_older_versions:)
end

#tag_specification_for(tag, no_older_versions: false) ⇒ Utils::Bottles::TagSpecification?

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
# File 'bottle_specification.rb', line 149

def tag_specification_for(tag, no_older_versions: false)
  collector.specification_for(tag, no_older_versions:)
end

#tag_to_cellar(tag = Utils::Bottles.tag) ⇒ Symbol, 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.

Parameters:

Returns:



74
75
76
77
78
79
80
81
# File 'bottle_specification.rb', line 74

def tag_to_cellar(tag = Utils::Bottles.tag)
  spec = collector.specification_for(tag)
  if spec.present?
    spec.cellar
  else
    tag.default_cellar
  end
end