| 
									
										
										
										
											2023-03-06 09:49:53 -08:00
										 |  |  | # typed: true | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-26 11:03:08 -07:00
										 |  |  | # `brew uses foo bar` returns formulae that use both foo and bar | 
					
						
							|  |  |  | # If you want the union, run the command twice and concatenate the results. | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | # The intersection is harder to achieve with shell tools. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 00:07:27 -04:00
										 |  |  | require "formula" | 
					
						
							|  |  |  | require "cli/parser" | 
					
						
							| 
									
										
										
										
											2020-07-30 12:59:01 -04:00
										 |  |  | require "cask/caskroom" | 
					
						
							| 
									
										
										
										
											2020-07-31 11:35:45 -04:00
										 |  |  | require "dependencies_helpers" | 
					
						
							| 
									
										
										
										
											2023-03-08 09:16:53 -08:00
										 |  |  | require "ostruct" | 
					
						
							| 
									
										
										
										
											2019-09-04 00:07:27 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-18 22:41:47 -05:00
										 |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2020-07-23 02:00:44 +02:00
										 |  |  |   extend DependenciesHelpers | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   sig { returns(CLI::Parser) } | 
					
						
							| 
									
										
										
										
											2023-03-06 09:49:53 -08:00
										 |  |  |   def self.uses_args | 
					
						
							| 
									
										
										
										
											2018-11-11 19:03:08 +05:30
										 |  |  |     Homebrew::CLI::Parser.new do | 
					
						
							| 
									
										
										
										
											2021-01-15 15:04:02 -05:00
										 |  |  |       description <<~EOS | 
					
						
							| 
									
										
										
										
											2021-01-24 12:38:32 -05:00
										 |  |  |         Show formulae and casks that specify <formula> as a dependency; that is, show dependents | 
					
						
							| 
									
										
										
										
											2021-01-24 01:59:02 -05:00
										 |  |  |         of <formula>. When given multiple formula arguments, show the intersection | 
					
						
							| 
									
										
										
										
											2020-12-05 18:19:56 -05:00
										 |  |  |         of formulae that use <formula>. By default, `uses` shows all formulae and casks that | 
					
						
							| 
									
										
										
										
											2020-07-20 08:08:13 -07:00
										 |  |  |         specify <formula> as a required or recommended dependency for their stable builds. | 
					
						
							| 
									
										
										
										
											2023-08-28 22:14:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-09 12:09:38 -04:00
										 |  |  |         *Note:* `--missing` and `--skip-recommended` have precedence over `--include-*`. | 
					
						
							| 
									
										
										
										
											2018-11-11 19:03:08 +05:30
										 |  |  |       EOS | 
					
						
							|  |  |  |       switch "--recursive", | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |              description: "Resolve more than one level of dependencies." | 
					
						
							| 
									
										
										
										
											2018-11-11 19:03:08 +05:30
										 |  |  |       switch "--installed", | 
					
						
							| 
									
										
										
										
											2020-12-05 18:19:56 -05:00
										 |  |  |              description: "Only list formulae and casks that are currently installed." | 
					
						
							| 
									
										
										
										
											2023-05-17 14:53:19 -05:00
										 |  |  |       switch "--missing", | 
					
						
							| 
									
										
										
										
											2023-05-17 13:59:38 -05:00
										 |  |  |              description: "Only list formulae and casks that are not currently installed." | 
					
						
							| 
									
										
										
										
											2022-09-05 13:57:22 +01:00
										 |  |  |       switch "--eval-all", | 
					
						
							|  |  |  |              description: "Evaluate all available formulae and casks, whether installed or not, to show " \ | 
					
						
							|  |  |  |                           "their dependents." | 
					
						
							| 
									
										
										
										
											2018-11-11 19:03:08 +05:30
										 |  |  |       switch "--include-build", | 
					
						
							| 
									
										
										
										
											2023-08-28 22:14:26 -07:00
										 |  |  |              description: "Include formulae that specify <formula> as a `:build` dependency." | 
					
						
							| 
									
										
										
										
											2018-11-11 19:03:08 +05:30
										 |  |  |       switch "--include-test", | 
					
						
							| 
									
										
										
										
											2023-08-28 22:14:26 -07:00
										 |  |  |              description: "Include formulae that specify <formula> as a `:test` dependency." | 
					
						
							| 
									
										
										
										
											2018-11-11 19:03:08 +05:30
										 |  |  |       switch "--include-optional", | 
					
						
							| 
									
										
										
										
											2023-08-28 22:14:26 -07:00
										 |  |  |              description: "Include formulae that specify <formula> as an `:optional` dependency." | 
					
						
							| 
									
										
										
										
											2018-11-11 19:03:08 +05:30
										 |  |  |       switch "--skip-recommended", | 
					
						
							| 
									
										
										
										
											2023-08-28 22:14:26 -07:00
										 |  |  |              description: "Skip all formulae that specify <formula> as a `:recommended` dependency." | 
					
						
							| 
									
										
										
										
											2020-12-05 18:19:56 -05:00
										 |  |  |       switch "--formula", "--formulae", | 
					
						
							|  |  |  |              description: "Include only formulae." | 
					
						
							|  |  |  |       switch "--cask", "--casks", | 
					
						
							|  |  |  |              description: "Include only casks." | 
					
						
							| 
									
										
										
										
											2020-11-12 10:40:41 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-05 18:19:56 -05:00
										 |  |  |       conflicts "--formula", "--cask" | 
					
						
							| 
									
										
										
										
											2022-03-08 19:24:55 +00:00
										 |  |  |       conflicts "--installed", "--all" | 
					
						
							| 
									
										
										
										
											2023-05-17 14:53:19 -05:00
										 |  |  |       conflicts "--missing", "--installed" | 
					
						
							| 
									
										
										
										
											2021-01-10 14:26:40 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |       named_args :formula, min: 1
 | 
					
						
							| 
									
										
										
										
											2018-11-11 19:03:08 +05:30
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-06 09:49:53 -08:00
										 |  |  |   def self.uses | 
					
						
							| 
									
										
										
										
											2020-07-30 18:40:10 +02:00
										 |  |  |     args = uses_args.parse | 
					
						
							| 
									
										
										
										
											2018-11-11 19:03:08 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 20:34:50 +00:00
										 |  |  |     Formulary.enable_factory_cache! | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-17 15:06:24 +01:00
										 |  |  |     used_formulae_missing = false | 
					
						
							|  |  |  |     used_formulae = begin | 
					
						
							| 
									
										
										
										
											2020-08-19 10:34:48 -04:00
										 |  |  |       args.named.to_formulae | 
					
						
							| 
									
										
										
										
											2017-04-17 15:06:24 +01:00
										 |  |  |     rescue FormulaUnavailableError => e | 
					
						
							|  |  |  |       opoo e | 
					
						
							|  |  |  |       used_formulae_missing = true | 
					
						
							|  |  |  |       # If the formula doesn't exist: fake the needed formula object name. | 
					
						
							| 
									
										
										
										
											2023-02-28 12:24:22 -08:00
										 |  |  |       # This is a legacy use of OpenStruct that should be refactored. | 
					
						
							|  |  |  |       # rubocop:disable Style/OpenStructUse | 
					
						
							| 
									
										
										
										
											2020-03-04 17:28:15 +00:00
										 |  |  |       args.named.map { |name| OpenStruct.new name: name, full_name: name } | 
					
						
							| 
									
										
										
										
											2023-02-28 12:24:22 -08:00
										 |  |  |       # rubocop:enable Style/OpenStructUse | 
					
						
							| 
									
										
										
										
											2017-04-17 15:06:24 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-27 12:49:46 +00:00
										 |  |  |     use_runtime_dependents = args.installed? && | 
					
						
							| 
									
										
										
										
											2020-07-31 10:46:02 -07:00
										 |  |  |                              !used_formulae_missing && | 
					
						
							| 
									
										
										
										
											2019-11-27 12:49:46 +00:00
										 |  |  |                              !args.include_build? && | 
					
						
							|  |  |  |                              !args.include_test? && | 
					
						
							|  |  |  |                              !args.include_optional? && | 
					
						
							|  |  |  |                              !args.skip_recommended? | 
					
						
							| 
									
										
										
										
											2018-03-24 16:55:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-31 10:46:02 -07:00
										 |  |  |     uses = intersection_of_dependents(use_runtime_dependents, used_formulae, args: args) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return if uses.empty? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     puts Formatter.columns(uses.map(&:full_name).sort) | 
					
						
							|  |  |  |     odie "Missing formulae should not have dependents!" if used_formulae_missing | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-06 09:49:53 -08:00
										 |  |  |   def self.intersection_of_dependents(use_runtime_dependents, used_formulae, args:) | 
					
						
							| 
									
										
										
										
											2020-08-01 11:55:40 -04:00
										 |  |  |     recursive = args.recursive? | 
					
						
							| 
									
										
										
										
											2020-12-07 11:12:28 -05:00
										 |  |  |     show_formulae_and_casks = !args.formula? && !args.cask? | 
					
						
							| 
									
										
										
										
											2020-08-01 11:55:40 -04:00
										 |  |  |     includes, ignores = args_includes_ignores(args) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-05 18:19:56 -05:00
										 |  |  |     deps = [] | 
					
						
							| 
									
										
										
										
											2020-07-31 10:46:02 -07:00
										 |  |  |     if use_runtime_dependents | 
					
						
							| 
									
										
										
										
											2020-12-07 11:12:28 -05:00
										 |  |  |       if show_formulae_and_casks || args.formula? | 
					
						
							| 
									
										
										
										
											2020-12-05 18:19:56 -05:00
										 |  |  |         deps += used_formulae.map(&:runtime_installed_formula_dependents) | 
					
						
							|  |  |  |                              .reduce(&:&) | 
					
						
							|  |  |  |                              .select(&:any_version_installed?) | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2020-12-07 11:12:28 -05:00
										 |  |  |       if show_formulae_and_casks || args.cask? | 
					
						
							| 
									
										
										
										
											2020-12-05 18:19:56 -05:00
										 |  |  |         deps += select_used_dependents( | 
					
						
							| 
									
										
										
										
											2021-03-22 22:26:06 +00:00
										 |  |  |           dependents(Cask::Caskroom.casks), | 
					
						
							| 
									
										
										
										
											2020-10-01 00:57:02 +02:00
										 |  |  |           used_formulae, recursive, includes, ignores | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-12-05 18:19:56 -05:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       deps | 
					
						
							| 
									
										
										
										
											2019-11-05 20:34:50 +00:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2022-09-05 13:57:22 +01:00
										 |  |  |       all = args.eval_all? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if !args.installed? && !(all || Homebrew::EnvConfig.eval_all?) | 
					
						
							| 
									
										
										
										
											2023-07-06 16:47:09 +01:00
										 |  |  |         raise UsageError, "`brew uses` needs `--installed` or `--eval-all` passed or `HOMEBREW_EVAL_ALL` set!" | 
					
						
							| 
									
										
										
										
											2022-09-05 13:57:22 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-07-06 16:47:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-07 11:12:28 -05:00
										 |  |  |       if show_formulae_and_casks || args.formula? | 
					
						
							| 
									
										
										
										
											2023-09-02 19:35:22 +09:00
										 |  |  |         deps += args.installed? ? Formula.installed : Formula.all(eval_all: args.eval_all?) | 
					
						
							| 
									
										
										
										
											2020-12-06 22:21:02 -05:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2020-12-07 11:12:28 -05:00
										 |  |  |       if show_formulae_and_casks || args.cask? | 
					
						
							| 
									
										
										
										
											2023-12-21 21:55:16 -08:00
										 |  |  |         deps += args.installed? ? Cask::Caskroom.casks : Cask::Cask.all(eval_all: args.eval_all?) | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2020-07-30 12:59:01 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 13:50:53 -07:00
										 |  |  |       if args.missing? | 
					
						
							|  |  |  |         deps.reject! do |dep| | 
					
						
							|  |  |  |           case dep | 
					
						
							|  |  |  |           when Formula | 
					
						
							|  |  |  |             dep.any_version_installed? | 
					
						
							|  |  |  |           when Cask::Cask | 
					
						
							|  |  |  |             dep.installed? | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         ignores.delete(:satisfied?) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-05 18:19:56 -05:00
										 |  |  |       select_used_dependents(dependents(deps), used_formulae, recursive, includes, ignores) | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2020-07-30 12:59:01 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-06 09:49:53 -08:00
										 |  |  |   def self.select_used_dependents(dependents, used_formulae, recursive, includes, ignores) | 
					
						
							| 
									
										
										
										
											2020-07-30 12:59:01 -04:00
										 |  |  |     dependents.select do |d| | 
					
						
							|  |  |  |       deps = if recursive | 
					
						
							|  |  |  |         recursive_includes(Dependency, d, includes, ignores) | 
					
						
							|  |  |  |       else | 
					
						
							| 
									
										
										
										
											2023-08-24 21:18:24 -07:00
										 |  |  |         select_includes(d.deps, ignores, includes) | 
					
						
							| 
									
										
										
										
											2020-07-30 12:59:01 -04:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       used_formulae.all? do |ff| | 
					
						
							|  |  |  |         deps.any? do |dep| | 
					
						
							|  |  |  |           match = begin | 
					
						
							|  |  |  |             dep.to_formula.full_name == ff.full_name if dep.name.include?("/") | 
					
						
							|  |  |  |           rescue | 
					
						
							|  |  |  |             nil | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |           next match unless match.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           dep.name == ff.name | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       rescue FormulaUnavailableError | 
					
						
							|  |  |  |         # Silently ignore this case as we don't care about things used in | 
					
						
							|  |  |  |         # taps that aren't currently tapped. | 
					
						
							|  |  |  |         next | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | end |