Module: Utils::Bottles

Extended by:
MacOSOverride
Defined in:
utils/bottles.rb,
extend/os/mac/utils/bottles.rb

Overview

This module is part of an internal API. This module may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this module if possible, as it may be removed or changed without warning.

Helper functions for bottles.

Defined Under Namespace

Modules: MacOSOverride Classes: Collector, Tag, TagSpecification

Class Method Summary collapse

Methods included from MacOSOverride

tag

Class Method Details

.built_as?(formula) ⇒ Boolean

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


30
31
32
33
34
35
# File 'utils/bottles.rb', line 30

def built_as?(formula)
  return false unless formula.latest_version_installed?

  tab = Keg.new(formula.latest_installed_prefix).tab
  tab.built_as_bottle
end

.extname_tag_rebuild(filename) ⇒ Object

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



49
50
51
# File 'utils/bottles.rb', line 49

def extname_tag_rebuild(filename)
  HOMEBREW_BOTTLES_EXTNAME_REGEX.match(filename).to_a
end

.file_from_bottle(bottle_file, file_path) ⇒ Object

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



59
60
61
# File 'utils/bottles.rb', line 59

def file_from_bottle(bottle_file, file_path)
  Utils.popen_read("tar", "--extract", "--to-stdout", "--file", bottle_file, file_path)
end

.file_outdated?(formula, file) ⇒ Boolean

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


37
38
39
40
41
42
43
44
45
46
47
# File 'utils/bottles.rb', line 37

def file_outdated?(formula, file)
  file = file.resolved_path

  filename = file.basename.to_s
  return false if formula.bottle.blank?

  _, bottle_tag, bottle_rebuild = extname_tag_rebuild(filename)
  return false if bottle_tag.blank?

  bottle_tag != formula.bottle.tag.to_s || bottle_rebuild.to_i != formula.bottle.rebuild
end

.formula_contents(bottle_file, name: ) ⇒ Object

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



88
89
90
91
92
93
94
95
96
# File 'utils/bottles.rb', line 88

def formula_contents(bottle_file,
                     name: resolve_formula_names(bottle_file)[0])
  bottle_version = resolve_version bottle_file
  formula_path = "#{name}/#{bottle_version}/.brew/#{name}.rb"
  contents = file_from_bottle(bottle_file, formula_path)
  raise BottleFormulaUnavailableError.new(bottle_file, formula_path) unless $CHILD_STATUS.success?

  contents
end

.load_tab(formula) ⇒ Object

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'utils/bottles.rb', line 107

def load_tab(formula)
  keg = Keg.new(formula.prefix)
  tabfile = keg/AbstractTab::FILENAME
  bottle_json_path = formula.local_bottle_path&.sub(/\.(\d+\.)?tar\.gz$/, ".json")

  if (tab_attributes = formula.bottle_tab_attributes.presence)
    Tab.from_file_content(tab_attributes.to_json, tabfile)
  elsif !tabfile.exist? && bottle_json_path&.exist?
    _, tag, = Utils::Bottles.extname_tag_rebuild(formula.local_bottle_path)
    bottle_hash = JSON.parse(File.read(bottle_json_path))
    tab_json = bottle_hash[formula.full_name]["bottle"]["tags"][tag]["tab"].to_json
    Tab.from_file_content(tab_json, tabfile)
  else
    tab = keg.tab

    tab.runtime_dependencies = begin
      f_runtime_deps = formula.runtime_dependencies(read_from_tab: false)
      Tab.runtime_deps_hash(formula, f_runtime_deps)
    end

    tab
  end
end

.path_resolved_basename(root_url, name, checksum, filename) ⇒ Object

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



98
99
100
101
102
103
104
105
# File 'utils/bottles.rb', line 98

def path_resolved_basename(root_url, name, checksum, filename)
  if root_url.match?(GitHubPackages::URL_REGEX)
    image_name = GitHubPackages.image_formula_name(name)
    ["#{image_name}/blobs/sha256:#{checksum}", filename&.github_packages]
  else
    filename&.url_encode
  end
end

.receipt_path(bottle_file) ⇒ Object

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



53
54
55
56
57
# File 'utils/bottles.rb', line 53

def receipt_path(bottle_file)
  bottle_file_list(bottle_file).find do |line|
    %r{.+/.+/INSTALL_RECEIPT.json}.match?(line)
  end
end

.resolve_formula_names(bottle_file) ⇒ Object

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'utils/bottles.rb', line 63

def resolve_formula_names(bottle_file)
  name = bottle_file_list(bottle_file).first.to_s.split("/").first
  full_name = if (receipt_file_path = receipt_path(bottle_file))
    receipt_file = file_from_bottle(bottle_file, receipt_file_path)
    tap = Tab.from_file_content(receipt_file, "#{bottle_file}/#{receipt_file_path}").tap
    "#{tap}/#{name}" if tap.present? && !tap.core_tap?
  else
    bottle_json_path = Pathname(bottle_file.sub(/\.(\d+\.)?tar\.gz$/, ".json"))
    if bottle_json_path.exist? &&
       (bottle_json_path_contents = bottle_json_path.read.presence) &&
       (bottle_json = JSON.parse(bottle_json_path_contents).presence) &&
       bottle_json.is_a?(Hash)
      bottle_json.keys.first.presence
    end
  end
  full_name ||= name

  [name, full_name]
end

.resolve_version(bottle_file) ⇒ Object

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



83
84
85
86
# File 'utils/bottles.rb', line 83

def resolve_version(bottle_file)
  version = bottle_file_list(bottle_file).first.to_s.split("/").second
  PkgVersion.parse(version)
end

.tag(tag = nil) ⇒ Tag

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Gets the tag for the running OS.

Parameters:

Returns:



16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'utils/bottles.rb', line 16

def tag(tag = nil)
  case tag
  when Symbol
    Tag.from_symbol(tag)
  when Tag
    tag
  else
    @tag ||= Tag.new(
      system: HOMEBREW_SYSTEM.downcase.to_sym,
      arch:   HOMEBREW_PROCESSOR.downcase.to_sym,
    )
  end
end