mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Port Homebrew::DevCmd::Bottle
This commit is contained in:
parent
0f2efd3939
commit
ee0c967ce0
@ -1,6 +1,7 @@
|
|||||||
# typed: true
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "abstract_command"
|
||||||
require "formula"
|
require "formula"
|
||||||
require "utils/bottles"
|
require "utils/bottles"
|
||||||
require "tab"
|
require "tab"
|
||||||
@ -13,7 +14,12 @@ require "utils/gzip"
|
|||||||
require "api"
|
require "api"
|
||||||
require "extend/hash/deep_merge"
|
require "extend/hash/deep_merge"
|
||||||
|
|
||||||
BOTTLE_ERB = <<-EOS.freeze
|
module Homebrew
|
||||||
|
module DevCmd
|
||||||
|
class Bottle < AbstractCommand
|
||||||
|
include FileUtils
|
||||||
|
|
||||||
|
BOTTLE_ERB = <<-EOS.freeze
|
||||||
bottle do
|
bottle do
|
||||||
<% if [HOMEBREW_BOTTLE_DEFAULT_DOMAIN.to_s,
|
<% if [HOMEBREW_BOTTLE_DEFAULT_DOMAIN.to_s,
|
||||||
"#{HOMEBREW_BOTTLE_DEFAULT_DOMAIN}/bottles"].exclude?(root_url) %>
|
"#{HOMEBREW_BOTTLE_DEFAULT_DOMAIN}/bottles"].exclude?(root_url) %>
|
||||||
@ -28,18 +34,15 @@ BOTTLE_ERB = <<-EOS.freeze
|
|||||||
<%= line %>
|
<%= line %>
|
||||||
<% end %>
|
<% end %>
|
||||||
end
|
end
|
||||||
EOS
|
EOS
|
||||||
|
|
||||||
MAXIMUM_STRING_MATCHES = 100
|
MAXIMUM_STRING_MATCHES = 100
|
||||||
|
|
||||||
ALLOWABLE_HOMEBREW_REPOSITORY_LINKS = [
|
ALLOWABLE_HOMEBREW_REPOSITORY_LINKS = [
|
||||||
%r{#{Regexp.escape(HOMEBREW_LIBRARY)}/Homebrew/os/(mac|linux)/pkgconfig},
|
%r{#{Regexp.escape(HOMEBREW_LIBRARY)}/Homebrew/os/(mac|linux)/pkgconfig},
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
module Homebrew
|
cmd_args do
|
||||||
sig { returns(CLI::Parser) }
|
|
||||||
def self.bottle_args
|
|
||||||
Homebrew::CLI::Parser.new do
|
|
||||||
description <<~EOS
|
description <<~EOS
|
||||||
Generate a bottle (binary package) from a formula that was installed with
|
Generate a bottle (binary package) from a formula that was installed with
|
||||||
`--build-bottle`.
|
`--build-bottle`.
|
||||||
@ -89,24 +92,22 @@ module Homebrew
|
|||||||
|
|
||||||
named_args [:installed_formula, :file], min: 1, without_api: true
|
named_args [:installed_formula, :file], min: 1, without_api: true
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def self.bottle
|
|
||||||
args = bottle_args.parse
|
|
||||||
|
|
||||||
|
sig { override.void }
|
||||||
|
def run
|
||||||
if args.merge?
|
if args.merge?
|
||||||
Homebrew.install_bundler_gems!(groups: ["ast"])
|
Homebrew.install_bundler_gems!(groups: ["ast"])
|
||||||
return merge(args:)
|
return merge
|
||||||
end
|
end
|
||||||
|
|
||||||
gnu_tar_formula_ensure_installed_if_needed!(only_json_tab: args.only_json_tab?)
|
gnu_tar_formula_ensure_installed_if_needed!
|
||||||
|
|
||||||
args.named.to_resolved_formulae(uniq: false).each do |formula|
|
args.named.to_resolved_formulae(uniq: false).each do |formula|
|
||||||
bottle_formula formula, args:
|
bottle_formula formula
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.keg_contain?(string, keg, ignores, formula_and_runtime_deps_names = nil, args:)
|
def keg_contain?(string, keg, ignores, formula_and_runtime_deps_names = nil)
|
||||||
@put_string_exists_header, @put_filenames = nil
|
@put_string_exists_header, @put_filenames = nil
|
||||||
|
|
||||||
print_filename = lambda do |str, filename|
|
print_filename = lambda do |str, filename|
|
||||||
@ -138,7 +139,8 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
text_matches = Keg.text_matches_in_file(file, string, ignores, linked_libraries, formula_and_runtime_deps_names)
|
text_matches = Keg.text_matches_in_file(file, string, ignores, linked_libraries,
|
||||||
|
formula_and_runtime_deps_names)
|
||||||
result = true if text_matches.any?
|
result = true if text_matches.any?
|
||||||
|
|
||||||
next if !args.verbose? || text_matches.empty?
|
next if !args.verbose? || text_matches.empty?
|
||||||
@ -153,10 +155,10 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
keg_contain_absolute_symlink_starting_with?(string, keg, args:) || result
|
keg_contain_absolute_symlink_starting_with?(string, keg) || result
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.keg_contain_absolute_symlink_starting_with?(string, keg, args:)
|
def keg_contain_absolute_symlink_starting_with?(string, keg)
|
||||||
absolute_symlinks_start_with_string = []
|
absolute_symlinks_start_with_string = []
|
||||||
keg.find do |pn|
|
keg.find do |pn|
|
||||||
next if !pn.symlink? || !(link = pn.readlink).absolute?
|
next if !pn.symlink? || !(link = pn.readlink).absolute?
|
||||||
@ -174,7 +176,7 @@ module Homebrew
|
|||||||
!absolute_symlinks_start_with_string.empty?
|
!absolute_symlinks_start_with_string.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.cellar_parameter_needed?(cellar)
|
def cellar_parameter_needed?(cellar)
|
||||||
default_cellars = [
|
default_cellars = [
|
||||||
Homebrew::DEFAULT_MACOS_CELLAR,
|
Homebrew::DEFAULT_MACOS_CELLAR,
|
||||||
Homebrew::DEFAULT_MACOS_ARM_CELLAR,
|
Homebrew::DEFAULT_MACOS_ARM_CELLAR,
|
||||||
@ -183,7 +185,7 @@ module Homebrew
|
|||||||
cellar.present? && default_cellars.exclude?(cellar)
|
cellar.present? && default_cellars.exclude?(cellar)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.generate_sha256_line(tag, digest, cellar, tag_column, digest_column)
|
def generate_sha256_line(tag, digest, cellar, tag_column, digest_column)
|
||||||
line = "sha256 "
|
line = "sha256 "
|
||||||
tag_column += line.length
|
tag_column += line.length
|
||||||
digest_column += line.length
|
digest_column += line.length
|
||||||
@ -198,7 +200,7 @@ module Homebrew
|
|||||||
%Q(#{line}"#{digest}")
|
%Q(#{line}"#{digest}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.bottle_output(bottle, root_url_using)
|
def bottle_output(bottle, root_url_using)
|
||||||
cellars = bottle.checksums.filter_map do |checksum|
|
cellars = bottle.checksums.filter_map do |checksum|
|
||||||
cellar = checksum["cellar"]
|
cellar = checksum["cellar"]
|
||||||
next unless cellar_parameter_needed? cellar
|
next unless cellar_parameter_needed? cellar
|
||||||
@ -226,24 +228,24 @@ module Homebrew
|
|||||||
erb.result(erb_binding).gsub(/^\s*$\n/, "")
|
erb.result(erb_binding).gsub(/^\s*$\n/, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.sudo_purge
|
def sudo_purge
|
||||||
return unless ENV["HOMEBREW_BOTTLE_SUDO_PURGE"]
|
return unless ENV["HOMEBREW_BOTTLE_SUDO_PURGE"]
|
||||||
|
|
||||||
system "/usr/bin/sudo", "--non-interactive", "/usr/sbin/purge"
|
system "/usr/bin/sudo", "--non-interactive", "/usr/sbin/purge"
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.tar_args
|
def tar_args
|
||||||
[].freeze
|
[].freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(gnu_tar_formula: Formula).returns(String) }
|
sig { params(gnu_tar_formula: Formula).returns(String) }
|
||||||
def self.gnu_tar(gnu_tar_formula)
|
def gnu_tar(gnu_tar_formula)
|
||||||
"#{gnu_tar_formula.opt_bin}/tar"
|
"#{gnu_tar_formula.opt_bin}/tar"
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(mtime: String).returns(T::Array[String]) }
|
sig { params(mtime: String).returns(T::Array[String]) }
|
||||||
def self.reproducible_gnutar_args(mtime)
|
def reproducible_gnutar_args(mtime)
|
||||||
# Ensure gnu tar is set up for reproducibility.
|
# Ensure gnu tar is set up for reproducibility.
|
||||||
# https://reproducible-builds.org/docs/archives/
|
# https://reproducible-builds.org/docs/archives/
|
||||||
[
|
[
|
||||||
@ -260,8 +262,8 @@ module Homebrew
|
|||||||
].freeze
|
].freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(only_json_tab: T::Boolean).returns(T.nilable(Formula)) }
|
sig { returns(T.nilable(Formula)) }
|
||||||
def self.gnu_tar_formula_ensure_installed_if_needed!(only_json_tab:)
|
def gnu_tar_formula_ensure_installed_if_needed!
|
||||||
gnu_tar_formula = begin
|
gnu_tar_formula = begin
|
||||||
Formula["gnu-tar"]
|
Formula["gnu-tar"]
|
||||||
rescue FormulaUnavailableError
|
rescue FormulaUnavailableError
|
||||||
@ -274,21 +276,21 @@ module Homebrew
|
|||||||
gnu_tar_formula
|
gnu_tar_formula
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(args: T.untyped, mtime: String).returns([String, T::Array[String]]) }
|
sig { params(mtime: String).returns([String, T::Array[String]]) }
|
||||||
def self.setup_tar_and_args!(args, mtime)
|
def setup_tar_and_args!(mtime)
|
||||||
# Without --only-json-tab bottles are never reproducible
|
# Without --only-json-tab bottles are never reproducible
|
||||||
default_tar_args = ["tar", tar_args].freeze
|
default_tar_args = ["tar", tar_args].freeze
|
||||||
return default_tar_args unless args.only_json_tab?
|
return default_tar_args unless args.only_json_tab?
|
||||||
|
|
||||||
# Use gnu-tar as it can be set up for reproducibility better than libarchive
|
# Use gnu-tar as it can be set up for reproducibility better than libarchive
|
||||||
# and to be consistent between macOS and Linux.
|
# and to be consistent between macOS and Linux.
|
||||||
gnu_tar_formula = gnu_tar_formula_ensure_installed_if_needed!(only_json_tab: args.only_json_tab?)
|
gnu_tar_formula = gnu_tar_formula_ensure_installed_if_needed!
|
||||||
return default_tar_args if gnu_tar_formula.blank?
|
return default_tar_args if gnu_tar_formula.blank?
|
||||||
|
|
||||||
[gnu_tar(gnu_tar_formula), reproducible_gnutar_args(mtime)].freeze
|
[gnu_tar(gnu_tar_formula), reproducible_gnutar_args(mtime)].freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.formula_ignores(formula)
|
def formula_ignores(formula)
|
||||||
ignores = []
|
ignores = []
|
||||||
cellar_regex = Regexp.escape(HOMEBREW_CELLAR)
|
cellar_regex = Regexp.escape(HOMEBREW_CELLAR)
|
||||||
prefix_regex = Regexp.escape(HOMEBREW_PREFIX)
|
prefix_regex = Regexp.escape(HOMEBREW_PREFIX)
|
||||||
@ -318,7 +320,7 @@ module Homebrew
|
|||||||
ignores.compact
|
ignores.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.bottle_formula(formula, args:)
|
def bottle_formula(formula)
|
||||||
local_bottle_json = args.json? && formula.local_bottle_path.present?
|
local_bottle_json = args.json? && formula.local_bottle_path.present?
|
||||||
|
|
||||||
unless local_bottle_json
|
unless local_bottle_json
|
||||||
@ -366,7 +368,7 @@ module Homebrew
|
|||||||
end || 0
|
end || 0
|
||||||
end
|
end
|
||||||
|
|
||||||
filename = Bottle::Filename.create(formula, bottle_tag, rebuild)
|
filename = ::Bottle::Filename.create(formula, bottle_tag, rebuild)
|
||||||
local_filename = filename.to_s
|
local_filename = filename.to_s
|
||||||
bottle_path = Pathname.pwd/local_filename
|
bottle_path = Pathname.pwd/local_filename
|
||||||
|
|
||||||
@ -395,7 +397,8 @@ module Homebrew
|
|||||||
tab_json = Utils::Bottles.file_from_bottle(bottle_path, tab_path)
|
tab_json = Utils::Bottles.file_from_bottle(bottle_path, tab_path)
|
||||||
tab = Tab.from_file_content(tab_json, tab_path)
|
tab = Tab.from_file_content(tab_json, tab_path)
|
||||||
|
|
||||||
tag_spec = Formula[formula.name].bottle_specification.tag_specification_for(bottle_tag, no_older_versions: true)
|
tag_spec = Formula[formula.name].bottle_specification.tag_specification_for(bottle_tag,
|
||||||
|
no_older_versions: true)
|
||||||
relocatable = [:any, :any_skip_relocation].include?(tag_spec.cellar)
|
relocatable = [:any, :any_skip_relocation].include?(tag_spec.cellar)
|
||||||
skip_relocation = tag_spec.cellar == :any_skip_relocation
|
skip_relocation = tag_spec.cellar == :any_skip_relocation
|
||||||
|
|
||||||
@ -445,7 +448,7 @@ module Homebrew
|
|||||||
sudo_purge
|
sudo_purge
|
||||||
# Tar then gzip for reproducible bottles.
|
# Tar then gzip for reproducible bottles.
|
||||||
tar_mtime = tab.source_modified_time.strftime("%Y-%m-%d %H:%M:%S")
|
tar_mtime = tab.source_modified_time.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
tar, tar_args = setup_tar_and_args!(args, tar_mtime)
|
tar, tar_args = setup_tar_and_args!(tar_mtime)
|
||||||
safe_system tar, "--create", "--numeric-owner",
|
safe_system tar, "--create", "--numeric-owner",
|
||||||
*tar_args,
|
*tar_args,
|
||||||
"--file", tar_path, "#{formula.name}/#{formula.pkg_version}"
|
"--file", tar_path, "#{formula.name}/#{formula.pkg_version}"
|
||||||
@ -482,7 +485,7 @@ module Homebrew
|
|||||||
else
|
else
|
||||||
HOMEBREW_REPOSITORY
|
HOMEBREW_REPOSITORY
|
||||||
end.to_s
|
end.to_s
|
||||||
if keg_contain?(repository_reference, keg, ignores + ALLOWABLE_HOMEBREW_REPOSITORY_LINKS, args:)
|
if keg_contain?(repository_reference, keg, ignores + ALLOWABLE_HOMEBREW_REPOSITORY_LINKS)
|
||||||
odie "Bottle contains non-relocatable reference to #{repository_reference}!"
|
odie "Bottle contains non-relocatable reference to #{repository_reference}!"
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -490,16 +493,14 @@ module Homebrew
|
|||||||
if args.skip_relocation?
|
if args.skip_relocation?
|
||||||
skip_relocation = true
|
skip_relocation = true
|
||||||
else
|
else
|
||||||
relocatable = false if keg_contain?(prefix_check, keg, ignores, formula_and_runtime_deps_names, args:)
|
relocatable = false if keg_contain?(prefix_check, keg, ignores, formula_and_runtime_deps_names)
|
||||||
relocatable = false if keg_contain?(cellar, keg, ignores, formula_and_runtime_deps_names, args:)
|
relocatable = false if keg_contain?(cellar, keg, ignores, formula_and_runtime_deps_names)
|
||||||
if keg_contain?(HOMEBREW_LIBRARY.to_s, keg, ignores, formula_and_runtime_deps_names, args:)
|
relocatable = false if keg_contain?(HOMEBREW_LIBRARY.to_s, keg, ignores, formula_and_runtime_deps_names)
|
||||||
relocatable = false
|
|
||||||
end
|
|
||||||
if prefix != prefix_check
|
if prefix != prefix_check
|
||||||
relocatable = false if keg_contain_absolute_symlink_starting_with?(prefix, keg, args:)
|
relocatable = false if keg_contain_absolute_symlink_starting_with?(prefix, keg)
|
||||||
relocatable = false if keg_contain?("#{prefix}/etc", keg, ignores, args:)
|
relocatable = false if keg_contain?("#{prefix}/etc", keg, ignores)
|
||||||
relocatable = false if keg_contain?("#{prefix}/var", keg, ignores, args:)
|
relocatable = false if keg_contain?("#{prefix}/var", keg, ignores)
|
||||||
relocatable = false if keg_contain?("#{prefix}/share/vim", keg, ignores, args:)
|
relocatable = false if keg_contain?("#{prefix}/share/vim", keg, ignores)
|
||||||
end
|
end
|
||||||
skip_relocation = relocatable && !keg.require_relocation?
|
skip_relocation = relocatable && !keg.require_relocation?
|
||||||
end
|
end
|
||||||
@ -599,13 +600,13 @@ module Homebrew
|
|||||||
json_path.write(JSON.pretty_generate(json))
|
json_path.write(JSON.pretty_generate(json))
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.parse_json_files(filenames)
|
def parse_json_files(filenames)
|
||||||
filenames.map do |filename|
|
filenames.map do |filename|
|
||||||
JSON.parse(File.read(filename))
|
JSON.parse(File.read(filename))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.merge_json_files(json_files)
|
def merge_json_files(json_files)
|
||||||
json_files.reduce({}) do |hash, json_file|
|
json_files.reduce({}) do |hash, json_file|
|
||||||
json_file.each_value do |json_hash|
|
json_file.each_value do |json_hash|
|
||||||
json_bottle = json_hash["bottle"]
|
json_bottle = json_hash["bottle"]
|
||||||
@ -618,7 +619,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.merge(args:)
|
def merge
|
||||||
bottles_hash = merge_json_files(parse_json_files(args.named))
|
bottles_hash = merge_json_files(parse_json_files(args.named))
|
||||||
|
|
||||||
any_cellars = ["any", "any_skip_relocation"]
|
any_cellars = ["any", "any_skip_relocation"]
|
||||||
@ -689,7 +690,7 @@ module Homebrew
|
|||||||
|
|
||||||
all_bottle_hash = T.let(nil, T.nilable(Hash))
|
all_bottle_hash = T.let(nil, T.nilable(Hash))
|
||||||
bottle_hash["bottle"]["tags"].each do |tag, tag_hash|
|
bottle_hash["bottle"]["tags"].each do |tag, tag_hash|
|
||||||
filename = Bottle::Filename.new(
|
filename = ::Bottle::Filename.new(
|
||||||
formula_name,
|
formula_name,
|
||||||
PkgVersion.parse(bottle_hash["formula"]["pkg_version"]),
|
PkgVersion.parse(bottle_hash["formula"]["pkg_version"]),
|
||||||
Utils::Bottles::Tag.from_symbol(tag.to_sym),
|
Utils::Bottles::Tag.from_symbol(tag.to_sym),
|
||||||
@ -699,7 +700,7 @@ module Homebrew
|
|||||||
if all_bottle && all_bottle_hash.nil?
|
if all_bottle && all_bottle_hash.nil?
|
||||||
all_bottle_tag_hash = tag_hash.dup
|
all_bottle_tag_hash = tag_hash.dup
|
||||||
|
|
||||||
all_filename = Bottle::Filename.new(
|
all_filename = ::Bottle::Filename.new(
|
||||||
formula_name,
|
formula_name,
|
||||||
PkgVersion.parse(bottle_hash["formula"]["pkg_version"]),
|
PkgVersion.parse(bottle_hash["formula"]["pkg_version"]),
|
||||||
Utils::Bottles::Tag.from_symbol(:all),
|
Utils::Bottles::Tag.from_symbol(:all),
|
||||||
@ -735,7 +736,7 @@ module Homebrew
|
|||||||
|
|
||||||
require "utils/ast"
|
require "utils/ast"
|
||||||
formula_ast = Utils::AST::FormulaAST.new(path.read)
|
formula_ast = Utils::AST::FormulaAST.new(path.read)
|
||||||
checksums = old_checksums(formula, formula_ast, bottle_hash, args:)
|
checksums = old_checksums(formula, formula_ast, bottle_hash)
|
||||||
update_or_add = checksums.nil? ? "add" : "update"
|
update_or_add = checksums.nil? ? "add" : "update"
|
||||||
|
|
||||||
checksums&.each(&bottle.method(:sha256))
|
checksums&.each(&bottle.method(:sha256))
|
||||||
@ -772,7 +773,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.merge_bottle_spec(old_keys, old_bottle_spec, new_bottle_hash)
|
def merge_bottle_spec(old_keys, old_bottle_spec, new_bottle_hash)
|
||||||
mismatches = []
|
mismatches = []
|
||||||
checksums = []
|
checksums = []
|
||||||
|
|
||||||
@ -812,12 +813,13 @@ module Homebrew
|
|||||||
[mismatches, checksums]
|
[mismatches, checksums]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.old_checksums(formula, formula_ast, bottle_hash, args:)
|
def old_checksums(formula, formula_ast, bottle_hash)
|
||||||
bottle_node = formula_ast.bottle_block
|
bottle_node = formula_ast.bottle_block
|
||||||
return if bottle_node.nil?
|
return if bottle_node.nil?
|
||||||
return [] unless args.keep_old?
|
return [] unless args.keep_old?
|
||||||
|
|
||||||
old_keys = T.cast(Utils::AST.body_children(bottle_node.body), T::Array[RuboCop::AST::SendNode]).map(&:method_name)
|
old_keys = T.cast(Utils::AST.body_children(bottle_node.body),
|
||||||
|
T::Array[RuboCop::AST::SendNode]).map(&:method_name)
|
||||||
old_bottle_spec = formula.bottle_specification
|
old_bottle_spec = formula.bottle_specification
|
||||||
mismatches, checksums = merge_bottle_spec(old_keys, old_bottle_spec, bottle_hash["bottle"])
|
mismatches, checksums = merge_bottle_spec(old_keys, old_bottle_spec, bottle_hash["bottle"])
|
||||||
if mismatches.present?
|
if mismatches.present?
|
||||||
@ -828,6 +830,8 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
checksums
|
checksums
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
require "extend/os/dev-cmd/bottle"
|
require "extend/os/dev-cmd/bottle"
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
class << self
|
module DevCmd
|
||||||
|
class Bottle < AbstractCommand
|
||||||
undef tar_args
|
undef tar_args
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
@ -21,4 +22,5 @@ module Homebrew
|
|||||||
"#{gnu_tar_formula.opt_bin}/gtar"
|
"#{gnu_tar_formula.opt_bin}/gtar"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
require "cmd/shared_examples/args_parse"
|
require "cmd/shared_examples/args_parse"
|
||||||
require "dev-cmd/bottle"
|
require "dev-cmd/bottle"
|
||||||
|
|
||||||
RSpec.describe "brew bottle" do
|
RSpec.describe Homebrew::DevCmd::Bottle do
|
||||||
def stub_hash(parameters)
|
def stub_hash(parameters)
|
||||||
<<~EOS
|
<<~EOS
|
||||||
{
|
{
|
||||||
@ -30,7 +30,7 @@ RSpec.describe "brew bottle" do
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like "parseable arguments"
|
it_behaves_like "parseable arguments", argv: ["foo"]
|
||||||
|
|
||||||
it "builds a bottle for the given Formula", :integration_test do
|
it "builds a bottle for the given Formula", :integration_test do
|
||||||
install_test_formula "testball", build_bottle: true
|
install_test_formula "testball", build_bottle: true
|
||||||
@ -308,8 +308,8 @@ RSpec.describe "brew bottle" do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Homebrew do
|
describe "bottle_cmd" do
|
||||||
subject(:homebrew) { described_class }
|
subject(:homebrew) { described_class.new(["foo"]) }
|
||||||
|
|
||||||
let(:hello_hash_big_sur) do
|
let(:hello_hash_big_sur) do
|
||||||
JSON.parse stub_hash(
|
JSON.parse stub_hash(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user