From 46b572d1daa8b7164bb840d9b87bcad17855592f Mon Sep 17 00:00:00 2001
From: Carlo Cabrera <30379873+carlocab@users.noreply.github.com>
Date: Mon, 14 Oct 2024 13:55:28 +0800
Subject: [PATCH] formula_installer: verify attestations at bottle fetch time

See discussion at #18544.
---
 Library/Homebrew/formula_installer.rb | 52 +++++++++++++++++----------
 1 file changed, 33 insertions(+), 19 deletions(-)

diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb
index 52221ac196107d..bc760b4b05ab38 100644
--- a/Library/Homebrew/formula_installer.rb
+++ b/Library/Homebrew/formula_installer.rb
@@ -1306,43 +1306,33 @@ def fetch
 
     oh1 "Fetching #{Formatter.identifier(formula.full_name)}".strip
 
-    if pour_bottle?(output_warning: true)
+    downloadable_object = downloadable
+    check_attestation = if pour_bottle?(output_warning: true)
       fetch_bottle_tab
+
+      !downloadable_object.cached_download.exist?
     else
       @formula = Homebrew::API::Formula.source_download(formula) if formula.loaded_from_api?
 
       formula.fetch_patches
       formula.resources.each(&:fetch)
-    end
-    downloadable.fetch
-
-    self.class.fetched << formula
-  end
 
-  sig { returns(Downloadable) }
-  def downloadable
-    if (bottle_path = formula.local_bottle_path)
-      Resource::Local.new(bottle_path)
-    elsif pour_bottle?
-      T.must(formula.bottle)
-    else
-      T.must(formula.resource)
+      false
     end
-  end
+    downloadable_object.fetch
 
-  sig { void }
-  def pour
     # We skip `gh` to avoid a bootstrapping cycle, in the off-chance a user attempts
     # to explicitly `brew install gh` without already having a version for bootstrapping.
     # We also skip bottle installs from local bottle paths, as these are done in CI
     # as part of the build lifecycle before attestations are produced.
-    if Homebrew::Attestation.enabled? &&
+    if check_attestation &&
+       Homebrew::Attestation.enabled? &&
        formula.tap&.core_tap? &&
        formula.name != "gh" &&
        formula.local_bottle_path.blank?
       ohai "Verifying attestation for #{formula.name}"
       begin
-        Homebrew::Attestation.check_core_attestation T.must(formula.bottle)
+        Homebrew::Attestation.check_core_attestation T.cast(downloadable_object, Bottle)
       rescue Homebrew::Attestation::GhIncompatible
         # A small but significant number of users have developer mode enabled
         # but *also* haven't upgraded in a long time, meaning that their `gh`
@@ -1399,6 +1389,30 @@ def pour
       end
     end
 
+    self.class.fetched << formula
+  rescue CannotInstallFormulaError
+    if downloadable_object &&
+       downloadable_object.respond_to?(:cached_download) &&
+       downloadable_object.cached_download.exist?
+      downloadable_object.cached_download.unlink
+    end
+
+    raise
+  end
+
+  sig { returns(Downloadable) }
+  def downloadable
+    if (bottle_path = formula.local_bottle_path)
+      Resource::Local.new(bottle_path)
+    elsif pour_bottle?
+      T.must(formula.bottle)
+    else
+      T.must(formula.resource)
+    end
+  end
+
+  sig { void }
+  def pour
     HOMEBREW_CELLAR.cd do
       downloadable.downloader.stage
     end