Merge pull request #17606 from Homebrew/sorbet-strict-devcmd
This commit is contained in:
commit
3773940382
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -329,6 +329,7 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { params(results: T::Hash[[Symbol, Pathname], T::Array[T::Hash[Symbol, T.untyped]]]).void }
|
||||||
def print_problems(results)
|
def print_problems(results)
|
||||||
results.each do |(name, path), problems|
|
results.each do |(name, path), problems|
|
||||||
problem_lines = format_problem_lines(problems)
|
problem_lines = format_problem_lines(problems)
|
||||||
@ -343,6 +344,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(problems: T::Array[T::Hash[Symbol, T.untyped]]).returns(T::Array[String]) }
|
||||||
def format_problem_lines(problems)
|
def format_problem_lines(problems)
|
||||||
problems.map do |problem|
|
problems.map do |problem|
|
||||||
status = " #{Formatter.success("[corrected]")}" if problem.fetch(:corrected)
|
status = " #{Formatter.success("[corrected]")}" if problem.fetch(:corrected)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -20,7 +20,7 @@ module Homebrew
|
|||||||
class Bottle < AbstractCommand
|
class Bottle < AbstractCommand
|
||||||
include FileUtils
|
include FileUtils
|
||||||
|
|
||||||
BOTTLE_ERB = <<-EOS.freeze
|
BOTTLE_ERB = T.let(<<-EOS.freeze, String)
|
||||||
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) %>
|
||||||
@ -39,9 +39,9 @@ module Homebrew
|
|||||||
|
|
||||||
MAXIMUM_STRING_MATCHES = 100
|
MAXIMUM_STRING_MATCHES = 100
|
||||||
|
|
||||||
ALLOWABLE_HOMEBREW_REPOSITORY_LINKS = [
|
ALLOWABLE_HOMEBREW_REPOSITORY_LINKS = T.let([
|
||||||
%r{#{Regexp.escape(HOMEBREW_LIBRARY)}/Homebrew/os/(mac|linux)/pkgconfig},
|
%r{#{Regexp.escape(HOMEBREW_LIBRARY)}/Homebrew/os/(mac|linux)/pkgconfig},
|
||||||
].freeze
|
].freeze, T::Array[Regexp])
|
||||||
|
|
||||||
cmd_args do
|
cmd_args do
|
||||||
description <<~EOS
|
description <<~EOS
|
||||||
@ -110,6 +110,10 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(tag: Symbol, digest: T.any(Checksum, String), cellar: T.nilable(T.any(String, Symbol)),
|
||||||
|
tag_column: Integer, digest_column: Integer).returns(String)
|
||||||
|
}
|
||||||
def 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
|
||||||
@ -125,6 +129,7 @@ module Homebrew
|
|||||||
%Q(#{line}"#{digest}")
|
%Q(#{line}"#{digest}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(bottle: BottleSpecification, root_url_using: T.nilable(String)).returns(String) }
|
||||||
def 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"]
|
||||||
@ -153,12 +158,14 @@ module Homebrew
|
|||||||
erb.result(erb_binding).gsub(/^\s*$\n/, "")
|
erb.result(erb_binding).gsub(/^\s*$\n/, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(filenames: T::Array[String]).returns(T::Array[T::Hash[String, T.untyped]]) }
|
||||||
def 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
|
||||||
|
|
||||||
|
sig { params(json_files: T::Array[T::Hash[String, T.untyped]]).returns(T::Hash[String, T.untyped]) }
|
||||||
def 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|
|
||||||
@ -172,6 +179,10 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(old_keys: T::Array[String], old_bottle_spec: BottleSpecification,
|
||||||
|
new_bottle_hash: T::Hash[String, T.untyped]).returns(T::Array[T::Array[String]])
|
||||||
|
}
|
||||||
def 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 = []
|
||||||
@ -214,16 +225,20 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(string: String, keg: Keg, ignores: T::Array[String],
|
||||||
|
formula_and_runtime_deps_names: T.nilable(T::Array[String])).returns(T::Boolean)
|
||||||
|
}
|
||||||
def keg_contain?(string, keg, ignores, formula_and_runtime_deps_names = nil)
|
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|
|
||||||
unless @put_string_exists_header
|
unless @put_string_exists_header
|
||||||
opoo "String '#{str}' still exists in these files:"
|
opoo "String '#{str}' still exists in these files:"
|
||||||
@put_string_exists_header = true
|
@put_string_exists_header = T.let(true, T.nilable(T::Boolean))
|
||||||
end
|
end
|
||||||
|
|
||||||
@put_filenames ||= []
|
@put_filenames ||= T.let([], T.nilable(T::Array[T.any(String, Pathname)]))
|
||||||
|
|
||||||
return false if @put_filenames.include?(filename)
|
return false if @put_filenames.include?(filename)
|
||||||
|
|
||||||
@ -265,6 +280,7 @@ module Homebrew
|
|||||||
keg_contain_absolute_symlink_starting_with?(string, keg) || result
|
keg_contain_absolute_symlink_starting_with?(string, keg) || result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(string: String, keg: Keg).returns(T::Boolean) }
|
||||||
def keg_contain_absolute_symlink_starting_with?(string, keg)
|
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|
|
||||||
@ -283,6 +299,7 @@ module Homebrew
|
|||||||
!absolute_symlinks_start_with_string.empty?
|
!absolute_symlinks_start_with_string.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(cellar: T.nilable(T.any(String, Symbol))).returns(T::Boolean) }
|
||||||
def cellar_parameter_needed?(cellar)
|
def cellar_parameter_needed?(cellar)
|
||||||
default_cellars = [
|
default_cellars = [
|
||||||
Homebrew::DEFAULT_MACOS_CELLAR,
|
Homebrew::DEFAULT_MACOS_CELLAR,
|
||||||
@ -292,6 +309,7 @@ module Homebrew
|
|||||||
cellar.present? && default_cellars.exclude?(cellar)
|
cellar.present? && default_cellars.exclude?(cellar)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T.nilable(T::Boolean)) }
|
||||||
def sudo_purge
|
def sudo_purge
|
||||||
return unless ENV["HOMEBREW_BOTTLE_SUDO_PURGE"]
|
return unless ENV["HOMEBREW_BOTTLE_SUDO_PURGE"]
|
||||||
|
|
||||||
@ -354,6 +372,7 @@ module Homebrew
|
|||||||
[gnu_tar(gnu_tar_formula), reproducible_gnutar_args(mtime)].freeze
|
[gnu_tar(gnu_tar_formula), reproducible_gnutar_args(mtime)].freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: T.untyped).returns(T::Array[T.untyped]) }
|
||||||
def formula_ignores(formula)
|
def formula_ignores(formula)
|
||||||
ignores = []
|
ignores = []
|
||||||
cellar_regex = Regexp.escape(HOMEBREW_CELLAR)
|
cellar_regex = Regexp.escape(HOMEBREW_CELLAR)
|
||||||
@ -384,6 +403,7 @@ module Homebrew
|
|||||||
ignores.compact
|
ignores.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: Formula).void }
|
||||||
def bottle_formula(formula)
|
def bottle_formula(formula)
|
||||||
local_bottle_json = args.json? && formula.local_bottle_path.present?
|
local_bottle_json = args.json? && formula.local_bottle_path.present?
|
||||||
|
|
||||||
@ -453,6 +473,8 @@ module Homebrew
|
|||||||
|
|
||||||
if local_bottle_json
|
if local_bottle_json
|
||||||
bottle_path = formula.local_bottle_path
|
bottle_path = formula.local_bottle_path
|
||||||
|
return if bottle_path.blank?
|
||||||
|
|
||||||
local_filename = bottle_path.basename.to_s
|
local_filename = bottle_path.basename.to_s
|
||||||
|
|
||||||
tab_path = Utils::Bottles.receipt_path(bottle_path)
|
tab_path = Utils::Bottles.receipt_path(bottle_path)
|
||||||
@ -471,6 +493,7 @@ module Homebrew
|
|||||||
else
|
else
|
||||||
tar_filename = filename.to_s.sub(/.gz$/, "")
|
tar_filename = filename.to_s.sub(/.gz$/, "")
|
||||||
tar_path = Pathname.pwd/tar_filename
|
tar_path = Pathname.pwd/tar_filename
|
||||||
|
return if tar_path.blank?
|
||||||
|
|
||||||
keg = Keg.new(formula.prefix)
|
keg = Keg.new(formula.prefix)
|
||||||
end
|
end
|
||||||
@ -681,6 +704,7 @@ module Homebrew
|
|||||||
json_path.write(JSON.pretty_generate(json))
|
json_path.write(JSON.pretty_generate(json))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Hash[String, T.untyped]) }
|
||||||
def merge
|
def merge
|
||||||
bottles_hash = merge_json_files(parse_json_files(args.named))
|
bottles_hash = merge_json_files(parse_json_files(args.named))
|
||||||
|
|
||||||
@ -750,7 +774,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
all_bottle_hash = T.let(nil, T.nilable(Hash))
|
all_bottle_hash = T.let(nil, T.nilable(T::Hash[String, T.untyped]))
|
||||||
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,
|
||||||
@ -801,7 +825,7 @@ module Homebrew
|
|||||||
checksums = old_checksums(formula, formula_ast, bottle_hash)
|
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 { |checksum| bottle.sha256(checksum) }
|
||||||
output = bottle_output(bottle, args.root_url_using)
|
output = bottle_output(bottle, args.root_url_using)
|
||||||
puts output
|
puts output
|
||||||
|
|
||||||
@ -835,8 +859,12 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(formula: Formula, formula_ast: Utils::AST::FormulaAST,
|
||||||
|
bottle_hash: T::Hash[String, T.untyped]).returns(T.nilable(T::Array[String]))
|
||||||
|
}
|
||||||
def old_checksums(formula, formula_ast, bottle_hash)
|
def old_checksums(formula, formula_ast, bottle_hash)
|
||||||
bottle_node = formula_ast.bottle_block
|
bottle_node = T.cast(formula_ast.bottle_block, T.nilable(RuboCop::AST::BlockNode))
|
||||||
return if bottle_node.nil?
|
return if bottle_node.nil?
|
||||||
return [] unless args.keep_old?
|
return [] unless args.keep_old?
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -145,10 +145,10 @@ module Homebrew
|
|||||||
|
|
||||||
old_mirrors = formula_spec.mirrors
|
old_mirrors = formula_spec.mirrors
|
||||||
new_mirrors ||= args.mirror
|
new_mirrors ||= args.mirror
|
||||||
new_mirror ||= determine_mirror(new_url)
|
if new_url.present? && (new_mirror = determine_mirror(new_url))
|
||||||
new_mirrors ||= [new_mirror] if new_mirror.present?
|
new_mirrors ||= [new_mirror]
|
||||||
|
check_for_mirrors(formula, old_mirrors, new_mirrors)
|
||||||
check_for_mirrors(formula, old_mirrors, new_mirrors) if new_url.present?
|
end
|
||||||
|
|
||||||
old_hash = formula_spec.checksum&.hexdigest
|
old_hash = formula_spec.checksum&.hexdigest
|
||||||
new_hash = args.sha256
|
new_hash = args.sha256
|
||||||
@ -190,12 +190,14 @@ module Homebrew
|
|||||||
elsif new_url.blank? && new_version.blank?
|
elsif new_url.blank? && new_version.blank?
|
||||||
raise UsageError, "#{formula}: no `--url` or `--version` argument specified!"
|
raise UsageError, "#{formula}: no `--url` or `--version` argument specified!"
|
||||||
else
|
else
|
||||||
new_url ||= PyPI.update_pypi_url(old_url, T.must(new_version))
|
return unless new_version.present?
|
||||||
|
|
||||||
|
new_url ||= PyPI.update_pypi_url(old_url, new_version)
|
||||||
if new_url.blank?
|
if new_url.blank?
|
||||||
new_url = update_url(old_url, old_version, T.must(new_version))
|
new_url = update_url(old_url, old_version, new_version)
|
||||||
if new_mirrors.blank? && old_mirrors.present?
|
if new_mirrors.blank? && old_mirrors.present?
|
||||||
new_mirrors = old_mirrors.map do |old_mirror|
|
new_mirrors = old_mirrors.map do |old_mirror|
|
||||||
update_url(old_mirror, old_version, T.must(new_version))
|
update_url(old_mirror, old_version, new_version)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -271,9 +273,9 @@ module Homebrew
|
|||||||
|
|
||||||
old_contents = formula.path.read
|
old_contents = formula.path.read
|
||||||
|
|
||||||
if new_mirrors.present?
|
if new_mirrors.present? && new_url.present?
|
||||||
replacement_pairs << [
|
replacement_pairs << [
|
||||||
/^( +)(url "#{Regexp.escape(T.must(new_url))}"[^\n]*?\n)/m,
|
/^( +)(url "#{Regexp.escape(new_url)}"[^\n]*?\n)/m,
|
||||||
"\\1\\2\\1mirror \"#{new_mirrors.join("\"\n\\1mirror \"")}\"\n",
|
"\\1\\2\\1mirror \"#{new_mirrors.join("\"\n\\1mirror \"")}\"\n",
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
@ -395,6 +397,7 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { params(url: String).returns(T.nilable(String)) }
|
||||||
def determine_mirror(url)
|
def determine_mirror(url)
|
||||||
case url
|
case url
|
||||||
when %r{.*ftp\.gnu\.org/gnu.*}
|
when %r{.*ftp\.gnu\.org/gnu.*}
|
||||||
@ -408,6 +411,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: String, old_mirrors: T::Array[String], new_mirrors: T::Array[String]).void }
|
||||||
def check_for_mirrors(formula, old_mirrors, new_mirrors)
|
def check_for_mirrors(formula, old_mirrors, new_mirrors)
|
||||||
return if new_mirrors.present? || old_mirrors.empty?
|
return if new_mirrors.present? || old_mirrors.empty?
|
||||||
|
|
||||||
@ -427,11 +431,17 @@ module Homebrew
|
|||||||
return new_url if (old_version_parts = old_version.split(".")).length < 2
|
return new_url if (old_version_parts = old_version.split(".")).length < 2
|
||||||
return new_url if (new_version_parts = new_version.split(".")).length != old_version_parts.length
|
return new_url if (new_version_parts = new_version.split(".")).length != old_version_parts.length
|
||||||
|
|
||||||
partial_old_version = T.must(old_version_parts[0..-2]).join(".")
|
partial_old_version = old_version_parts[0..-2]&.join(".")
|
||||||
partial_new_version = T.must(new_version_parts[0..-2]).join(".")
|
partial_new_version = new_version_parts[0..-2]&.join(".")
|
||||||
|
return new_url if partial_old_version.blank? || partial_new_version.blank?
|
||||||
|
|
||||||
new_url.gsub(%r{/(v?)#{Regexp.escape(partial_old_version)}/}, "/\\1#{partial_new_version}/")
|
new_url.gsub(%r{/(v?)#{Regexp.escape(partial_old_version)}/}, "/\\1#{partial_new_version}/")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(formula: Formula, new_version: T.nilable(String), url: String,
|
||||||
|
specs: Float).returns(T::Array[T.untyped])
|
||||||
|
}
|
||||||
def fetch_resource_and_forced_version(formula, new_version, url, **specs)
|
def fetch_resource_and_forced_version(formula, new_version, url, **specs)
|
||||||
resource = Resource.new
|
resource = Resource.new
|
||||||
resource.url(url, **specs)
|
resource.url(url, **specs)
|
||||||
@ -442,6 +452,7 @@ module Homebrew
|
|||||||
[resource.fetch, forced_version]
|
[resource.fetch, forced_version]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: Formula, contents: T.nilable(String)).returns(String) }
|
||||||
def formula_version(formula, contents = nil)
|
def formula_version(formula, contents = nil)
|
||||||
spec = :stable
|
spec = :stable
|
||||||
name = formula.name
|
name = formula.name
|
||||||
@ -453,17 +464,29 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: Formula, tap_remote_repo: String).returns(T.nilable(T::Array[String])) }
|
||||||
def check_open_pull_requests(formula, tap_remote_repo)
|
def check_open_pull_requests(formula, tap_remote_repo)
|
||||||
GitHub.check_for_duplicate_pull_requests(formula.name, tap_remote_repo,
|
tap = formula.tap
|
||||||
|
return if tap.nil?
|
||||||
|
|
||||||
|
GitHub.check_for_duplicate_pull_requests(
|
||||||
|
formula.name, tap_remote_repo,
|
||||||
state: "open",
|
state: "open",
|
||||||
file: formula.path.relative_path_from(formula.tap.path).to_s,
|
file: formula.path.relative_path_from(tap.path).to_s,
|
||||||
quiet: args.quiet?)
|
quiet: args.quiet?
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(formula: Formula, tap_remote_repo: String, version: T.nilable(String), url: T.nilable(String),
|
||||||
|
tag: T.nilable(String)).void
|
||||||
|
}
|
||||||
def check_new_version(formula, tap_remote_repo, version: nil, url: nil, tag: nil)
|
def check_new_version(formula, tap_remote_repo, version: nil, url: nil, tag: nil)
|
||||||
if version.nil?
|
if version.nil?
|
||||||
specs = {}
|
specs = {}
|
||||||
specs[:tag] = tag if tag.present?
|
specs[:tag] = tag if tag.present?
|
||||||
|
return if url.blank?
|
||||||
|
|
||||||
version = Version.detect(url, **specs).to_s
|
version = Version.detect(url, **specs).to_s
|
||||||
return if version.blank?
|
return if version.blank?
|
||||||
end
|
end
|
||||||
@ -472,9 +495,13 @@ module Homebrew
|
|||||||
check_closed_pull_requests(formula, tap_remote_repo, version:)
|
check_closed_pull_requests(formula, tap_remote_repo, version:)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: Formula, new_version: String).returns(NilClass) }
|
||||||
def check_throttle(formula, new_version)
|
def check_throttle(formula, new_version)
|
||||||
|
tap = formula.tap
|
||||||
|
return if tap.nil?
|
||||||
|
|
||||||
throttled_rate = formula.livecheck.throttle
|
throttled_rate = formula.livecheck.throttle
|
||||||
throttled_rate ||= if (rate = formula.tap.audit_exceptions.dig(:throttled_formulae, formula.name))
|
throttled_rate ||= if (rate = tap.audit_exceptions.dig(:throttled_formulae, formula.name))
|
||||||
odisabled "throttled_formulae.json", "Livecheck#throttle"
|
odisabled "throttled_formulae.json", "Livecheck#throttle"
|
||||||
rate
|
rate
|
||||||
end
|
end
|
||||||
@ -486,27 +513,41 @@ module Homebrew
|
|||||||
odie "#{formula} should only be updated every #{throttled_rate} releases on multiples of #{throttled_rate}"
|
odie "#{formula} should only be updated every #{throttled_rate} releases on multiples of #{throttled_rate}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(formula: Formula, tap_remote_repo: String,
|
||||||
|
version: T.nilable(String)).returns(T.nilable(T::Array[String]))
|
||||||
|
}
|
||||||
def check_closed_pull_requests(formula, tap_remote_repo, version:)
|
def check_closed_pull_requests(formula, tap_remote_repo, version:)
|
||||||
|
tap = formula.tap
|
||||||
|
return if tap.nil?
|
||||||
|
|
||||||
# if we haven't already found open requests, try for an exact match across closed requests
|
# if we haven't already found open requests, try for an exact match across closed requests
|
||||||
GitHub.check_for_duplicate_pull_requests(formula.name, tap_remote_repo,
|
GitHub.check_for_duplicate_pull_requests(
|
||||||
|
formula.name, tap_remote_repo,
|
||||||
version:,
|
version:,
|
||||||
state: "closed",
|
state: "closed",
|
||||||
file: formula.path.relative_path_from(formula.tap.path).to_s,
|
file: formula.path.relative_path_from(tap.path).to_s,
|
||||||
quiet: args.quiet?)
|
quiet: args.quiet?
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: Formula, new_formula_version: String).returns(T.nilable(T::Array[String])) }
|
||||||
def alias_update_pair(formula, new_formula_version)
|
def alias_update_pair(formula, new_formula_version)
|
||||||
versioned_alias = formula.aliases.grep(/^.*@\d+(\.\d+)?$/).first
|
versioned_alias = formula.aliases.grep(/^.*@\d+(\.\d+)?$/).first
|
||||||
return if versioned_alias.nil?
|
return if versioned_alias.nil?
|
||||||
|
|
||||||
name, old_alias_version = versioned_alias.split("@")
|
name, old_alias_version = versioned_alias.split("@")
|
||||||
|
return if old_alias_version.blank?
|
||||||
|
|
||||||
new_alias_regex = (old_alias_version.split(".").length == 1) ? /^\d+/ : /^\d+\.\d+/
|
new_alias_regex = (old_alias_version.split(".").length == 1) ? /^\d+/ : /^\d+\.\d+/
|
||||||
new_alias_version, = *new_formula_version.to_s.match(new_alias_regex)
|
new_alias_version, = *new_formula_version.to_s.match(new_alias_regex)
|
||||||
|
return if new_alias_version.blank?
|
||||||
return if Version.new(new_alias_version) <= Version.new(old_alias_version)
|
return if Version.new(new_alias_version) <= Version.new(old_alias_version)
|
||||||
|
|
||||||
[versioned_alias, "#{name}@#{new_alias_version}"]
|
[versioned_alias, "#{name}@#{new_alias_version}"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: Formula, alias_rename: T.nilable(T::Array[String]), old_contents: String).void }
|
||||||
def run_audit(formula, alias_rename, old_contents)
|
def run_audit(formula, alias_rename, old_contents)
|
||||||
audit_args = ["--formula"]
|
audit_args = ["--formula"]
|
||||||
audit_args << "--strict" if args.strict?
|
audit_args << "--strict" if args.strict?
|
||||||
@ -521,7 +562,9 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
FileUtils.mv alias_rename.first, alias_rename.last if alias_rename.present?
|
if alias_rename && (source = alias_rename.first) && (destination = alias_rename.last)
|
||||||
|
FileUtils.mv source, destination
|
||||||
|
end
|
||||||
failed_audit = false
|
failed_audit = false
|
||||||
if args.no_audit?
|
if args.no_audit?
|
||||||
ohai "Skipping `brew audit`"
|
ohai "Skipping `brew audit`"
|
||||||
@ -535,7 +578,9 @@ module Homebrew
|
|||||||
return unless failed_audit
|
return unless failed_audit
|
||||||
|
|
||||||
formula.path.atomic_write(old_contents)
|
formula.path.atomic_write(old_contents)
|
||||||
FileUtils.mv alias_rename.last, alias_rename.first if alias_rename.present?
|
if alias_rename && (source = alias_rename.first) && (destination = alias_rename.last)
|
||||||
|
FileUtils.mv source, destination
|
||||||
|
end
|
||||||
odie "`brew audit` failed!"
|
odie "`brew audit` failed!"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -10,12 +10,12 @@ end
|
|||||||
module Homebrew
|
module Homebrew
|
||||||
module DevCmd
|
module DevCmd
|
||||||
class Contributions < AbstractCommand
|
class Contributions < AbstractCommand
|
||||||
PRIMARY_REPOS = %w[brew core cask].freeze
|
PRIMARY_REPOS = T.let(%w[brew core cask].freeze, T::Array[String])
|
||||||
SUPPORTED_REPOS = [
|
SUPPORTED_REPOS = T.let([
|
||||||
PRIMARY_REPOS,
|
PRIMARY_REPOS,
|
||||||
OFFICIAL_CMD_TAPS.keys.map { |t| t.delete_prefix("homebrew/") },
|
OFFICIAL_CMD_TAPS.keys.map { |t| t.delete_prefix("homebrew/") },
|
||||||
OFFICIAL_CASK_TAPS.reject { |t| t == "cask" },
|
OFFICIAL_CASK_TAPS.reject { |t| t == "cask" },
|
||||||
].flatten.freeze
|
].flatten.freeze, T::Array[String])
|
||||||
MAX_REPO_COMMITS = 1000
|
MAX_REPO_COMMITS = 1000
|
||||||
|
|
||||||
cmd_args do
|
cmd_args do
|
||||||
@ -50,9 +50,9 @@ module Homebrew
|
|||||||
results = {}
|
results = {}
|
||||||
grand_totals = {}
|
grand_totals = {}
|
||||||
|
|
||||||
repos = if args.repositories.blank? || T.must(args.repositories).include?("primary")
|
repos = if args.repositories.blank? || args.repositories&.include?("primary")
|
||||||
PRIMARY_REPOS
|
PRIMARY_REPOS
|
||||||
elsif T.must(args.repositories).include?("all")
|
elsif args.repositories&.include?("all")
|
||||||
SUPPORTED_REPOS
|
SUPPORTED_REPOS
|
||||||
else
|
else
|
||||||
args.repositories
|
args.repositories
|
||||||
@ -116,7 +116,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(totals: Hash).returns(String) }
|
sig { params(totals: T::Hash[String, T::Hash[Symbol, Integer]]).returns(String) }
|
||||||
def generate_csv(totals)
|
def generate_csv(totals)
|
||||||
CSV.generate do |csv|
|
CSV.generate do |csv|
|
||||||
csv << %w[user repo author committer coauthor review total]
|
csv << %w[user repo author committer coauthor review total]
|
||||||
@ -127,7 +127,14 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(user: String, grand_total: Hash).returns(Array) }
|
sig {
|
||||||
|
params(
|
||||||
|
user: String,
|
||||||
|
grand_total: T::Hash[Symbol, Integer],
|
||||||
|
).returns(
|
||||||
|
[String, String, T.nilable(Integer), T.nilable(Integer), T.nilable(Integer), T.nilable(Integer), Integer],
|
||||||
|
)
|
||||||
|
}
|
||||||
def grand_total_row(user, grand_total)
|
def grand_total_row(user, grand_total)
|
||||||
[
|
[
|
||||||
user,
|
user,
|
||||||
@ -140,7 +147,10 @@ module Homebrew
|
|||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(repos: T.nilable(T::Array[String]), person: String, from: String).void }
|
||||||
def scan_repositories(repos, person, from:)
|
def scan_repositories(repos, person, from:)
|
||||||
|
return if repos.blank?
|
||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
repos.each do |repo|
|
repos.each do |repo|
|
||||||
@ -168,7 +178,7 @@ module Homebrew
|
|||||||
data[repo] = {
|
data[repo] = {
|
||||||
author: author_commits,
|
author: author_commits,
|
||||||
committer: committer_commits,
|
committer: committer_commits,
|
||||||
coauthor: git_log_trailers_cmd(T.must(repo_path), person, "Co-authored-by", from:, to: args.to),
|
coauthor: git_log_trailers_cmd(repo_path, person, "Co-authored-by", from:, to: args.to),
|
||||||
review: count_reviews(repo_full_name, person, from:, to: args.to),
|
review: count_reviews(repo_full_name, person, from:, to: args.to),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@ -176,7 +186,7 @@ module Homebrew
|
|||||||
data
|
data
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(results: Hash).returns(Hash) }
|
sig { params(results: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, Integer]) }
|
||||||
def total(results)
|
def total(results)
|
||||||
totals = { author: 0, committer: 0, coauthor: 0, review: 0 }
|
totals = { author: 0, committer: 0, coauthor: 0, review: 0 }
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: true # This cannot be `# typed: strict` due to the use of `undef`.
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -71,6 +71,7 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { params(title: String).returns(String) }
|
||||||
def html_template(title)
|
def html_template(title)
|
||||||
<<~EOS
|
<<~EOS
|
||||||
---
|
---
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -69,6 +69,7 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { params(title: String).returns(String) }
|
||||||
def html_template(title)
|
def html_template(title)
|
||||||
<<~EOS
|
<<~EOS
|
||||||
---
|
---
|
||||||
|
|||||||
@ -1,18 +1,20 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
|
require "formula"
|
||||||
require "formulary"
|
require "formulary"
|
||||||
require "cask/cask_loader"
|
require "cask/cask_loader"
|
||||||
|
|
||||||
class String
|
class String
|
||||||
# @!visibility private
|
# @!visibility private
|
||||||
|
sig { params(args: Integer).returns(Formula) }
|
||||||
def f(*args)
|
def f(*args)
|
||||||
require "formula"
|
|
||||||
Formulary.factory(self, *args)
|
Formulary.factory(self, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
# @!visibility private
|
||||||
|
sig { params(config: T.nilable(T::Hash[Symbol, T.untyped])).returns(Cask::Cask) }
|
||||||
def c(config: nil)
|
def c(config: nil)
|
||||||
Cask::CaskLoader.load(self, config:)
|
Cask::CaskLoader.load(self, config:)
|
||||||
end
|
end
|
||||||
@ -20,11 +22,13 @@ end
|
|||||||
|
|
||||||
class Symbol
|
class Symbol
|
||||||
# @!visibility private
|
# @!visibility private
|
||||||
|
sig { params(args: Integer).returns(Formula) }
|
||||||
def f(*args)
|
def f(*args)
|
||||||
to_s.f(*args)
|
to_s.f(*args)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
# @!visibility private
|
||||||
|
sig { params(config: T.nilable(T::Hash[Symbol, T.untyped])).returns(Cask::Cask) }
|
||||||
def c(config: nil)
|
def c(config: nil)
|
||||||
to_s.c(config:)
|
to_s.c(config:)
|
||||||
end
|
end
|
||||||
@ -72,7 +76,6 @@ module Homebrew
|
|||||||
require "irb"
|
require "irb"
|
||||||
end
|
end
|
||||||
|
|
||||||
require "formula"
|
|
||||||
require "keg"
|
require "keg"
|
||||||
require "cask"
|
require "cask"
|
||||||
|
|
||||||
@ -94,6 +97,7 @@ module Homebrew
|
|||||||
|
|
||||||
# Remove the `--debug`, `--verbose` and `--quiet` options which cause problems
|
# Remove the `--debug`, `--verbose` and `--quiet` options which cause problems
|
||||||
# for IRB and have already been parsed by the CLI::Parser.
|
# for IRB and have already been parsed by the CLI::Parser.
|
||||||
|
sig { returns(T.nilable(T::Array[Symbol])) }
|
||||||
def clean_argv
|
def clean_argv
|
||||||
global_options = Homebrew::CLI::Parser
|
global_options = Homebrew::CLI::Parser
|
||||||
.global_options
|
.global_options
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -113,8 +113,9 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
def watchlist_path
|
def watchlist_path
|
||||||
@watchlist_path ||= File.expand_path(Homebrew::EnvConfig.livecheck_watchlist)
|
@watchlist_path ||= T.let(File.expand_path(Homebrew::EnvConfig.livecheck_watchlist), T.nilable(String))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -141,7 +141,7 @@ module Homebrew
|
|||||||
user, repo, pr, workflow_id: workflow, artifact_pattern:
|
user, repo, pr, workflow_id: workflow, artifact_pattern:
|
||||||
)
|
)
|
||||||
if args.ignore_missing_artifacts.present? &&
|
if args.ignore_missing_artifacts.present? &&
|
||||||
T.must(args.ignore_missing_artifacts).include?(workflow) &&
|
args.ignore_missing_artifacts&.include?(workflow) &&
|
||||||
workflow_run.first.blank?
|
workflow_run.first.blank?
|
||||||
# Ignore that workflow as it was not executed and we specified
|
# Ignore that workflow as it was not executed and we specified
|
||||||
# that we could skip it.
|
# that we could skip it.
|
||||||
@ -183,8 +183,10 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Separates a commit message into subject, body and trailers.
|
# Separates a commit message into subject, body and trailers.
|
||||||
|
sig { params(message: String).returns([String, String, String]) }
|
||||||
def separate_commit_message(message)
|
def separate_commit_message(message)
|
||||||
subject = message.lines.first.strip
|
first_line = message.lines.first
|
||||||
|
return ["", "", ""] unless first_line
|
||||||
|
|
||||||
# Skip the subject and separate lines that look like trailers (e.g. "Co-authored-by")
|
# Skip the subject and separate lines that look like trailers (e.g. "Co-authored-by")
|
||||||
# from lines that look like regular body text.
|
# from lines that look like regular body text.
|
||||||
@ -193,11 +195,15 @@ module Homebrew
|
|||||||
trailers = trailers.uniq.join.strip
|
trailers = trailers.uniq.join.strip
|
||||||
body = body.join.strip.gsub(/\n{3,}/, "\n\n")
|
body = body.join.strip.gsub(/\n{3,}/, "\n\n")
|
||||||
|
|
||||||
[subject, body, trailers]
|
[first_line.strip, body, trailers]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(git_repo: GitRepository, pull_request: T.nilable(String), dry_run: T::Boolean).void }
|
||||||
def signoff!(git_repo, pull_request: nil, dry_run: false)
|
def signoff!(git_repo, pull_request: nil, dry_run: false)
|
||||||
subject, body, trailers = separate_commit_message(git_repo.commit_message)
|
msg = git_repo.commit_message
|
||||||
|
return if msg.blank?
|
||||||
|
|
||||||
|
subject, body, trailers = separate_commit_message(msg)
|
||||||
|
|
||||||
if pull_request
|
if pull_request
|
||||||
# This is a tap pull request and approving reviewers should also sign-off.
|
# This is a tap pull request and approving reviewers should also sign-off.
|
||||||
@ -210,7 +216,7 @@ module Homebrew
|
|||||||
|
|
||||||
# Append the close message as well, unless the commit body already includes it.
|
# Append the close message as well, unless the commit body already includes it.
|
||||||
close_message = "Closes ##{pull_request}."
|
close_message = "Closes ##{pull_request}."
|
||||||
body += "\n\n#{close_message}" unless body.include? close_message
|
body.concat("\n\n#{close_message}") unless body.include?(close_message)
|
||||||
end
|
end
|
||||||
|
|
||||||
git_args = Utils::Git.git, "-C", git_repo.pathname, "commit", "--amend", "--signoff", "--allow-empty",
|
git_args = Utils::Git.git, "-C", git_repo.pathname, "commit", "--amend", "--signoff", "--allow-empty",
|
||||||
@ -223,6 +229,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(tap: Tap, subject_name: String, subject_path: Pathname, content: String).returns(T.untyped) }
|
||||||
def get_package(tap, subject_name, subject_path, content)
|
def get_package(tap, subject_name, subject_path, content)
|
||||||
if subject_path.to_s.start_with?("#{tap.cask_dir}/")
|
if subject_path.to_s.start_with?("#{tap.cask_dir}/")
|
||||||
cask = begin
|
cask = begin
|
||||||
@ -240,6 +247,10 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(old_contents: String, new_contents: String, subject_path: T.any(String, Pathname),
|
||||||
|
reason: T.nilable(String)).returns(String)
|
||||||
|
}
|
||||||
def determine_bump_subject(old_contents, new_contents, subject_path, reason: nil)
|
def determine_bump_subject(old_contents, new_contents, subject_path, reason: nil)
|
||||||
subject_path = Pathname(subject_path)
|
subject_path = Pathname(subject_path)
|
||||||
tap = Tap.from_path(subject_path)
|
tap = Tap.from_path(subject_path)
|
||||||
@ -268,6 +279,10 @@ module Homebrew
|
|||||||
|
|
||||||
# Cherry picks a single commit that modifies a single file.
|
# Cherry picks a single commit that modifies a single file.
|
||||||
# Potentially rewords this commit using {determine_bump_subject}.
|
# Potentially rewords this commit using {determine_bump_subject}.
|
||||||
|
sig {
|
||||||
|
params(commit: String, file: String, git_repo: GitRepository, reason: T.nilable(String), verbose: T::Boolean,
|
||||||
|
resolve: T::Boolean).void
|
||||||
|
}
|
||||||
def reword_package_commit(commit, file, git_repo:, reason: "", verbose: false, resolve: false)
|
def reword_package_commit(commit, file, git_repo:, reason: "", verbose: false, resolve: false)
|
||||||
package_file = git_repo.pathname / file
|
package_file = git_repo.pathname / file
|
||||||
package_name = package_file.basename.to_s.chomp(".rb")
|
package_name = package_file.basename.to_s.chomp(".rb")
|
||||||
@ -279,7 +294,10 @@ module Homebrew
|
|||||||
new_package = Utils::Git.file_at_commit(git_repo.to_s, file, "HEAD")
|
new_package = Utils::Git.file_at_commit(git_repo.to_s, file, "HEAD")
|
||||||
|
|
||||||
bump_subject = determine_bump_subject(old_package, new_package, package_file, reason:).strip
|
bump_subject = determine_bump_subject(old_package, new_package, package_file, reason:).strip
|
||||||
subject, body, trailers = separate_commit_message(git_repo.commit_message)
|
msg = git_repo.commit_message
|
||||||
|
return if msg.blank?
|
||||||
|
|
||||||
|
subject, body, trailers = separate_commit_message(msg)
|
||||||
|
|
||||||
if subject != bump_subject && !subject.start_with?("#{package_name}:")
|
if subject != bump_subject && !subject.start_with?("#{package_name}:")
|
||||||
safe_system("git", "-C", git_repo.pathname, "commit", "--amend", "-q",
|
safe_system("git", "-C", git_repo.pathname, "commit", "--amend", "-q",
|
||||||
@ -293,6 +311,10 @@ module Homebrew
|
|||||||
# Cherry picks multiple commits that each modify a single file.
|
# Cherry picks multiple commits that each modify a single file.
|
||||||
# Words the commit according to {determine_bump_subject} with the body
|
# Words the commit according to {determine_bump_subject} with the body
|
||||||
# corresponding to all the original commit messages combined.
|
# corresponding to all the original commit messages combined.
|
||||||
|
sig {
|
||||||
|
params(commits: T::Array[String], file: String, git_repo: GitRepository, reason: T.nilable(String),
|
||||||
|
verbose: T::Boolean, resolve: T::Boolean).void
|
||||||
|
}
|
||||||
def squash_package_commits(commits, file, git_repo:, reason: "", verbose: false, resolve: false)
|
def squash_package_commits(commits, file, git_repo:, reason: "", verbose: false, resolve: false)
|
||||||
odebug "Squashing #{file}: #{commits.join " "}"
|
odebug "Squashing #{file}: #{commits.join " "}"
|
||||||
|
|
||||||
@ -304,7 +326,10 @@ module Homebrew
|
|||||||
messages = []
|
messages = []
|
||||||
trailers = []
|
trailers = []
|
||||||
commits.each do |commit|
|
commits.each do |commit|
|
||||||
subject, body, trailer = separate_commit_message(git_repo.commit_message(commit))
|
msg = git_repo.commit_message(commit)
|
||||||
|
next if msg.blank?
|
||||||
|
|
||||||
|
subject, body, trailer = separate_commit_message(msg)
|
||||||
body = body.lines.map { |line| " #{line.strip}" }.join("\n")
|
body = body.lines.map { |line| " #{line.strip}" }.join("\n")
|
||||||
messages << "* #{subject}\n#{body}".strip
|
messages << "* #{subject}\n#{body}".strip
|
||||||
trailers << trailer
|
trailers << trailer
|
||||||
@ -340,9 +365,12 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
# TODO: fix test in `test/dev-cmd/pr-pull_spec.rb` and assume `cherry_picked: false`.
|
# TODO: fix test in `test/dev-cmd/pr-pull_spec.rb` and assume `cherry_picked: false`.
|
||||||
|
sig {
|
||||||
|
params(original_commit: String, tap: Tap, reason: T.nilable(String), verbose: T::Boolean, resolve: T::Boolean,
|
||||||
|
cherry_picked: T::Boolean).void
|
||||||
|
}
|
||||||
def autosquash!(original_commit, tap:, reason: "", verbose: false, resolve: false, cherry_picked: true)
|
def autosquash!(original_commit, tap:, reason: "", verbose: false, resolve: false, cherry_picked: true)
|
||||||
git_repo = tap.git_repository
|
git_repo = tap.git_repository
|
||||||
original_head = git_repo.head_ref
|
|
||||||
|
|
||||||
commits = Utils.safe_popen_read("git", "-C", tap.path, "rev-list",
|
commits = Utils.safe_popen_read("git", "-C", tap.path, "rev-list",
|
||||||
"--reverse", "#{original_commit}..HEAD").lines.map(&:strip)
|
"--reverse", "#{original_commit}..HEAD").lines.map(&:strip)
|
||||||
@ -402,14 +430,18 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
|
original_head = git_repo&.head_ref
|
||||||
|
return if original_head.nil?
|
||||||
|
|
||||||
opoo "Autosquash encountered an error; resetting to original state at #{original_head}"
|
opoo "Autosquash encountered an error; resetting to original state at #{original_head}"
|
||||||
system "git", "-C", tap.path, "reset", "--hard", original_head
|
system "git", "-C", tap.path.to_s, "reset", "--hard", original_head
|
||||||
system "git", "-C", tap.path, "cherry-pick", "--abort" if cherry_picked
|
system "git", "-C", tap.path.to_s, "cherry-pick", "--abort" if cherry_picked
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { params(user: String, repo: String, pull_request: String, path: T.any(String, Pathname)).void }
|
||||||
def cherry_pick_pr!(user, repo, pull_request, path: ".")
|
def cherry_pick_pr!(user, repo, pull_request, path: ".")
|
||||||
if args.dry_run?
|
if args.dry_run?
|
||||||
puts <<~EOS
|
puts <<~EOS
|
||||||
@ -427,6 +459,7 @@ module Homebrew
|
|||||||
resolve: args.resolve?)
|
resolve: args.resolve?)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(tap: Tap, original_commit: String, labels: T::Array[String]).returns(T::Boolean) }
|
||||||
def formulae_need_bottles?(tap, original_commit, labels)
|
def formulae_need_bottles?(tap, original_commit, labels)
|
||||||
return false if args.dry_run?
|
return false if args.dry_run?
|
||||||
|
|
||||||
@ -437,6 +470,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(tap: Tap, original_commit: String).returns(T::Array[String]) }
|
||||||
def changed_packages(tap, original_commit)
|
def changed_packages(tap, original_commit)
|
||||||
formulae = Utils.popen_read("git", "-C", tap.path, "diff-tree",
|
formulae = Utils.popen_read("git", "-C", tap.path, "diff-tree",
|
||||||
"-r", "--name-only", "--diff-filter=AM",
|
"-r", "--name-only", "--diff-filter=AM",
|
||||||
@ -473,6 +507,7 @@ module Homebrew
|
|||||||
formulae + casks
|
formulae + casks
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(repo: String, pull_request: String).void }
|
||||||
def pr_check_conflicts(repo, pull_request)
|
def pr_check_conflicts(repo, pull_request)
|
||||||
long_build_pr_files = GitHub.issues(
|
long_build_pr_files = GitHub.issues(
|
||||||
repo:, state: "open", labels: "no long build conflict",
|
repo:, state: "open", labels: "no long build conflict",
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -120,6 +120,7 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { params(bottles_hash: T::Hash[String, T.untyped]).void }
|
||||||
def check_bottled_formulae!(bottles_hash)
|
def check_bottled_formulae!(bottles_hash)
|
||||||
bottles_hash.each do |name, bottle_hash|
|
bottles_hash.each do |name, bottle_hash|
|
||||||
formula_path = HOMEBREW_REPOSITORY/bottle_hash["formula"]["path"]
|
formula_path = HOMEBREW_REPOSITORY/bottle_hash["formula"]["path"]
|
||||||
@ -131,22 +132,25 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(bottles_hash: T::Hash[String, T.untyped]).returns(T::Boolean) }
|
||||||
def github_releases?(bottles_hash)
|
def github_releases?(bottles_hash)
|
||||||
@github_releases ||= bottles_hash.values.all? do |bottle_hash|
|
@github_releases ||= T.let(bottles_hash.values.all? do |bottle_hash|
|
||||||
root_url = bottle_hash["bottle"]["root_url"]
|
root_url = bottle_hash["bottle"]["root_url"]
|
||||||
url_match = root_url.match GitHubReleases::URL_REGEX
|
url_match = root_url.match GitHubReleases::URL_REGEX
|
||||||
_, _, _, tag = *url_match
|
_, _, _, tag = *url_match
|
||||||
|
|
||||||
tag
|
tag
|
||||||
end
|
end, T.nilable(T::Boolean))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(bottles_hash: T::Hash[String, T.untyped]).returns(T::Boolean) }
|
||||||
def github_packages?(bottles_hash)
|
def github_packages?(bottles_hash)
|
||||||
@github_packages ||= bottles_hash.values.all? do |bottle_hash|
|
@github_packages ||= T.let(bottles_hash.values.all? do |bottle_hash|
|
||||||
bottle_hash["bottle"]["root_url"].match? GitHubPackages::URL_REGEX
|
bottle_hash["bottle"]["root_url"].match? GitHubPackages::URL_REGEX
|
||||||
end
|
end, T.nilable(T::Boolean))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(json_files: T::Array[String], args: T.untyped).returns(T::Hash[String, T.untyped]) }
|
||||||
def bottles_hash_from_json_files(json_files, args)
|
def bottles_hash_from_json_files(json_files, args)
|
||||||
puts "Reading JSON files: #{json_files.join(", ")}" if args.verbose?
|
puts "Reading JSON files: #{json_files.join(", ")}" if args.verbose?
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -197,6 +197,7 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { params(tap: Tap, filename: T.any(String, Pathname), content: String).void }
|
||||||
def write_path(tap, filename, content)
|
def write_path(tap, filename, content)
|
||||||
path = tap.path/filename
|
path = tap.path/filename
|
||||||
tap.path.mkpath
|
tap.path.mkpath
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -110,8 +110,9 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { params(formula: Formula).returns(T::Boolean) }
|
||||||
def retry_test?(formula)
|
def retry_test?(formula)
|
||||||
@test_failed ||= Set.new
|
@test_failed ||= T.let(Set.new, T.nilable(T::Set[T.untyped]))
|
||||||
if args.retry? && @test_failed.add?(formula)
|
if args.retry? && @test_failed.add?(formula)
|
||||||
oh1 "Testing #{formula.full_name} (again)"
|
oh1 "Testing #{formula.full_name} (again)"
|
||||||
formula.clear_cache
|
formula.clear_cache
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -168,15 +168,17 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { returns(T.nilable(T::Boolean)) }
|
||||||
def use_buildpulse?
|
def use_buildpulse?
|
||||||
return @use_buildpulse if defined?(@use_buildpulse)
|
return @use_buildpulse if defined?(@use_buildpulse)
|
||||||
|
|
||||||
@use_buildpulse = ENV["HOMEBREW_BUILDPULSE_ACCESS_KEY_ID"].present? &&
|
@use_buildpulse = T.let(ENV["HOMEBREW_BUILDPULSE_ACCESS_KEY_ID"].present? &&
|
||||||
ENV["HOMEBREW_BUILDPULSE_SECRET_ACCESS_KEY"].present? &&
|
ENV["HOMEBREW_BUILDPULSE_SECRET_ACCESS_KEY"].present? &&
|
||||||
ENV["HOMEBREW_BUILDPULSE_ACCOUNT_ID"].present? &&
|
ENV["HOMEBREW_BUILDPULSE_ACCOUNT_ID"].present? &&
|
||||||
ENV["HOMEBREW_BUILDPULSE_REPOSITORY_ID"].present?
|
ENV["HOMEBREW_BUILDPULSE_REPOSITORY_ID"].present?, T.nilable(T::Boolean))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def run_buildpulse
|
def run_buildpulse
|
||||||
require "formula"
|
require "formula"
|
||||||
|
|
||||||
@ -198,6 +200,7 @@ module Homebrew
|
|||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Array[String]) }
|
||||||
def changed_test_files
|
def changed_test_files
|
||||||
changed_files = Utils.popen_read("git", "diff", "--name-only", "master")
|
changed_files = Utils.popen_read("git", "diff", "--name-only", "master")
|
||||||
|
|
||||||
@ -215,6 +218,7 @@ module Homebrew
|
|||||||
end.select(&:exist?)
|
end.select(&:exist?)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Array[String]) }
|
||||||
def setup_environment!
|
def setup_environment!
|
||||||
# Cleanup any unwanted user configuration.
|
# Cleanup any unwanted user configuration.
|
||||||
allowed_test_env = %w[
|
allowed_test_env = %w[
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -34,11 +34,15 @@ module Homebrew
|
|||||||
def run
|
def run
|
||||||
Formulary.enable_factory_cache!
|
Formulary.enable_factory_cache!
|
||||||
|
|
||||||
@bottle_tag = if (tag = args.tag)
|
@bottle_tag = T.let(
|
||||||
|
if (tag = args.tag)
|
||||||
Utils::Bottles::Tag.from_symbol(tag.to_sym)
|
Utils::Bottles::Tag.from_symbol(tag.to_sym)
|
||||||
else
|
else
|
||||||
Utils::Bottles.tag
|
Utils::Bottles.tag
|
||||||
end
|
end,
|
||||||
|
T.nilable(Utils::Bottles::Tag),
|
||||||
|
)
|
||||||
|
return unless @bottle_tag
|
||||||
|
|
||||||
if args.lost?
|
if args.lost?
|
||||||
if args.named.present?
|
if args.named.present?
|
||||||
@ -98,12 +102,17 @@ module Homebrew
|
|||||||
["installs", formula_installs]
|
["installs", formula_installs]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return if hash.nil?
|
||||||
|
|
||||||
output_unbottled(formulae, deps_hash, noun, hash, args.named.present?)
|
output_unbottled(formulae, deps_hash, noun, hash, args.named.present?)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(all: T::Boolean).returns([T::Array[Formula], T::Array[Formula], T.nilable(T::Hash[Symbol, Integer])])
|
||||||
|
}
|
||||||
def formulae_all_installs_from_args(all)
|
def formulae_all_installs_from_args(all)
|
||||||
if args.named.present?
|
if args.named.present?
|
||||||
formulae = all_formulae = args.named.to_formulae
|
formulae = all_formulae = args.named.to_formulae
|
||||||
@ -115,7 +124,7 @@ module Homebrew
|
|||||||
|
|
||||||
formulae = all_formulae = Formula.all(eval_all: args.eval_all?)
|
formulae = all_formulae = Formula.all(eval_all: args.eval_all?)
|
||||||
|
|
||||||
@sort = " (sorted by number of dependents)"
|
@sort = T.let(" (sorted by number of dependents)", T.nilable(String))
|
||||||
elsif all
|
elsif all
|
||||||
formulae = all_formulae = Formula.all(eval_all: args.eval_all?)
|
formulae = all_formulae = Formula.all(eval_all: args.eval_all?)
|
||||||
else
|
else
|
||||||
@ -142,7 +151,7 @@ module Homebrew
|
|||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@sort = " (sorted by installs in the last 90 days; top 10,000 only)"
|
@sort = T.let(" (sorted by installs in the last 90 days; top 10,000 only)", T.nilable(String))
|
||||||
|
|
||||||
all_formulae = Formula.all(eval_all: args.eval_all?)
|
all_formulae = Formula.all(eval_all: args.eval_all?)
|
||||||
end
|
end
|
||||||
@ -151,9 +160,11 @@ module Homebrew
|
|||||||
formulae = Array(formulae).reject(&:deprecated?) if formulae.present?
|
formulae = Array(formulae).reject(&:deprecated?) if formulae.present?
|
||||||
all_formulae = Array(all_formulae).reject(&:deprecated?) if all_formulae.present?
|
all_formulae = Array(all_formulae).reject(&:deprecated?) if all_formulae.present?
|
||||||
|
|
||||||
[formulae, all_formulae, formula_installs]
|
[T.let(formulae, T::Array[Formula]), T.let(all_formulae, T::Array[Formula]),
|
||||||
|
T.let(formula_installs, T.nilable(T::Hash[Symbol, Integer]))]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(all_formulae: T.untyped).returns([T::Hash[String, T.untyped], T::Hash[String, T.untyped]]) }
|
||||||
def deps_uses_from_formulae(all_formulae)
|
def deps_uses_from_formulae(all_formulae)
|
||||||
ohai "Populating dependency tree..."
|
ohai "Populating dependency tree..."
|
||||||
|
|
||||||
@ -175,7 +186,10 @@ module Homebrew
|
|||||||
[deps_hash, uses_hash]
|
[deps_hash, uses_hash]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formulae: T::Array[Formula]).returns(NilClass) }
|
||||||
def output_total(formulae)
|
def output_total(formulae)
|
||||||
|
return unless @bottle_tag
|
||||||
|
|
||||||
ohai "Unbottled :#{@bottle_tag} formulae"
|
ohai "Unbottled :#{@bottle_tag} formulae"
|
||||||
unbottled_formulae = 0
|
unbottled_formulae = 0
|
||||||
|
|
||||||
@ -188,7 +202,14 @@ module Homebrew
|
|||||||
puts "#{unbottled_formulae}/#{formulae.length} remaining."
|
puts "#{unbottled_formulae}/#{formulae.length} remaining."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(formulae: T::Array[Formula], deps_hash: T::Hash[T.any(Symbol, String), T.untyped],
|
||||||
|
noun: T.nilable(String), hash: T::Hash[T.any(Symbol, String), T.untyped],
|
||||||
|
any_named_args: T::Boolean).returns(NilClass)
|
||||||
|
}
|
||||||
def output_unbottled(formulae, deps_hash, noun, hash, any_named_args)
|
def output_unbottled(formulae, deps_hash, noun, hash, any_named_args)
|
||||||
|
return unless @bottle_tag
|
||||||
|
|
||||||
ohai ":#{@bottle_tag} bottle status#{@sort}"
|
ohai ":#{@bottle_tag} bottle status#{@sort}"
|
||||||
any_found = T.let(false, T::Boolean)
|
any_found = T.let(false, T::Boolean)
|
||||||
|
|
||||||
@ -258,6 +279,7 @@ module Homebrew
|
|||||||
puts "No unbottled dependencies found!"
|
puts "No unbottled dependencies found!"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(NilClass) }
|
||||||
def output_lost_bottles
|
def output_lost_bottles
|
||||||
ohai ":#{@bottle_tag} lost bottles"
|
ohai ":#{@bottle_tag} lost bottles"
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: true
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -62,14 +62,17 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { params(sponsor: T::Hash[Symbol, T.untyped]).returns(T.nilable(String)) }
|
||||||
def sponsor_name(sponsor)
|
def sponsor_name(sponsor)
|
||||||
sponsor[:name] || sponsor[:login]
|
sponsor[:name] || sponsor[:login]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(sponsor: T::Hash[Symbol, T.untyped]).returns(String) }
|
||||||
def sponsor_logo(sponsor)
|
def sponsor_logo(sponsor)
|
||||||
"https://github.com/#{sponsor[:login]}.png?size=64"
|
"https://github.com/#{sponsor[:login]}.png?size=64"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(sponsor: T::Hash[Symbol, T.untyped]).returns(String) }
|
||||||
def sponsor_url(sponsor)
|
def sponsor_url(sponsor)
|
||||||
"https://github.com/#{sponsor[:login]}"
|
"https://github.com/#{sponsor[:login]}"
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user