Class: BottleSpecification

Inherits:
Object show all
Includes:
OS::Linux::BottleSpecification, Utils::Output::Mixin
Defined in:
bottle_specification.rb

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

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

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



32
33
34
35
36
37
38
# File 'bottle_specification.rb', line 32

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.



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

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:



29
30
31
# File 'bottle_specification.rb', line 29

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:



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

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:



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

def tap
  @tap
end

Class Method Details

.compatible_locations?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 bottles built in the default prefix can be installed here.

Returns:

  • (Boolean)


87
# File 'bottle_specification.rb', line 87

def self.compatible_locations? = new.compatible_locations?

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:



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'bottle_specification.rb', line 167

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, built_prefix: nil, padded_prefix: 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:

  • tag (Utils::Bottles::Tag) (defaults to: Utils::Bottles.tag)
  • built_prefix (String, nil) (defaults to: nil)
  • padded_prefix (Boolean) (defaults to: false)

Returns:

  • (Boolean)


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'bottle_specification.rb', line 93

def compatible_locations?(tag: Utils::Bottles.tag, built_prefix: nil, padded_prefix: false)
  return false if padded_prefix && built_prefix.nil?

  cellar = padded_prefix ? "#{built_prefix}/Cellar" : tag_to_cellar(tag)

  return true if RELOCATABLE_CELLARS.include?(cellar)

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

  # Raw prefix strings are patched in place, so the byte length decides.
  relocatable = !Homebrew::EnvConfig.no_relocate_build_prefix?
  cellar_relocatable = relocatable && cellar.to_s.bytesize >= HOMEBREW_CELLAR.to_s.bytesize
  prefix_relocatable = relocatable && prefix.bytesize >= HOMEBREW_PREFIX.to_s.bytesize

  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 = 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, nil) (defaults to: nil)

Returns:



41
42
43
# File 'bottle_specification.rb', line 41

def rebuild(val = 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:



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

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, monterey: "449de5ea35d0e94..." end

Parameters:



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'bottle_specification.rb', line 137

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)


119
120
121
122
# File 'bottle_specification.rb', line 119

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)


125
126
127
# File 'bottle_specification.rb', line 125

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:



162
163
164
# File 'bottle_specification.rb', line 162

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:



76
77
78
79
80
81
82
83
# File 'bottle_specification.rb', line 76

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