Skip to content

Commit 46b572d

Browse files
committed
formula_installer: verify attestations at bottle fetch time
See discussion at #18544.
1 parent d1e539c commit 46b572d

File tree

1 file changed

+33
-19
lines changed

1 file changed

+33
-19
lines changed

Library/Homebrew/formula_installer.rb

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,43 +1306,33 @@ def fetch
13061306

13071307
oh1 "Fetching #{Formatter.identifier(formula.full_name)}".strip
13081308

1309-
if pour_bottle?(output_warning: true)
1309+
downloadable_object = downloadable
1310+
check_attestation = if pour_bottle?(output_warning: true)
13101311
fetch_bottle_tab
1312+
1313+
!downloadable_object.cached_download.exist?
13111314
else
13121315
@formula = Homebrew::API::Formula.source_download(formula) if formula.loaded_from_api?
13131316

13141317
formula.fetch_patches
13151318
formula.resources.each(&:fetch)
1316-
end
1317-
downloadable.fetch
1318-
1319-
self.class.fetched << formula
1320-
end
13211319

1322-
sig { returns(Downloadable) }
1323-
def downloadable
1324-
if (bottle_path = formula.local_bottle_path)
1325-
Resource::Local.new(bottle_path)
1326-
elsif pour_bottle?
1327-
T.must(formula.bottle)
1328-
else
1329-
T.must(formula.resource)
1320+
false
13301321
end
1331-
end
1322+
downloadable_object.fetch
13321323

1333-
sig { void }
1334-
def pour
13351324
# We skip `gh` to avoid a bootstrapping cycle, in the off-chance a user attempts
13361325
# to explicitly `brew install gh` without already having a version for bootstrapping.
13371326
# We also skip bottle installs from local bottle paths, as these are done in CI
13381327
# as part of the build lifecycle before attestations are produced.
1339-
if Homebrew::Attestation.enabled? &&
1328+
if check_attestation &&
1329+
Homebrew::Attestation.enabled? &&
13401330
formula.tap&.core_tap? &&
13411331
formula.name != "gh" &&
13421332
formula.local_bottle_path.blank?
13431333
ohai "Verifying attestation for #{formula.name}"
13441334
begin
1345-
Homebrew::Attestation.check_core_attestation T.must(formula.bottle)
1335+
Homebrew::Attestation.check_core_attestation T.cast(downloadable_object, Bottle)
13461336
rescue Homebrew::Attestation::GhIncompatible
13471337
# A small but significant number of users have developer mode enabled
13481338
# but *also* haven't upgraded in a long time, meaning that their `gh`
@@ -1399,6 +1389,30 @@ def pour
13991389
end
14001390
end
14011391

1392+
self.class.fetched << formula
1393+
rescue CannotInstallFormulaError
1394+
if downloadable_object &&
1395+
downloadable_object.respond_to?(:cached_download) &&
1396+
downloadable_object.cached_download.exist?
1397+
downloadable_object.cached_download.unlink
1398+
end
1399+
1400+
raise
1401+
end
1402+
1403+
sig { returns(Downloadable) }
1404+
def downloadable
1405+
if (bottle_path = formula.local_bottle_path)
1406+
Resource::Local.new(bottle_path)
1407+
elsif pour_bottle?
1408+
T.must(formula.bottle)
1409+
else
1410+
T.must(formula.resource)
1411+
end
1412+
end
1413+
1414+
sig { void }
1415+
def pour
14021416
HOMEBREW_CELLAR.cd do
14031417
downloadable.downloader.stage
14041418
end

0 commit comments

Comments
 (0)