@@ -17,6 +17,15 @@ class FormulaeUpgradeContext < T::Struct
1717 const :formulae_to_install , T ::Array [ Formula ]
1818 const :formulae_installer , T ::Array [ FormulaInstaller ]
1919 const :dependants , Homebrew ::Upgrade ::Dependents
20+ const :pinned_formulae , T ::Array [ Formula ]
21+ end
22+
23+ class FinalUpgradeSummary < T ::Struct
24+ prop :version_changes , T ::Array [ String ] , default : [ ]
25+ prop :pinned_formulae , T ::Array [ String ] , default : [ ]
26+ prop :deprecated , T ::Array [ String ] , default : [ ]
27+ prop :disabled , T ::Array [ String ] , default : [ ]
28+ prop :source_build_formulae , T ::Array [ String ] , default : [ ]
2029 end
2130
2231 cmd_args do
@@ -147,6 +156,7 @@ def run
147156 prefetched_formulae_upgrades = T . let ( [ ] , T ::Array [ String ] )
148157 prefetched_cask_names = T . let ( [ ] , T ::Array [ String ] )
149158 prefetched_cask_upgrades = T . let ( [ ] , T ::Array [ String ] )
159+ @final_upgrade_summary = T . let ( FinalUpgradeSummary . new , T . nilable ( FinalUpgradeSummary ) )
150160
151161 if args . named . present?
152162 args . named . to_formulae_and_casks_and_unavailable ( method : :resolve ) . each do |item |
@@ -237,6 +247,8 @@ def run
237247 Homebrew ::Reinstall . reinstall_pkgconf_if_needed! ( dry_run : args . dry_run? )
238248
239249 Homebrew . messages . display_messages ( display_times : args . display_times? )
250+
251+ show_final_upgrade_summary
240252 end
241253
242254 private
@@ -324,7 +336,16 @@ def formulae_upgrade_context(formulae, show_upgrade_summary: true)
324336 verbose : args . verbose? ,
325337 )
326338
327- return if formulae_installer . blank?
339+ if formulae_installer . blank?
340+ return if pinned . blank?
341+
342+ return FormulaeUpgradeContext . new (
343+ formulae_to_install :,
344+ formulae_installer : formulae_installer ,
345+ dependants : Homebrew ::Upgrade ::Dependents . new ( upgradeable : [ ] , pinned : [ ] , skipped : [ ] ) ,
346+ pinned_formulae : pinned ,
347+ )
348+ end
328349
329350 dependants = Upgrade . dependants (
330351 formulae_to_install ,
@@ -349,9 +370,78 @@ def formulae_upgrade_context(formulae, show_upgrade_summary: true)
349370 formulae_to_install :,
350371 formulae_installer : formulae_installer ,
351372 dependants :,
373+ pinned_formulae : pinned ,
352374 )
353375 end
354376
377+ sig { returns ( FinalUpgradeSummary ) }
378+ def final_upgrade_summary
379+ @final_upgrade_summary ||= T . let ( FinalUpgradeSummary . new , T . nilable ( FinalUpgradeSummary ) )
380+ @final_upgrade_summary
381+ end
382+
383+ sig { params ( context : FormulaeUpgradeContext ) . void }
384+ def record_formula_upgrade_summary ( context )
385+ summary = final_upgrade_summary
386+ summary . version_changes . concat ( formula_upgrade_descriptions ( context . formulae_installer . map ( &:formula ) ) )
387+ summary . version_changes . concat ( formula_upgrade_descriptions ( context . dependants . upgradeable ) )
388+ summary . pinned_formulae . concat ( ( context . pinned_formulae + context . dependants . pinned ) . map do |formula |
389+ "#{ formula . full_specified_name } #{ formula . pkg_version } "
390+ end )
391+
392+ formulae = context . formulae_to_install + context . pinned_formulae +
393+ context . dependants . upgradeable + context . dependants . pinned
394+ summary . deprecated . concat ( formulae . filter_map do |formula |
395+ formula . full_specified_name if formula . deprecated?
396+ end )
397+ summary . disabled . concat ( formulae . filter_map do |formula |
398+ formula . full_specified_name if formula . disabled?
399+ end )
400+ summary . source_build_formulae . concat ( context . formulae_installer . filter_map do |formula_installer |
401+ formula = formula_installer . formula
402+ next unless formula . tap &.official?
403+ next if formula_installer . pour_bottle?
404+
405+ formula . full_specified_name
406+ end )
407+ end
408+
409+ sig { void }
410+ def show_final_upgrade_summary
411+ summary = final_upgrade_summary
412+ return if summary . version_changes . empty? && summary . pinned_formulae . empty? &&
413+ summary . deprecated . empty? && summary . disabled . empty? && summary . source_build_formulae . empty?
414+
415+ oh1 "Final upgrade summary"
416+ show_final_upgrade_summary_section ( "Version changes:" , summary . version_changes )
417+ show_final_upgrade_summary_section (
418+ args . dry_run? ? "Pinned formulae that would be skipped:" : "Pinned formulae skipped:" ,
419+ summary . pinned_formulae ,
420+ )
421+ show_final_upgrade_summary_section ( "Deprecated formulae/casks involved:" , summary . deprecated )
422+ show_final_upgrade_summary_section ( "Disabled formulae/casks involved:" , summary . disabled )
423+ if args . dry_run?
424+ show_final_upgrade_summary_section (
425+ "Official tap formulae that would build from source:" ,
426+ summary . source_build_formulae ,
427+ )
428+ else
429+ show_final_upgrade_summary_section (
430+ "Official tap formulae built from source:" ,
431+ summary . source_build_formulae ,
432+ )
433+ end
434+ end
435+
436+ sig { params ( title : String , items : T ::Array [ String ] ) . void }
437+ def show_final_upgrade_summary_section ( title , items )
438+ items = items . uniq
439+ return if items . empty?
440+
441+ puts title
442+ puts items . map { |item | " #{ item } " } . join ( "\n " )
443+ end
444+
355445 sig { params ( formulae : T ::Array [ Formula ] ) . returns ( T ::Array [ String ] ) }
356446 def formula_upgrade_descriptions ( formulae )
357447 formulae . map do |formula |
@@ -406,6 +496,7 @@ def upgrade_outdated_formulae!(formulae, prefetch_only: false, use_prefetched: f
406496 formulae_to_install : context . formulae_to_install ,
407497 formulae_installer : valid_formula_installers ,
408498 dependants : context . dependants ,
499+ pinned_formulae : context . pinned_formulae ,
409500 )
410501 return valid_formula_installers . present?
411502 end
@@ -432,6 +523,8 @@ def upgrade_outdated_formulae!(formulae, prefetch_only: false, use_prefetched: f
432523 verbose : args . verbose?
433524 )
434525
526+ record_formula_upgrade_summary ( context )
527+
435528 @prefetched_formulae_upgrade_context = nil if use_prefetched_context
436529 true
437530 end
@@ -523,6 +616,9 @@ def upgrade_outdated_casks!(casks, skip_prefetch: false, show_upgrade_summary: t
523616 skip_prefetch :,
524617 show_upgrade_summary :,
525618 download_queue :,
619+ summary_upgrades : final_upgrade_summary . version_changes ,
620+ summary_deprecated : final_upgrade_summary . deprecated ,
621+ summary_disabled : final_upgrade_summary . disabled ,
526622 args :,
527623 )
528624 rescue => e
0 commit comments