diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index b46b335414..6f96a13ee8 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -473,7 +473,9 @@ module Homebrew if local_bottle_json bottle_path = formula.local_bottle_path - local_filename = bottle_path&.basename&.to_s + return if bottle_path.blank? + + local_filename = bottle_path.basename.to_s tab_path = Utils::Bottles.receipt_path(bottle_path) raise "This bottle does not contain the file INSTALL_RECEIPT.json: #{bottle_path}" unless tab_path @@ -491,6 +493,7 @@ module Homebrew else tar_filename = filename.to_s.sub(/.gz$/, "") tar_path = Pathname.pwd/tar_filename + return if tar_path.blank? keg = Keg.new(formula.prefix) end @@ -549,13 +552,11 @@ module Homebrew Utils::Gzip.compress_with_options(relocatable_tar_path, mtime: tab.source_modified_time, orig_name: relocatable_tar_path, - output: T.must(bottle_path)) + output: bottle_path) sudo_purge end - if bottle_path && bottle_path.size > 1 * 1024 * 1024 - ohai "Detecting if #{local_filename} is relocatable..." - end + ohai "Detecting if #{local_filename} is relocatable..." if bottle_path.size > 1 * 1024 * 1024 prefix_check = if Homebrew.default_prefix?(prefix) File.join(prefix, "opt") @@ -596,7 +597,7 @@ module Homebrew end puts if !relocatable && args.verbose? rescue Interrupt - ignore_interrupts { bottle_path.unlink if bottle_path&.exist? } + ignore_interrupts { bottle_path.unlink if bottle_path.exist? } raise ensure ignore_interrupts do @@ -619,7 +620,7 @@ module Homebrew cellar end bottle.rebuild rebuild - sha256 = bottle_path&.sha256 + sha256 = bottle_path.sha256 bottle.sha256 cellar: bottle_cellar, bottle_tag.to_sym => sha256 old_spec = formula.bottle_specification @@ -628,7 +629,7 @@ module Homebrew old_spec.send(key) == bottle.send(key) end unless mismatches.empty? - bottle_path.unlink if bottle_path&.exist? + bottle_path.unlink if bottle_path.exist? mismatches.map! do |key| old_value = old_spec.send(key).inspect diff --git a/Library/Homebrew/dev-cmd/bump-formula-pr.rb b/Library/Homebrew/dev-cmd/bump-formula-pr.rb index b0e2f8e076..2e3f10b25f 100644 --- a/Library/Homebrew/dev-cmd/bump-formula-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-formula-pr.rb @@ -429,8 +429,10 @@ module Homebrew 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 - partial_old_version = T.must(old_version_parts[0..-2]).join(".") - partial_new_version = T.must(new_version_parts[0..-2]).join(".") + partial_old_version = old_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}/") end @@ -462,10 +464,13 @@ module Homebrew sig { params(formula: Formula, tap_remote_repo: String).returns(T.nilable(T::Array[String])) } def check_open_pull_requests(formula, tap_remote_repo) + tap = formula.tap + return if tap.nil? + GitHub.check_for_duplicate_pull_requests( formula.name, tap_remote_repo, state: "open", - file: formula.path.relative_path_from(T.must(formula.tap).path).to_s, + file: formula.path.relative_path_from(tap.path).to_s, quiet: args.quiet? ) end @@ -488,8 +493,11 @@ module Homebrew sig { params(formula: Formula, new_version: String).returns(NilClass) } def check_throttle(formula, new_version) + tap = formula.tap + return if tap.nil? + throttled_rate = formula.livecheck.throttle - throttled_rate ||= if (rate = T.must(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" rate end @@ -506,12 +514,15 @@ module Homebrew version: T.nilable(String)).returns(T.nilable(T::Array[String])) } 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 GitHub.check_for_duplicate_pull_requests( formula.name, tap_remote_repo, version:, state: "closed", - file: formula.path.relative_path_from(T.must(formula.tap).path).to_s, + file: formula.path.relative_path_from(tap.path).to_s, quiet: args.quiet? ) end @@ -522,9 +533,12 @@ module Homebrew return if versioned_alias.nil? name, old_alias_version = versioned_alias.split("@") - new_alias_regex = (T.must(old_alias_version).split(".").length == 1) ? /^\d+/ : /^\d+\.\d+/ + return if old_alias_version.blank? + + new_alias_regex = (old_alias_version.split(".").length == 1) ? /^\d+/ : /^\d+\.\d+/ new_alias_version, = *new_formula_version.to_s.match(new_alias_regex) - return if Version.new(T.must(new_alias_version)) <= Version.new(T.must(old_alias_version)) + return if new_alias_version.blank? + return if Version.new(new_alias_version) <= Version.new(old_alias_version) [versioned_alias, "#{name}@#{new_alias_version}"] end diff --git a/Library/Homebrew/dev-cmd/contributions.rb b/Library/Homebrew/dev-cmd/contributions.rb index a1fe4b80cd..96159227fa 100644 --- a/Library/Homebrew/dev-cmd/contributions.rb +++ b/Library/Homebrew/dev-cmd/contributions.rb @@ -10,7 +10,7 @@ end module Homebrew module DevCmd class Contributions < AbstractCommand - PRIMARY_REPOS = %w[brew core cask].freeze + PRIMARY_REPOS = T.let(%w[brew core cask].freeze, T::Array[String]) SUPPORTED_REPOS = T.let([ PRIMARY_REPOS, OFFICIAL_CMD_TAPS.keys.map { |t| t.delete_prefix("homebrew/") }, @@ -50,12 +50,12 @@ module Homebrew results = {} grand_totals = {} - repos = if args.repositories.blank? || T.must(args.repositories).include?("primary") + repos = if args.repositories.blank? || args.repositories&.include?("primary") PRIMARY_REPOS - elsif T.must(args.repositories).include?("all") + elsif args.repositories&.include?("all") SUPPORTED_REPOS else - T.must(args.repositories) + args.repositories end from = args.from.presence || Date.today.prev_year.iso8601 @@ -147,8 +147,10 @@ module Homebrew ] end - sig { params(repos: T::Array[String], person: String, from: String).void } + sig { params(repos: T.nilable(T::Array[String]), person: String, from: String).void } def scan_repositories(repos, person, from:) + return if repos.blank? + data = {} repos.each do |repo| diff --git a/Library/Homebrew/dev-cmd/pr-pull.rb b/Library/Homebrew/dev-cmd/pr-pull.rb index 2799830f44..d3f8225109 100644 --- a/Library/Homebrew/dev-cmd/pr-pull.rb +++ b/Library/Homebrew/dev-cmd/pr-pull.rb @@ -126,7 +126,7 @@ module Homebrew cherry_pick_pr!(user, repo, pr, path: tap.path) unless args.no_cherry_pick? if args.autosquash? && !args.dry_run? autosquash!(original_commit, tap:, cherry_picked: !args.no_cherry_pick?, - verbose: args.verbose?, resolve: args.resolve?, reason: T.must(args.message)) + verbose: args.verbose?, resolve: args.resolve?, reason: args.message) end signoff!(git_repo, pull_request: pr, dry_run: args.dry_run?) unless args.clean? end @@ -141,7 +141,7 @@ module Homebrew user, repo, pr, workflow_id: workflow, artifact_pattern: ) if args.ignore_missing_artifacts.present? && - T.must(args.ignore_missing_artifacts).include?(workflow) && + args.ignore_missing_artifacts&.include?(workflow) && workflow_run.first.blank? # Ignore that workflow as it was not executed and we specified # that we could skip it. @@ -185,7 +185,8 @@ module Homebrew # Separates a commit message into subject, body and trailers. sig { params(message: String).returns([String, String, String]) } def separate_commit_message(message) - subject = T.must(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") # from lines that look like regular body text. @@ -194,12 +195,15 @@ module Homebrew trailers = trailers.uniq.join.strip body = body.join.strip.gsub(/\n{3,}/, "\n\n") - [subject, body, trailers] + [first_line.strip, body, trailers] 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) - subject, body, trailers = separate_commit_message(T.must(git_repo.commit_message)) + msg = git_repo.commit_message + return if msg.blank? + + subject, body, trailers = separate_commit_message(msg) if pull_request # This is a tap pull request and approving reviewers should also sign-off. @@ -290,7 +294,10 @@ module Homebrew 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 - subject, body, trailers = separate_commit_message(T.must(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}:") safe_system("git", "-C", git_repo.pathname, "commit", "--amend", "-q", @@ -319,7 +326,10 @@ module Homebrew messages = [] trailers = [] commits.each do |commit| - subject, body, trailer = separate_commit_message(T.must(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") messages << "* #{subject}\n#{body}".strip trailers << trailer @@ -356,12 +366,11 @@ module Homebrew # TODO: fix test in `test/dev-cmd/pr-pull_spec.rb` and assume `cherry_picked: false`. sig { - params(original_commit: String, tap: Tap, reason: String, verbose: T::Boolean, resolve: T::Boolean, + 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) git_repo = tap.git_repository - original_head = git_repo.head_ref commits = Utils.safe_popen_read("git", "-C", tap.path, "rev-list", "--reverse", "#{original_commit}..HEAD").lines.map(&:strip) @@ -421,8 +430,11 @@ module Homebrew end end rescue + original_head = git_repo&.head_ref + return if original_head.nil? + opoo "Autosquash encountered an error; resetting to original state at #{original_head}" - system "git", "-C", tap.path.to_s, "reset", "--hard", T.must(original_head) + system "git", "-C", tap.path.to_s, "reset", "--hard", original_head system "git", "-C", tap.path.to_s, "cherry-pick", "--abort" if cherry_picked raise end diff --git a/Library/Homebrew/dev-cmd/unbottled.rb b/Library/Homebrew/dev-cmd/unbottled.rb index b85e0da356..7a73caf4a1 100644 --- a/Library/Homebrew/dev-cmd/unbottled.rb +++ b/Library/Homebrew/dev-cmd/unbottled.rb @@ -42,6 +42,7 @@ module Homebrew end, T.nilable(Utils::Bottles::Tag), ) + return unless @bottle_tag if args.lost? if args.named.present? @@ -54,13 +55,13 @@ module Homebrew end end - os = T.must(@bottle_tag).system - arch = if Hardware::CPU::INTEL_ARCHS.include?(T.must(@bottle_tag).arch) + os = @bottle_tag.system + arch = if Hardware::CPU::INTEL_ARCHS.include?(@bottle_tag.arch) :intel - elsif Hardware::CPU::ARM_ARCHS.include?(T.must(@bottle_tag).arch) + elsif Hardware::CPU::ARM_ARCHS.include?(@bottle_tag.arch) :arm else - raise "Unknown arch #{T.must(@bottle_tag).arch}." + raise "Unknown arch #{@bottle_tag.arch}." end Homebrew::SimulateSystem.with(os:, arch:) do @@ -101,7 +102,9 @@ module Homebrew ["installs", formula_installs] end - output_unbottled(formulae, deps_hash, noun, T.must(hash), args.named.present?) + return if hash.nil? + + output_unbottled(formulae, deps_hash, noun, hash, args.named.present?) end end @@ -158,7 +161,7 @@ module Homebrew all_formulae = Array(all_formulae).reject(&:deprecated?) if all_formulae.present? [T.let(formulae, T::Array[Formula]), T.let(all_formulae, T::Array[Formula]), - T.let(T.must(formula_installs), T.nilable(T::Hash[Symbol, Integer]))] + T.let(formula_installs, T.nilable(T::Hash[Symbol, Integer]))] end sig { params(all_formulae: T.untyped).returns([T::Hash[String, T.untyped], T::Hash[String, T.untyped]]) } @@ -185,6 +188,8 @@ module Homebrew sig { params(formulae: T::Array[Formula]).returns(NilClass) } def output_total(formulae) + return unless @bottle_tag + ohai "Unbottled :#{@bottle_tag} formulae" unbottled_formulae = 0 @@ -203,6 +208,8 @@ module Homebrew any_named_args: T::Boolean).returns(NilClass) } def output_unbottled(formulae, deps_hash, noun, hash, any_named_args) + return unless @bottle_tag + ohai ":#{@bottle_tag} bottle status#{@sort}" any_found = T.let(false, T::Boolean) @@ -215,7 +222,7 @@ module Homebrew end requirements = f.recursive_requirements - if T.must(@bottle_tag).linux? + if @bottle_tag.linux? if requirements.any? { |r| r.is_a?(MacOSRequirement) && !r.version } puts "#{Tty.bold}#{Tty.red}#{name}#{Tty.reset}: requires macOS" if any_named_args next @@ -224,7 +231,7 @@ module Homebrew puts "#{Tty.bold}#{Tty.red}#{name}#{Tty.reset}: requires Linux" if any_named_args next else - macos_version = T.must(@bottle_tag).to_macos_version + macos_version = @bottle_tag.to_macos_version macos_satisfied = requirements.all? do |r| case r when MacOSRequirement @@ -236,7 +243,7 @@ module Homebrew Version.new(MacOS::Xcode.latest_version(macos: macos_version)) >= r.version when ArchRequirement - r.arch == T.must(@bottle_tag).arch + r.arch == @bottle_tag.arch else true end