| 
									
										
										
										
											2024-08-12 10:30:59 +01:00
										 |  |  | # typed: true # rubocop:todo Sorbet/StrictSigil | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-05 23:19:18 -04:00
										 |  |  | require "diagnostic" | 
					
						
							|  |  |  | require "fileutils" | 
					
						
							|  |  |  | require "hardware" | 
					
						
							|  |  |  | require "development_tools" | 
					
						
							| 
									
										
										
										
											2021-06-15 10:11:40 -04:00
										 |  |  | require "upgrade" | 
					
						
							| 
									
										
										
										
											2025-07-17 17:55:50 +01:00
										 |  |  | require "download_queue" | 
					
						
							| 
									
										
										
										
											2018-06-05 23:19:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2020-08-17 18:39:55 +02:00
										 |  |  |   # Helper module for performing (pre-)install checks. | 
					
						
							| 
									
										
										
										
											2018-06-05 23:19:18 -04:00
										 |  |  |   module Install | 
					
						
							| 
									
										
										
										
											2023-04-17 10:37:59 -07:00
										 |  |  |     class << self | 
					
						
							| 
									
										
										
										
											2024-10-11 16:49:01 +01:00
										 |  |  |       sig { params(all_fatal: T::Boolean).void } | 
					
						
							|  |  |  |       def perform_preinstall_checks_once(all_fatal: false) | 
					
						
							|  |  |  |         @perform_preinstall_checks_once ||= {} | 
					
						
							|  |  |  |         @perform_preinstall_checks_once[all_fatal] ||= begin | 
					
						
							|  |  |  |           perform_preinstall_checks(all_fatal:) | 
					
						
							|  |  |  |           true | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { params(cc: T.nilable(String)).void } | 
					
						
							| 
									
										
										
										
											2024-10-11 16:49:01 +01:00
										 |  |  |       def check_cc_argv(cc) | 
					
						
							|  |  |  |         return unless cc | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @checks ||= Diagnostic::Checks.new | 
					
						
							|  |  |  |         opoo <<~EOS | 
					
						
							|  |  |  |           You passed `--cc=#{cc}`. | 
					
						
							| 
									
										
										
										
											2025-03-31 09:53:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |           #{@checks.support_tier_message(tier: 3)} | 
					
						
							| 
									
										
										
										
											2024-10-11 16:49:01 +01:00
										 |  |  |         EOS | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2020-08-17 18:39:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { params(all_fatal: T::Boolean).void } | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |       def perform_build_from_source_checks(all_fatal: false) | 
					
						
							|  |  |  |         Diagnostic.checks(:fatal_build_from_source_checks) | 
					
						
							|  |  |  |         Diagnostic.checks(:build_from_source_checks, fatal: all_fatal) | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2022-09-09 20:55:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { void } | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |       def global_post_install; end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { void } | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |       def check_prefix | 
					
						
							|  |  |  |         if (Hardware::CPU.intel? || Hardware::CPU.in_rosetta2?) && | 
					
						
							|  |  |  |            HOMEBREW_PREFIX.to_s == HOMEBREW_MACOS_ARM_DEFAULT_PREFIX | 
					
						
							|  |  |  |           if Hardware::CPU.in_rosetta2? | 
					
						
							|  |  |  |             odie <<~EOS | 
					
						
							|  |  |  |               Cannot install under Rosetta 2 in ARM default prefix (#{HOMEBREW_PREFIX})! | 
					
						
							|  |  |  |               To rerun under ARM use: | 
					
						
							|  |  |  |                   arch -arm64 brew install ... | 
					
						
							|  |  |  |               To install under x86_64, install Homebrew into #{HOMEBREW_DEFAULT_PREFIX}. | 
					
						
							|  |  |  |             EOS | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             odie "Cannot install on Intel processor in ARM default prefix (#{HOMEBREW_PREFIX})!" | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         elsif Hardware::CPU.arm? && HOMEBREW_PREFIX.to_s == HOMEBREW_DEFAULT_PREFIX | 
					
						
							| 
									
										
										
										
											2021-01-13 21:16:36 -07:00
										 |  |  |           odie <<~EOS | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |             Cannot install in Homebrew on ARM processor in Intel default prefix (#{HOMEBREW_PREFIX})! | 
					
						
							|  |  |  |             Please create a new installation in #{HOMEBREW_MACOS_ARM_DEFAULT_PREFIX} using one of the | 
					
						
							|  |  |  |             "Alternative Installs" from: | 
					
						
							|  |  |  |               #{Formatter.url("https://docs.brew.sh/Installation")} | 
					
						
							|  |  |  |             You can migrate your previously installed formula list with: | 
					
						
							|  |  |  |               brew bundle dump | 
					
						
							| 
									
										
										
										
											2021-01-13 21:16:36 -07:00
										 |  |  |           EOS | 
					
						
							| 
									
										
										
										
											2020-12-22 08:41:49 +00:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2020-11-12 17:06:47 +00:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2018-06-05 23:19:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { | 
					
						
							|  |  |  |         params(formula: Formula, head: T::Boolean, fetch_head: T::Boolean, | 
					
						
							|  |  |  |                only_dependencies: T::Boolean, force: T::Boolean, quiet: T::Boolean, | 
					
						
							|  |  |  |                skip_link: T::Boolean, overwrite: T::Boolean).returns(T::Boolean) | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |       def install_formula?( | 
					
						
							|  |  |  |         formula, | 
					
						
							|  |  |  |         head: false, | 
					
						
							|  |  |  |         fetch_head: false, | 
					
						
							|  |  |  |         only_dependencies: false, | 
					
						
							|  |  |  |         force: false, | 
					
						
							| 
									
										
										
										
											2024-10-08 11:19:58 -07:00
										 |  |  |         quiet: false, | 
					
						
							| 
									
										
										
										
											2025-01-23 14:42:03 +00:00
										 |  |  |         skip_link: false, | 
					
						
							| 
									
										
										
										
											2024-10-08 11:19:58 -07:00
										 |  |  |         overwrite: false | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |       ) | 
					
						
							|  |  |  |         # head-only without --HEAD is an error | 
					
						
							|  |  |  |         if !head && formula.stable.nil? | 
					
						
							|  |  |  |           odie <<~EOS | 
					
						
							|  |  |  |             #{formula.full_name} is a head-only formula. | 
					
						
							|  |  |  |             To install it, run: | 
					
						
							|  |  |  |               brew install --HEAD #{formula.full_name} | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  |           EOS | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         # --HEAD, fail with no head defined | 
					
						
							|  |  |  |         odie "No head is defined for #{formula.full_name}" if head && formula.head.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         installed_head_version = formula.latest_head_version | 
					
						
							|  |  |  |         if installed_head_version && | 
					
						
							| 
									
										
										
										
											2024-03-07 16:20:20 +00:00
										 |  |  |            !formula.head_version_outdated?(installed_head_version, fetch_head:) | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |           new_head_installed = true | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         prefix_installed = formula.prefix.exist? && !formula.prefix.children.empty? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-25 09:39:19 +01:00
										 |  |  |         # Check if the installed formula is from a different tap | 
					
						
							|  |  |  |         if formula.any_version_installed? && | 
					
						
							|  |  |  |            (current_tap_name = formula.tap&.name.presence) && | 
					
						
							|  |  |  |            (installed_keg_tab = formula.any_installed_keg&.tab.presence) && | 
					
						
							|  |  |  |            (installed_tap_name = installed_keg_tab.tap&.name.presence) && | 
					
						
							|  |  |  |            installed_tap_name != current_tap_name | 
					
						
							|  |  |  |           odie <<~EOS | 
					
						
							|  |  |  |             #{formula.name} was installed from the #{Formatter.identifier(installed_tap_name)} tap | 
					
						
							|  |  |  |             but you are trying to install it from the #{Formatter.identifier(current_tap_name)} tap. | 
					
						
							|  |  |  |             Formulae with the same name from different taps cannot be installed at the same time. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             To install this version, you must first uninstall the existing formula: | 
					
						
							|  |  |  |               brew uninstall #{formula.name} | 
					
						
							|  |  |  |             Then you can install the desired version: | 
					
						
							|  |  |  |               brew install #{formula.full_name} | 
					
						
							|  |  |  |           EOS | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         if formula.keg_only? && formula.any_version_installed? && formula.optlinked? && !force | 
					
						
							|  |  |  |           # keg-only install is only possible when no other version is | 
					
						
							|  |  |  |           # linked to opt, because installing without any warnings can break | 
					
						
							|  |  |  |           # dependencies. Therefore before performing other checks we need to be | 
					
						
							| 
									
										
										
										
											2023-09-08 14:46:15 -04:00
										 |  |  |           # sure the --force switch is passed. | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |           if formula.outdated? | 
					
						
							|  |  |  |             if !Homebrew::EnvConfig.no_install_upgrade? && !formula.pinned? | 
					
						
							|  |  |  |               name = formula.name | 
					
						
							|  |  |  |               version = formula.linked_version | 
					
						
							|  |  |  |               puts "#{name} #{version} is already installed but outdated (so it will be upgraded)." | 
					
						
							|  |  |  |               return true | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             unpin_cmd_if_needed = ("brew unpin #{formula.full_name} && " if formula.pinned?) | 
					
						
							|  |  |  |             optlinked_version = Keg.for(formula.opt_prefix).version | 
					
						
							|  |  |  |             onoe <<~EOS | 
					
						
							|  |  |  |               #{formula.full_name} #{optlinked_version} is already installed. | 
					
						
							|  |  |  |               To upgrade to #{formula.version}, run: | 
					
						
							|  |  |  |                 #{unpin_cmd_if_needed}brew upgrade #{formula.full_name} | 
					
						
							|  |  |  |             EOS | 
					
						
							|  |  |  |           elsif only_dependencies | 
					
						
							|  |  |  |             return true | 
					
						
							|  |  |  |           elsif !quiet | 
					
						
							|  |  |  |             opoo <<~EOS | 
					
						
							|  |  |  |               #{formula.full_name} #{formula.pkg_version} is already installed and up-to-date. | 
					
						
							|  |  |  |               To reinstall #{formula.pkg_version}, run: | 
					
						
							|  |  |  |                 brew reinstall #{formula.name} | 
					
						
							|  |  |  |             EOS | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         elsif (head && new_head_installed) || prefix_installed | 
					
						
							| 
									
										
										
										
											2023-09-08 14:46:15 -04:00
										 |  |  |           # After we're sure the --force switch was passed for linking to opt | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |           # keg-only we need to be sure that the version we're attempting to | 
					
						
							|  |  |  |           # install is not already installed. | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |           installed_version = if head | 
					
						
							|  |  |  |             formula.latest_head_version | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  |           else | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |             formula.pkg_version | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  |           end | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |           msg = "#{formula.full_name} #{installed_version} is already installed" | 
					
						
							|  |  |  |           linked_not_equals_installed = formula.linked_version != installed_version | 
					
						
							|  |  |  |           if formula.linked? && linked_not_equals_installed | 
					
						
							|  |  |  |             msg = if quiet | 
					
						
							|  |  |  |               nil | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |               <<~EOS | 
					
						
							|  |  |  |                 #{msg}. | 
					
						
							|  |  |  |                 The currently linked version is: #{formula.linked_version} | 
					
						
							|  |  |  |               EOS | 
					
						
							|  |  |  |             end | 
					
						
							| 
									
										
										
										
											2024-10-08 11:19:58 -07:00
										 |  |  |           elsif only_dependencies || (!formula.linked? && overwrite) | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |             msg = nil | 
					
						
							|  |  |  |             return true | 
					
						
							|  |  |  |           elsif !formula.linked? || formula.keg_only? | 
					
						
							|  |  |  |             msg = <<~EOS | 
					
						
							|  |  |  |               #{msg}, it's just not linked. | 
					
						
							|  |  |  |               To link this version, run: | 
					
						
							|  |  |  |                 brew link #{formula} | 
					
						
							|  |  |  |             EOS | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  |           else | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |             msg = if quiet | 
					
						
							|  |  |  |               nil | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |               <<~EOS | 
					
						
							|  |  |  |                 #{msg} and up-to-date. | 
					
						
							|  |  |  |                 To reinstall #{formula.pkg_version}, run: | 
					
						
							|  |  |  |                   brew reinstall #{formula.name} | 
					
						
							|  |  |  |               EOS | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |           opoo msg if msg | 
					
						
							|  |  |  |         elsif !formula.any_version_installed? && (old_formula = formula.old_installed_formulae.first) | 
					
						
							|  |  |  |           msg = "#{old_formula.full_name} #{old_formula.any_installed_version} already installed" | 
					
						
							|  |  |  |           msg = if !old_formula.linked? && !old_formula.keg_only? | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  |             <<~EOS | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |               #{msg}, it's just not linked. | 
					
						
							|  |  |  |               To link this version, run: | 
					
						
							|  |  |  |                 brew link #{old_formula.full_name} | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  |             EOS | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |           elsif quiet | 
					
						
							|  |  |  |             nil | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             "#{msg}." | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  |           end | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |           opoo msg if msg | 
					
						
							|  |  |  |         elsif formula.migration_needed? && !force | 
					
						
							|  |  |  |           # Check if the formula we try to install is the same as installed | 
					
						
							|  |  |  |           # but not migrated one. If --force is passed then install anyway. | 
					
						
							|  |  |  |           opoo <<~EOS | 
					
						
							| 
									
										
										
										
											2023-04-27 04:09:28 +01:00
										 |  |  |             #{formula.oldnames_to_migrate.first} is already installed, it's just not migrated. | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |             To migrate this formula, run: | 
					
						
							|  |  |  |               brew migrate #{formula} | 
					
						
							|  |  |  |             Or to force-install it, run: | 
					
						
							|  |  |  |               brew install #{formula} --force | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  |           EOS | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         elsif formula.linked? | 
					
						
							|  |  |  |           message = "#{formula.name} #{formula.linked_version} is already installed" | 
					
						
							|  |  |  |           if formula.outdated? && !head | 
					
						
							|  |  |  |             if !Homebrew::EnvConfig.no_install_upgrade? && !formula.pinned? | 
					
						
							|  |  |  |               puts "#{message} but outdated (so it will be upgraded)." | 
					
						
							|  |  |  |               return true | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             unpin_cmd_if_needed = ("brew unpin #{formula.full_name} && " if formula.pinned?) | 
					
						
							|  |  |  |             onoe <<~EOS | 
					
						
							|  |  |  |               #{message} | 
					
						
							|  |  |  |               To upgrade to #{formula.pkg_version}, run: | 
					
						
							|  |  |  |                 #{unpin_cmd_if_needed}brew upgrade #{formula.full_name} | 
					
						
							|  |  |  |             EOS | 
					
						
							| 
									
										
										
										
											2025-01-23 14:42:03 +00:00
										 |  |  |           elsif only_dependencies || skip_link | 
					
						
							| 
									
										
										
										
											2021-09-10 08:31:53 -07:00
										 |  |  |             return true | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |           else | 
					
						
							|  |  |  |             onoe <<~EOS | 
					
						
							|  |  |  |               #{message} | 
					
						
							|  |  |  |               To install #{formula.pkg_version}, first run: | 
					
						
							|  |  |  |                 brew unlink #{formula.name} | 
					
						
							|  |  |  |             EOS | 
					
						
							| 
									
										
										
										
											2021-09-10 08:31:53 -07:00
										 |  |  |           end | 
					
						
							| 
									
										
										
										
											2021-09-10 06:06:02 -07:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |           # If none of the above is true and the formula is linked, then | 
					
						
							|  |  |  |           # FormulaInstaller will handle this case. | 
					
						
							|  |  |  |           return true | 
					
						
							| 
									
										
										
										
											2021-09-10 06:06:02 -07:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         # Even if we don't install this formula mark it as no longer just | 
					
						
							|  |  |  |         # installed as a dependency. | 
					
						
							|  |  |  |         return false unless formula.opt_prefix.directory? | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         keg = Keg.new(formula.opt_prefix.resolved_path) | 
					
						
							| 
									
										
										
										
											2024-04-28 03:23:21 +02:00
										 |  |  |         tab = keg.tab | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         unless tab.installed_on_request | 
					
						
							|  |  |  |           tab.installed_on_request = true | 
					
						
							|  |  |  |           tab.write | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         false | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2021-06-10 10:50:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { | 
					
						
							|  |  |  |         params(formulae_to_install: T::Array[Formula], installed_on_request: T::Boolean, | 
					
						
							|  |  |  |                installed_as_dependency: T::Boolean, build_bottle: T::Boolean, force_bottle: T::Boolean, | 
					
						
							|  |  |  |                bottle_arch: T.nilable(String), ignore_deps: T::Boolean, only_deps: T::Boolean, | 
					
						
							|  |  |  |                include_test_formulae: T::Array[String], build_from_source_formulae: T::Array[String], | 
					
						
							|  |  |  |                cc: T.nilable(String), git: T::Boolean, interactive: T::Boolean, keep_tmp: T::Boolean, | 
					
						
							|  |  |  |                debug_symbols: T::Boolean, force: T::Boolean, overwrite: T::Boolean, debug: T::Boolean, | 
					
						
							|  |  |  |                quiet: T::Boolean, verbose: T::Boolean, dry_run: T::Boolean, skip_post_install: T::Boolean, | 
					
						
							|  |  |  |                skip_link: T::Boolean).returns(T::Array[FormulaInstaller]) | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2025-06-20 11:10:18 -04:00
										 |  |  |       def formula_installers( | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         formulae_to_install, | 
					
						
							| 
									
										
										
										
											2025-03-21 15:49:22 +00:00
										 |  |  |         installed_on_request: true, | 
					
						
							|  |  |  |         installed_as_dependency: false, | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         build_bottle: false, | 
					
						
							|  |  |  |         force_bottle: false, | 
					
						
							|  |  |  |         bottle_arch: nil, | 
					
						
							|  |  |  |         ignore_deps: false, | 
					
						
							|  |  |  |         only_deps: false, | 
					
						
							|  |  |  |         include_test_formulae: [], | 
					
						
							|  |  |  |         build_from_source_formulae: [], | 
					
						
							|  |  |  |         cc: nil, | 
					
						
							|  |  |  |         git: false, | 
					
						
							|  |  |  |         interactive: false, | 
					
						
							|  |  |  |         keep_tmp: false, | 
					
						
							|  |  |  |         debug_symbols: false, | 
					
						
							|  |  |  |         force: false, | 
					
						
							|  |  |  |         overwrite: false, | 
					
						
							|  |  |  |         debug: false, | 
					
						
							|  |  |  |         quiet: false, | 
					
						
							|  |  |  |         verbose: false, | 
					
						
							|  |  |  |         dry_run: false, | 
					
						
							| 
									
										
										
										
											2025-01-23 14:42:03 +00:00
										 |  |  |         skip_post_install: false, | 
					
						
							|  |  |  |         skip_link: false | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |       ) | 
					
						
							| 
									
										
										
										
											2025-06-08 12:34:24 -04:00
										 |  |  |         formulae_to_install.filter_map do |formula| | 
					
						
							| 
									
										
										
										
											2024-03-07 16:20:20 +00:00
										 |  |  |           Migrator.migrate_if_needed(formula, force:, dry_run:) | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |           build_options = formula.build | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-08 12:34:24 -04:00
										 |  |  |           FormulaInstaller.new( | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |             formula, | 
					
						
							|  |  |  |             options:                    build_options.used_options, | 
					
						
							| 
									
										
										
										
											2025-03-21 15:49:22 +00:00
										 |  |  |             installed_on_request:, | 
					
						
							|  |  |  |             installed_as_dependency:, | 
					
						
							| 
									
										
										
										
											2024-03-07 16:20:20 +00:00
										 |  |  |             build_bottle:, | 
					
						
							|  |  |  |             force_bottle:, | 
					
						
							|  |  |  |             bottle_arch:, | 
					
						
							|  |  |  |             ignore_deps:, | 
					
						
							|  |  |  |             only_deps:, | 
					
						
							|  |  |  |             include_test_formulae:, | 
					
						
							|  |  |  |             build_from_source_formulae:, | 
					
						
							|  |  |  |             cc:, | 
					
						
							|  |  |  |             git:, | 
					
						
							|  |  |  |             interactive:, | 
					
						
							|  |  |  |             keep_tmp:, | 
					
						
							|  |  |  |             debug_symbols:, | 
					
						
							|  |  |  |             force:, | 
					
						
							|  |  |  |             overwrite:, | 
					
						
							|  |  |  |             debug:, | 
					
						
							|  |  |  |             quiet:, | 
					
						
							|  |  |  |             verbose:, | 
					
						
							|  |  |  |             skip_post_install:, | 
					
						
							| 
									
										
										
										
											2025-01-23 14:42:03 +00:00
										 |  |  |             skip_link:, | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |           ) | 
					
						
							| 
									
										
										
										
											2024-02-22 23:29:55 +00:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2025-06-08 12:34:24 -04:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2021-09-01 22:27:34 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { params(formula_installers: T::Array[FormulaInstaller]).returns(T::Array[FormulaInstaller]) } | 
					
						
							|  |  |  |       def fetch_formulae(formula_installers) | 
					
						
							|  |  |  |         formulae_names_to_install = formula_installers.map { |fi| fi.formula.name } | 
					
						
							|  |  |  |         return formula_installers if formulae_names_to_install.empty? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         formula_sentence = formulae_names_to_install.map { |name| Formatter.identifier(name) }.to_sentence | 
					
						
							|  |  |  |         oh1 "Fetching downloads for: #{formula_sentence}", truncate: false | 
					
						
							|  |  |  |         if EnvConfig.download_concurrency > 1
 | 
					
						
							|  |  |  |           download_queue = Homebrew::DownloadQueue.new(pour: true) | 
					
						
							|  |  |  |           formula_installers.each do |fi| | 
					
						
							|  |  |  |             fi.download_queue = download_queue | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         valid_formula_installers = formula_installers.dup | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         begin | 
					
						
							|  |  |  |           [:prelude_fetch, :prelude, :fetch].each do |step| | 
					
						
							|  |  |  |             valid_formula_installers.select! do |fi| | 
					
						
							|  |  |  |               fi.public_send(step) | 
					
						
							|  |  |  |               true | 
					
						
							|  |  |  |             rescue CannotInstallFormulaError => e | 
					
						
							|  |  |  |               ofail e.message | 
					
						
							|  |  |  |               false | 
					
						
							|  |  |  |             rescue UnsatisfiedRequirements, DownloadError, ChecksumMismatchError => e | 
					
						
							|  |  |  |               ofail "#{fi.formula}: #{e}" | 
					
						
							|  |  |  |               false | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |             download_queue&.fetch | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         ensure | 
					
						
							|  |  |  |           download_queue&.shutdown | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         valid_formula_installers | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       sig { | 
					
						
							|  |  |  |         params(formula_installers: T::Array[FormulaInstaller], installed_on_request: T::Boolean, | 
					
						
							|  |  |  |                installed_as_dependency: T::Boolean, build_bottle: T::Boolean, force_bottle: T::Boolean, | 
					
						
							|  |  |  |                bottle_arch: T.nilable(String), ignore_deps: T::Boolean, only_deps: T::Boolean, | 
					
						
							|  |  |  |                include_test_formulae: T::Array[String], build_from_source_formulae: T::Array[String], | 
					
						
							|  |  |  |                cc: T.nilable(String), git: T::Boolean, interactive: T::Boolean, keep_tmp: T::Boolean, | 
					
						
							|  |  |  |                debug_symbols: T::Boolean, force: T::Boolean, overwrite: T::Boolean, debug: T::Boolean, | 
					
						
							|  |  |  |                quiet: T::Boolean, verbose: T::Boolean, dry_run: T::Boolean, | 
					
						
							|  |  |  |                skip_post_install: T::Boolean, skip_link: T::Boolean).void | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2025-06-08 12:34:24 -04:00
										 |  |  |       def install_formulae( | 
					
						
							|  |  |  |         formula_installers, | 
					
						
							|  |  |  |         installed_on_request: true, | 
					
						
							|  |  |  |         installed_as_dependency: false, | 
					
						
							|  |  |  |         build_bottle: false, | 
					
						
							|  |  |  |         force_bottle: false, | 
					
						
							|  |  |  |         bottle_arch: nil, | 
					
						
							|  |  |  |         ignore_deps: false, | 
					
						
							|  |  |  |         only_deps: false, | 
					
						
							|  |  |  |         include_test_formulae: [], | 
					
						
							|  |  |  |         build_from_source_formulae: [], | 
					
						
							|  |  |  |         cc: nil, | 
					
						
							|  |  |  |         git: false, | 
					
						
							|  |  |  |         interactive: false, | 
					
						
							|  |  |  |         keep_tmp: false, | 
					
						
							|  |  |  |         debug_symbols: false, | 
					
						
							|  |  |  |         force: false, | 
					
						
							|  |  |  |         overwrite: false, | 
					
						
							|  |  |  |         debug: false, | 
					
						
							|  |  |  |         quiet: false, | 
					
						
							|  |  |  |         verbose: false, | 
					
						
							|  |  |  |         dry_run: false, | 
					
						
							|  |  |  |         skip_post_install: false, | 
					
						
							|  |  |  |         skip_link: false | 
					
						
							|  |  |  |       ) | 
					
						
							| 
									
										
										
										
											2025-07-17 17:55:50 +01:00
										 |  |  |         formulae_names_to_install = formula_installers.map { |fi| fi.formula.name } | 
					
						
							|  |  |  |         return if formulae_names_to_install.empty? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if dry_run | 
					
						
							|  |  |  |           ohai "Would install #{Utils.pluralize("formula", formulae_names_to_install.count, | 
					
						
							|  |  |  |                                                 plural: "e", include_count: true)}:"
 | 
					
						
							|  |  |  |           puts formulae_names_to_install.join(" ") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-26 19:12:39 -04:00
										 |  |  |           formula_installers.each do |fi| | 
					
						
							| 
									
										
										
										
											2025-07-17 17:55:50 +01:00
										 |  |  |             print_dry_run_dependencies(fi.formula, fi.compute_dependencies, &:name) | 
					
						
							| 
									
										
										
										
											2025-06-26 19:12:39 -04:00
										 |  |  |           end | 
					
						
							| 
									
										
										
										
											2025-07-17 17:55:50 +01:00
										 |  |  |           return | 
					
						
							| 
									
										
										
										
											2025-06-26 19:12:39 -04:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |         valid_formula_installers = fetch_formulae(formula_installers) | 
					
						
							| 
									
										
										
										
											2022-08-17 22:14:20 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-23 21:13:22 +01:00
										 |  |  |         valid_formula_installers.each do |fi| | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |           formula = fi.formula | 
					
						
							|  |  |  |           upgrade = formula.linked? && formula.outdated? && !formula.head? && !Homebrew::EnvConfig.no_install_upgrade? | 
					
						
							|  |  |  |           install_formula(fi, upgrade:) | 
					
						
							|  |  |  |           Cleanup.install_formula_clean!(formula) | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2021-09-01 22:27:34 -07:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { params(formula: Formula, dependencies: T::Array[[Dependency, Options]]).void } | 
					
						
							| 
									
										
										
										
											2023-12-14 02:52:30 +00:00
										 |  |  |       def print_dry_run_dependencies(formula, dependencies) | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         return if dependencies.empty? | 
					
						
							| 
									
										
										
										
											2022-08-17 22:14:20 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         ohai "Would install #{Utils.pluralize("dependenc", dependencies.count, plural: "ies", singular: "y", | 
					
						
							| 
									
										
										
										
											2023-03-20 07:23:17 -04:00
										 |  |  |                                             include_count: true)} for #{formula.name}:" | 
					
						
							| 
									
										
										
										
											2023-12-14 02:52:30 +00:00
										 |  |  |         formula_names = dependencies.map { |(dep, _options)| yield dep.to_formula } | 
					
						
							| 
									
										
										
										
											2023-04-17 10:59:47 -07:00
										 |  |  |         puts formula_names.join(" ") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-04-17 11:02:59 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-07 11:32:34 -05:00
										 |  |  |       # If asking the user is enabled, show dependency and size information. | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { params(formulae_installer: T::Array[FormulaInstaller], dependants: Homebrew::Upgrade::Dependents, args: Homebrew::CLI::Args).void } | 
					
						
							| 
									
										
										
										
											2025-06-18 16:05:19 -04:00
										 |  |  |       def ask_formulae(formulae_installer, dependants, args:) | 
					
						
							|  |  |  |         return if formulae_installer.empty? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         formulae = collect_dependencies(formulae_installer, dependants) | 
					
						
							| 
									
										
										
										
											2025-05-03 15:39:43 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-05 17:38:18 -05:00
										 |  |  |         ohai "Looking for bottles..." | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-08 11:32:21 -04:00
										 |  |  |         sizes = compute_total_sizes(formulae, debug: args.debug?) | 
					
						
							| 
									
										
										
										
											2025-03-05 17:38:18 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-08 11:32:21 -04:00
										 |  |  |         puts "#{::Utils.pluralize("Formula", formulae.count, plural: "e")} \
 | 
					
						
							|  |  |  | (#{formulae.count}): #{formulae.join(", ")}\n\n" | 
					
						
							| 
									
										
										
										
											2025-07-31 17:31:27 +01:00
										 |  |  |         puts "Download Size: #{disk_usage_readable(sizes.fetch(:download))}" | 
					
						
							|  |  |  |         puts "Install Size:  #{disk_usage_readable(sizes.fetch(:installed))}" | 
					
						
							|  |  |  |         if (net_install_size = sizes[:net]) && net_install_size != 0
 | 
					
						
							|  |  |  |           puts "Net Install Size: #{disk_usage_readable(net_install_size)}" | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2025-03-05 17:38:18 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         ask_input | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { params(casks: T::Array[Cask::Cask]).void } | 
					
						
							| 
									
										
										
										
											2025-05-07 12:07:29 -04:00
										 |  |  |       def ask_casks(casks) | 
					
						
							|  |  |  |         return if casks.empty? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         puts "#{::Utils.pluralize("Cask", casks.count, plural: "s")} \
 | 
					
						
							|  |  |  | (#{casks.count}): #{casks.join(", ")}\n\n" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ask_input | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { params(formula_installer: FormulaInstaller, upgrade: T::Boolean).void } | 
					
						
							|  |  |  |       def install_formula(formula_installer, upgrade:) | 
					
						
							|  |  |  |         formula = formula_installer.formula | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         formula_installer.check_installation_already_attempted | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if upgrade | 
					
						
							|  |  |  |           Upgrade.print_upgrade_message(formula, formula_installer.options) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           kegs = Upgrade.outdated_kegs(formula) | 
					
						
							|  |  |  |           linked_kegs = kegs.select(&:linked?) | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           formula.print_tap_action | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # first we unlink the currently active keg for this formula otherwise it is | 
					
						
							|  |  |  |         # possible for the existing build to interfere with the build we are about to | 
					
						
							|  |  |  |         # do! Seriously, it happens! | 
					
						
							|  |  |  |         kegs.each(&:unlink) if kegs.present? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         formula_installer.install | 
					
						
							|  |  |  |         formula_installer.finish | 
					
						
							|  |  |  |       rescue FormulaInstallationAlreadyAttemptedError | 
					
						
							|  |  |  |         # We already attempted to upgrade f as part of the dependency tree of | 
					
						
							|  |  |  |         # another formula. In that case, don't generate an error, just move on. | 
					
						
							|  |  |  |         nil | 
					
						
							|  |  |  |       ensure | 
					
						
							|  |  |  |         # restore previous installation state if build failed | 
					
						
							|  |  |  |         begin | 
					
						
							|  |  |  |           linked_kegs&.each(&:link) unless formula&.latest_version_installed? | 
					
						
							|  |  |  |         rescue | 
					
						
							|  |  |  |           nil | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-05 17:38:18 -05:00
										 |  |  |       private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { params(formula: Formula).returns(T::Array[Keg]) } | 
					
						
							|  |  |  |       def outdated_kegs(formula) | 
					
						
							|  |  |  |         [formula, *formula.old_installed_formulae].map(&:linked_keg) | 
					
						
							|  |  |  |                                                   .select(&:directory?) | 
					
						
							|  |  |  |                                                   .map { |k| Keg.new(k.resolved_path) } | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       sig { params(all_fatal: T::Boolean).void } | 
					
						
							| 
									
										
										
										
											2025-03-05 17:38:18 -05:00
										 |  |  |       def perform_preinstall_checks(all_fatal: false) | 
					
						
							|  |  |  |         check_prefix | 
					
						
							|  |  |  |         check_cpu | 
					
						
							|  |  |  |         attempt_directory_creation | 
					
						
							|  |  |  |         Diagnostic.checks(:supported_configuration_checks, fatal: all_fatal) | 
					
						
							|  |  |  |         Diagnostic.checks(:fatal_preinstall_checks) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { void } | 
					
						
							| 
									
										
										
										
											2025-03-05 17:38:18 -05:00
										 |  |  |       def attempt_directory_creation | 
					
						
							|  |  |  |         Keg.must_exist_directories.each do |dir| | 
					
						
							|  |  |  |           FileUtils.mkdir_p(dir) unless dir.exist? | 
					
						
							|  |  |  |         rescue | 
					
						
							|  |  |  |           nil | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { void } | 
					
						
							| 
									
										
										
										
											2025-03-05 17:38:18 -05:00
										 |  |  |       def check_cpu | 
					
						
							|  |  |  |         return unless Hardware::CPU.ppc? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         odie <<~EOS | 
					
						
							|  |  |  |           Sorry, Homebrew does not support your computer's CPU architecture! | 
					
						
							|  |  |  |           For PowerPC Mac (PPC32/PPC64BE) support, see: | 
					
						
							|  |  |  |             #{Formatter.url("https://github.com/mistydemeo/tigerbrew")} | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { void } | 
					
						
							| 
									
										
										
										
											2025-02-18 22:41:40 -05:00
										 |  |  |       def ask_input | 
					
						
							| 
									
										
										
										
											2025-03-12 00:31:13 +03:00
										 |  |  |         ohai "Do you want to proceed with the installation? [Y/y/yes/N/n/no]" | 
					
						
							| 
									
										
										
										
											2025-02-18 22:41:40 -05:00
										 |  |  |         accepted_inputs = %w[y yes] | 
					
						
							|  |  |  |         declined_inputs = %w[n no] | 
					
						
							|  |  |  |         loop do | 
					
						
							| 
									
										
										
										
											2025-03-05 17:38:18 -05:00
										 |  |  |           result = $stdin.gets | 
					
						
							|  |  |  |           return unless result | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           result = result.chomp.strip.downcase | 
					
						
							| 
									
										
										
										
											2025-02-18 22:41:40 -05:00
										 |  |  |           if accepted_inputs.include?(result) | 
					
						
							|  |  |  |             break | 
					
						
							|  |  |  |           elsif declined_inputs.include?(result) | 
					
						
							| 
									
										
										
										
											2025-03-05 17:38:18 -05:00
										 |  |  |             exit 1
 | 
					
						
							| 
									
										
										
										
											2025-02-18 22:41:40 -05:00
										 |  |  |           else | 
					
						
							|  |  |  |             puts "Invalid input. Please enter 'Y', 'y', or 'yes' to proceed, or 'N' to abort." | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # Compute the total sizes (download, installed, and net) for the given formulae. | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { params(sized_formulae: T::Array[Formula], debug: T::Boolean).returns(T::Hash[Symbol, Integer]) } | 
					
						
							| 
									
										
										
										
											2025-02-18 22:41:40 -05:00
										 |  |  |       def compute_total_sizes(sized_formulae, debug: false) | 
					
						
							|  |  |  |         total_download_size  = 0
 | 
					
						
							|  |  |  |         total_installed_size = 0
 | 
					
						
							|  |  |  |         total_net_size       = 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |         sized_formulae.each do |formula| | 
					
						
							| 
									
										
										
										
											2025-03-07 16:18:17 -05:00
										 |  |  |           bottle = formula.bottle | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |           next unless bottle | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-18 22:41:40 -05:00
										 |  |  |           # Fetch additional bottle metadata (if necessary). | 
					
						
							|  |  |  |           bottle.fetch_tab(quiet: !debug) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           total_download_size  += bottle.bottle_size.to_i if bottle.bottle_size | 
					
						
							|  |  |  |           total_installed_size += bottle.installed_size.to_i if bottle.installed_size | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Sum disk usage for all installed kegs of the formula. | 
					
						
							|  |  |  |           next if formula.installed_kegs.none? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           kegs_dep_size = formula.installed_kegs.sum { |keg| keg.disk_usage.to_i } | 
					
						
							|  |  |  |           total_net_size += bottle.installed_size.to_i - kegs_dep_size if bottle.installed_size | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         { download:  total_download_size, | 
					
						
							|  |  |  |           installed: total_installed_size, | 
					
						
							|  |  |  |           net:       total_net_size } | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2025-06-18 16:05:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |       sig { | 
					
						
							|  |  |  |         params(formulae_installer: T::Array[FormulaInstaller], | 
					
						
							|  |  |  |                dependants:         Homebrew::Upgrade::Dependents).returns(T::Array[Formula]) | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2025-06-18 16:05:19 -04:00
										 |  |  |       def collect_dependencies(formulae_installer, dependants) | 
					
						
							|  |  |  |         formulae_dependencies = formulae_installer.flat_map do |f| | 
					
						
							| 
									
										
										
										
											2025-07-14 14:48:08 +01:00
										 |  |  |           [f.formula, f.compute_dependencies.flatten.grep(Dependency).flat_map(&:to_formula)] | 
					
						
							| 
									
										
										
										
											2025-06-18 16:05:19 -04:00
										 |  |  |         end.flatten.uniq | 
					
						
							| 
									
										
										
										
											2025-07-24 09:42:11 +01:00
										 |  |  |         formulae_dependencies.concat(dependants.upgradeable) if dependants.upgradeable | 
					
						
							| 
									
										
										
										
											2025-06-29 23:29:18 -04:00
										 |  |  |         formulae_dependencies.uniq | 
					
						
							| 
									
										
										
										
											2025-06-18 16:05:19 -04:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2022-08-17 22:14:20 +09:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-06-05 23:19:18 -04:00
										 |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							| 
									
										
										
										
											2018-09-28 14:01:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | require "extend/os/install" |