| 
									
										
										
										
											2024-06-30 17:49:27 +01:00
										 |  |  | # typed: strict | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  | require "abstract_command" | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | require "formula" | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | require "api" | 
					
						
							| 
									
										
										
										
											2023-03-02 23:28:56 -05:00
										 |  |  | require "os/mac/xcode" | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |   module DevCmd | 
					
						
							|  |  |  |     class Unbottled < AbstractCommand | 
					
						
							|  |  |  |       cmd_args do | 
					
						
							|  |  |  |         description <<~EOS | 
					
						
							|  |  |  |           Show the unbottled dependents of formulae. | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |         flag   "--tag=", | 
					
						
							|  |  |  |                description: "Use the specified bottle tag (e.g. `big_sur`) instead of the current OS." | 
					
						
							|  |  |  |         switch "--dependents", | 
					
						
							|  |  |  |                description: "Skip getting analytics data and sort by number of dependents instead." | 
					
						
							|  |  |  |         switch "--total", | 
					
						
							|  |  |  |                description: "Print the number of unbottled and total formulae." | 
					
						
							|  |  |  |         switch "--lost", | 
					
						
							|  |  |  |                description: "Print the `homebrew/core` commits where bottles were lost in the last week." | 
					
						
							|  |  |  |         switch "--eval-all", | 
					
						
							|  |  |  |                description: "Evaluate all available formulae and casks, whether installed or not, to check them. " \ | 
					
						
							|  |  |  |                             "Implied if `HOMEBREW_EVAL_ALL` is set." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         conflicts "--dependents", "--total", "--lost" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         named_args :formula | 
					
						
							| 
									
										
										
										
											2023-10-15 15:14:48 -07:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |       sig { override.void } | 
					
						
							|  |  |  |       def run | 
					
						
							|  |  |  |         Formulary.enable_factory_cache! | 
					
						
							| 
									
										
										
										
											2022-11-15 05:22:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-01 19:13:38 +01:00
										 |  |  |         @bottle_tag = T.let( | 
					
						
							|  |  |  |           if (tag = args.tag) | 
					
						
							|  |  |  |             Utils::Bottles::Tag.from_symbol(tag.to_sym) | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             Utils::Bottles.tag | 
					
						
							|  |  |  |           end, | 
					
						
							|  |  |  |           T.nilable(Utils::Bottles::Tag), | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-07-02 15:24:01 +01:00
										 |  |  |         return unless @bottle_tag | 
					
						
							| 
									
										
										
										
											2023-07-06 16:47:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         if args.lost? | 
					
						
							|  |  |  |           if args.named.present? | 
					
						
							|  |  |  |             raise UsageError, "`brew unbottled --lost` cannot be used with formula arguments!" | 
					
						
							|  |  |  |           elsif !CoreTap.instance.installed? | 
					
						
							|  |  |  |             raise UsageError, "`brew unbottled --lost` requires `homebrew/core` to be tapped locally!" | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             output_lost_bottles | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2022-03-08 19:24:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-02 15:24:01 +01:00
										 |  |  |         os = @bottle_tag.system | 
					
						
							|  |  |  |         arch = if Hardware::CPU::INTEL_ARCHS.include?(@bottle_tag.arch) | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           :intel | 
					
						
							| 
									
										
										
										
											2024-07-02 15:24:01 +01:00
										 |  |  |         elsif Hardware::CPU::ARM_ARCHS.include?(@bottle_tag.arch) | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           :arm | 
					
						
							|  |  |  |         else | 
					
						
							| 
									
										
										
										
											2024-07-02 15:24:01 +01:00
										 |  |  |           raise "Unknown arch #{@bottle_tag.arch}." | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         Homebrew::SimulateSystem.with(os:, arch:) do | 
					
						
							|  |  |  |           all = args.eval_all? | 
					
						
							|  |  |  |           if args.total? | 
					
						
							|  |  |  |             if !all && !Homebrew::EnvConfig.eval_all? | 
					
						
							|  |  |  |               raise UsageError, "`brew unbottled --total` needs `--eval-all` passed or `HOMEBREW_EVAL_ALL` set!" | 
					
						
							|  |  |  |             end | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |             all = true | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2020-12-28 09:49:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           if args.named.blank? | 
					
						
							|  |  |  |             ohai "Getting formulae..." | 
					
						
							|  |  |  |           elsif all | 
					
						
							|  |  |  |             raise UsageError, "Cannot specify formulae when using `--eval-all`/`--total`." | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           formulae, all_formulae, formula_installs = formulae_all_installs_from_args(all) | 
					
						
							|  |  |  |           deps_hash, uses_hash = deps_uses_from_formulae(all_formulae) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if args.dependents? | 
					
						
							|  |  |  |             formula_dependents = {} | 
					
						
							|  |  |  |             formulae = formulae.sort_by do |f| | 
					
						
							|  |  |  |               dependents = uses_hash[f.name]&.length || 0
 | 
					
						
							|  |  |  |               formula_dependents[f.name] ||= dependents | 
					
						
							|  |  |  |             end.reverse | 
					
						
							|  |  |  |           elsif all | 
					
						
							|  |  |  |             output_total(formulae) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2023-07-06 16:47:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           noun, hash = if args.named.present? | 
					
						
							|  |  |  |             [nil, {}] | 
					
						
							|  |  |  |           elsif args.dependents? | 
					
						
							|  |  |  |             ["dependents", formula_dependents] | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             ["installs", formula_installs] | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-02 15:24:01 +01:00
										 |  |  |           return if hash.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           output_unbottled(formulae, deps_hash, noun, hash, args.named.present?) | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |       private | 
					
						
							| 
									
										
										
										
											2020-11-26 16:54:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-01 19:13:38 +01:00
										 |  |  |       sig { | 
					
						
							|  |  |  |         params(all: T::Boolean).returns([T::Array[Formula], T::Array[Formula], T.nilable(T::Hash[Symbol, Integer])]) | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |       def formulae_all_installs_from_args(all) | 
					
						
							|  |  |  |         if args.named.present? | 
					
						
							|  |  |  |           formulae = all_formulae = args.named.to_formulae | 
					
						
							|  |  |  |         elsif args.dependents? | 
					
						
							|  |  |  |           if !args.eval_all? && !Homebrew::EnvConfig.eval_all? | 
					
						
							|  |  |  |             raise UsageError, | 
					
						
							|  |  |  |                   "`brew unbottled --dependents` needs `--eval-all` passed or `HOMEBREW_EVAL_ALL` set!" | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2020-11-26 16:54:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           formulae = all_formulae = Formula.all(eval_all: args.eval_all?) | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-30 17:49:27 +01:00
										 |  |  |           @sort = T.let(" (sorted by number of dependents)", T.nilable(String)) | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         elsif all | 
					
						
							|  |  |  |           formulae = all_formulae = Formula.all(eval_all: args.eval_all?) | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           formula_installs = {} | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           ohai "Getting analytics data..." | 
					
						
							|  |  |  |           analytics = Homebrew::API::Analytics.fetch "install", 90
 | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           if analytics.blank? | 
					
						
							|  |  |  |             raise UsageError, | 
					
						
							|  |  |  |                   "default sort by analytics data requires " \ | 
					
						
							|  |  |  |                   "`HOMEBREW_NO_GITHUB_API` and `HOMEBREW_NO_ANALYTICS` to be unset" | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2023-10-16 22:20:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           formulae = analytics["items"].filter_map do |i| | 
					
						
							|  |  |  |             f = i["formula"].split.first | 
					
						
							|  |  |  |             next if f.include?("/") | 
					
						
							|  |  |  |             next if formula_installs[f].present? | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |             formula_installs[f] = i["count"] | 
					
						
							|  |  |  |             begin | 
					
						
							|  |  |  |               Formula[f] | 
					
						
							|  |  |  |             rescue FormulaUnavailableError | 
					
						
							|  |  |  |               nil | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2024-06-30 17:49:27 +01:00
										 |  |  |           @sort = T.let(" (sorted by installs in the last 90 days; top 10,000 only)", T.nilable(String)) | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           all_formulae = Formula.all(eval_all: args.eval_all?) | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         # Remove deprecated formulae as we do not care if they are unbottled | 
					
						
							|  |  |  |         formulae = Array(formulae).reject(&:deprecated?) if formulae.present? | 
					
						
							|  |  |  |         all_formulae = Array(all_formulae).reject(&:deprecated?) if all_formulae.present? | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-01 19:13:38 +01:00
										 |  |  |         [T.let(formulae, T::Array[Formula]), T.let(all_formulae, T::Array[Formula]), | 
					
						
							| 
									
										
										
										
											2024-07-02 15:24:01 +01:00
										 |  |  |          T.let(formula_installs, T.nilable(T::Hash[Symbol, Integer]))] | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-04 10:35:00 +01:00
										 |  |  |       sig { | 
					
						
							|  |  |  |         params(all_formulae: T::Array[Formula]).returns([T::Hash[String, T.untyped], T::Hash[String, T.untyped]]) | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |       def deps_uses_from_formulae(all_formulae) | 
					
						
							|  |  |  |         ohai "Populating dependency tree..." | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         deps_hash = {} | 
					
						
							|  |  |  |         uses_hash = {} | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         all_formulae.each do |f| | 
					
						
							|  |  |  |           deps = Dependency.expand(f, cache_key: "unbottled") do |_, dep| | 
					
						
							|  |  |  |             Dependency.prune if dep.optional? | 
					
						
							|  |  |  |           end.map(&:to_formula) | 
					
						
							|  |  |  |           deps_hash[f.name] = deps | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           deps.each do |dep| | 
					
						
							|  |  |  |             uses_hash[dep.name] ||= [] | 
					
						
							|  |  |  |             uses_hash[dep.name] << f | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         [deps_hash, uses_hash] | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-04 10:35:00 +01:00
										 |  |  |       sig { params(formulae: T::Array[Formula]).void } | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |       def output_total(formulae) | 
					
						
							| 
									
										
										
										
											2024-07-02 15:24:01 +01:00
										 |  |  |         return unless @bottle_tag | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         ohai "Unbottled :#{@bottle_tag} formulae" | 
					
						
							|  |  |  |         unbottled_formulae = 0
 | 
					
						
							| 
									
										
										
										
											2020-12-28 09:49:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         formulae.each do |f| | 
					
						
							|  |  |  |           next if f.bottle_specification.tag?(@bottle_tag) | 
					
						
							| 
									
										
										
										
											2021-02-23 04:41:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           unbottled_formulae += 1
 | 
					
						
							| 
									
										
										
										
											2021-02-23 04:41:29 +00:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2020-12-28 09:49:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         puts "#{unbottled_formulae}/#{formulae.length} remaining." | 
					
						
							| 
									
										
										
										
											2021-05-31 15:24:20 +01:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-01 19:13:38 +01:00
										 |  |  |       sig { | 
					
						
							|  |  |  |         params(formulae: T::Array[Formula], deps_hash: T::Hash[T.any(Symbol, String), T.untyped], | 
					
						
							|  |  |  |                noun: T.nilable(String), hash: T::Hash[T.any(Symbol, String), T.untyped], | 
					
						
							| 
									
										
										
										
											2024-07-04 10:35:00 +01:00
										 |  |  |                any_named_args: T::Boolean).void | 
					
						
							| 
									
										
										
										
											2024-07-01 19:13:38 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |       def output_unbottled(formulae, deps_hash, noun, hash, any_named_args) | 
					
						
							| 
									
										
										
										
											2024-07-02 15:24:01 +01:00
										 |  |  |         return unless @bottle_tag | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         ohai ":#{@bottle_tag} bottle status#{@sort}" | 
					
						
							|  |  |  |         any_found = T.let(false, T::Boolean) | 
					
						
							| 
									
										
										
										
											2020-12-23 10:57:10 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         formulae.each do |f| | 
					
						
							|  |  |  |           name = f.name.downcase | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           if f.disabled? | 
					
						
							|  |  |  |             puts "#{Tty.bold}#{Tty.green}#{name}#{Tty.reset}: formula disabled" if any_named_args | 
					
						
							|  |  |  |             next | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           requirements = f.recursive_requirements | 
					
						
							| 
									
										
										
										
											2024-07-02 15:24:01 +01:00
										 |  |  |           if @bottle_tag.linux? | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |             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 | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           elsif requirements.any?(LinuxRequirement) | 
					
						
							|  |  |  |             puts "#{Tty.bold}#{Tty.red}#{name}#{Tty.reset}: requires Linux" if any_named_args | 
					
						
							|  |  |  |             next | 
					
						
							|  |  |  |           else | 
					
						
							| 
									
										
										
										
											2024-07-02 15:24:01 +01:00
										 |  |  |             macos_version = @bottle_tag.to_macos_version | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |             macos_satisfied = requirements.all? do |r| | 
					
						
							|  |  |  |               case r | 
					
						
							|  |  |  |               when MacOSRequirement | 
					
						
							|  |  |  |                 next true unless r.version_specified? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 macos_version.compare(r.comparator, r.version) | 
					
						
							|  |  |  |               when XcodeRequirement | 
					
						
							|  |  |  |                 next true unless r.version | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 Version.new(MacOS::Xcode.latest_version(macos: macos_version)) >= r.version | 
					
						
							|  |  |  |               when ArchRequirement | 
					
						
							| 
									
										
										
										
											2024-07-02 15:24:01 +01:00
										 |  |  |                 r.arch == @bottle_tag.arch | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |               else | 
					
						
							|  |  |  |                 true | 
					
						
							|  |  |  |               end | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |             unless macos_satisfied | 
					
						
							|  |  |  |               puts "#{Tty.bold}#{Tty.red}#{name}#{Tty.reset}: doesn't support this macOS" if any_named_args | 
					
						
							|  |  |  |               next | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2023-10-15 15:14:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           if f.bottle_specification.tag?(@bottle_tag, no_older_versions: true) | 
					
						
							|  |  |  |             puts "#{Tty.bold}#{Tty.green}#{name}#{Tty.reset}: already bottled" if any_named_args | 
					
						
							|  |  |  |             next | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2023-10-16 20:51:38 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           deps = Array(deps_hash[f.name]).reject do |dep| | 
					
						
							|  |  |  |             dep.bottle_specification.tag?(@bottle_tag, no_older_versions: true) | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2023-10-17 22:41:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           if deps.blank? | 
					
						
							|  |  |  |             count = " (#{hash[f.name]} #{noun})" if noun | 
					
						
							|  |  |  |             puts "#{Tty.bold}#{Tty.green}#{name}#{Tty.reset}#{count}: ready to bottle" | 
					
						
							|  |  |  |             next | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2023-10-15 15:14:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |           any_found ||= true | 
					
						
							|  |  |  |           count = " (#{hash[f.name]} #{noun})" if noun | 
					
						
							|  |  |  |           puts "#{Tty.bold}#{Tty.yellow}#{name}#{Tty.reset}#{count}: unbottled deps: #{deps.join(" ")}" | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         return if any_found | 
					
						
							|  |  |  |         return if any_named_args | 
					
						
							| 
									
										
										
										
											2023-10-15 15:14:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         puts "No unbottled dependencies found!" | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-10-15 15:14:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-04 10:35:00 +01:00
										 |  |  |       sig { void } | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |       def output_lost_bottles | 
					
						
							|  |  |  |         ohai ":#{@bottle_tag} lost bottles" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         bottle_tag_regex_fragment = " +sha256.* #{@bottle_tag}: " | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # $ git log --patch --no-ext-diff -G'^ +sha256.* sonoma:' --since=@{'1 week ago'} | 
					
						
							|  |  |  |         git_log = %w[git log --patch --no-ext-diff] | 
					
						
							|  |  |  |         git_log << "-G^#{bottle_tag_regex_fragment}" | 
					
						
							|  |  |  |         git_log << "--since=@{'1 week ago'}" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         bottle_tag_sha_regex = /^[+-]#{bottle_tag_regex_fragment}/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         processed_formulae = Set.new | 
					
						
							|  |  |  |         commit = T.let(nil, T.nilable(String)) | 
					
						
							|  |  |  |         formula = T.let(nil, T.nilable(String)) | 
					
						
							|  |  |  |         lost_bottles = 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         CoreTap.instance.path.cd do | 
					
						
							|  |  |  |           Utils.safe_popen_read(*git_log) do |io| | 
					
						
							|  |  |  |             io.each_line do |line| | 
					
						
							|  |  |  |               case line | 
					
						
							|  |  |  |               when /^commit [0-9a-f]{40}$/ | 
					
						
							|  |  |  |                 # Example match: `commit 7289b409b96a752540befef1a56b8a818baf1db7` | 
					
						
							|  |  |  |                 if commit && formula && lost_bottles.positive? && processed_formulae.exclude?(formula) | 
					
						
							|  |  |  |                   puts "#{commit}: bottle lost for #{formula}" | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |                 processed_formulae << formula | 
					
						
							|  |  |  |                 commit = line.split.last | 
					
						
							|  |  |  |                 formula = nil | 
					
						
							|  |  |  |               when %r{^diff --git a/Formula/} | 
					
						
							|  |  |  |                 # Example match: `diff --git a/Formula/a/aws-cdk.rb b/Formula/a/aws-cdk.rb` | 
					
						
							|  |  |  |                 formula = line.split("/").last.chomp(".rb\n") | 
					
						
							|  |  |  |                 formula = CoreTap.instance.formula_renames.fetch(formula, formula) | 
					
						
							|  |  |  |                 lost_bottles = 0
 | 
					
						
							|  |  |  |               when bottle_tag_sha_regex | 
					
						
							|  |  |  |                 # Example match: `-    sha256 cellar: :any_skip_relocation, sonoma: "f0a4..."` | 
					
						
							|  |  |  |                 next if processed_formulae.include?(formula) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 case line.chr | 
					
						
							|  |  |  |                 when "+" then lost_bottles -= 1
 | 
					
						
							|  |  |  |                 when "-" then lost_bottles += 1
 | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |               when /^[+] +sha256.* all: / | 
					
						
							|  |  |  |                 # Example match: `+    sha256 cellar: :any_skip_relocation, all: "9e35..."` | 
					
						
							|  |  |  |                 lost_bottles -= 1
 | 
					
						
							|  |  |  |               end | 
					
						
							| 
									
										
										
										
											2023-10-15 15:14:48 -07:00
										 |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         return if !commit || !formula || !lost_bottles.positive? || processed_formulae.include?(formula) | 
					
						
							| 
									
										
										
										
											2023-10-15 15:14:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:59:48 -07:00
										 |  |  |         puts "#{commit}: bottle lost for #{formula}" | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2023-10-15 15:14:48 -07:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2020-11-26 08:17:20 +00:00
										 |  |  | end |