| 
									
										
										
										
											2023-03-13 18:31:26 -07:00
										 |  |  | # typed: true | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-24 16:14:44 +01:00
										 |  |  | require "formula" | 
					
						
							| 
									
										
										
										
											2016-01-14 13:33:56 +08:00
										 |  |  | require "formula_versions" | 
					
						
							| 
									
										
										
										
											2017-12-03 14:02:55 +01:00
										 |  |  | require "utils/curl" | 
					
						
							| 
									
										
										
										
											2020-09-10 22:00:18 +02:00
										 |  |  | require "utils/github/actions" | 
					
						
							| 
									
										
										
										
											2020-08-26 09:42:39 +02:00
										 |  |  | require "utils/shared_audits" | 
					
						
							| 
									
										
										
										
											2020-08-04 10:07:57 -07:00
										 |  |  | require "utils/spdx" | 
					
						
							| 
									
										
										
										
											2015-05-24 16:14:44 +01:00
										 |  |  | require "extend/ENV" | 
					
						
							|  |  |  | require "formula_cellar_checks" | 
					
						
							| 
									
										
										
										
											2015-05-31 18:40:28 +08:00
										 |  |  | require "cmd/search" | 
					
						
							| 
									
										
										
										
											2018-06-05 23:19:18 -04:00
										 |  |  | require "style" | 
					
						
							| 
									
										
										
										
											2015-07-09 15:28:27 +01:00
										 |  |  | require "date" | 
					
						
							| 
									
										
										
										
											2017-03-18 17:02:08 +02:00
										 |  |  | require "missing_formula" | 
					
						
							| 
									
										
										
										
											2017-02-02 21:25:29 +00:00
										 |  |  | require "digest" | 
					
						
							| 
									
										
										
										
											2019-04-17 18:25:08 +09:00
										 |  |  | require "cli/parser" | 
					
						
							| 
									
										
										
										
											2020-06-16 01:00:36 +08:00
										 |  |  | require "json" | 
					
						
							| 
									
										
										
										
											2020-11-18 10:25:12 +01:00
										 |  |  | require "formula_auditor" | 
					
						
							| 
									
										
										
										
											2020-11-18 10:05:23 +01:00
										 |  |  | require "tap_auditor" | 
					
						
							| 
									
										
										
										
											2012-03-17 19:49:49 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-18 22:41:47 -05:00
										 |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   sig { returns(CLI::Parser) } | 
					
						
							| 
									
										
										
										
											2023-03-13 18:31:26 -07:00
										 |  |  |   def self.audit_args | 
					
						
							| 
									
										
										
										
											2018-07-30 18:25:38 +05:30
										 |  |  |     Homebrew::CLI::Parser.new do | 
					
						
							| 
									
										
										
										
											2021-01-15 15:04:02 -05:00
										 |  |  |       description <<~EOS | 
					
						
							| 
									
										
										
										
											2019-01-30 21:33:03 +00:00
										 |  |  |         Check <formula> for Homebrew coding style violations. This should be run before | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  |         submitting a new formula or cask. If no <formula>|<cask> are provided, check all | 
					
						
							|  |  |  |         locally available formulae and casks and skip style checks. Will exit with a | 
					
						
							|  |  |  |         non-zero status if any errors are found. | 
					
						
							| 
									
										
										
										
											2018-06-28 09:28:19 +05:30
										 |  |  |       EOS | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |       flag   "--os=", | 
					
						
							|  |  |  |              description: "Audit the given operating system. (Pass `all` to audit all operating systems.)" | 
					
						
							|  |  |  |       flag   "--arch=", | 
					
						
							|  |  |  |              description: "Audit the given CPU architecture. (Pass `all` to audit all architectures.)" | 
					
						
							| 
									
										
										
										
											2018-09-22 09:31:30 +05:30
										 |  |  |       switch "--strict", | 
					
						
							| 
									
										
										
										
											2020-04-16 08:24:38 +01:00
										 |  |  |              description: "Run additional, stricter style checks." | 
					
						
							| 
									
										
										
										
											2020-06-08 15:00:09 +01:00
										 |  |  |       switch "--git", | 
					
						
							|  |  |  |              description: "Run additional, slower style checks that navigate the Git repository." | 
					
						
							| 
									
										
										
										
											2018-09-22 09:31:30 +05:30
										 |  |  |       switch "--online", | 
					
						
							| 
									
										
										
										
											2020-04-16 08:24:38 +01:00
										 |  |  |              description: "Run additional, slower style checks that require a network connection." | 
					
						
							| 
									
										
										
										
											2022-03-08 19:24:55 +00:00
										 |  |  |       switch "--installed", | 
					
						
							|  |  |  |              description: "Only check formulae and casks that are 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 audit them. " \ | 
					
						
							| 
									
										
										
										
											2023-02-10 23:15:40 -05:00
										 |  |  |                           "Implied if `HOMEBREW_EVAL_ALL` is set." | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  |       switch "--new", "--new-formula", "--new-cask", | 
					
						
							| 
									
										
										
										
											2022-06-28 10:09:59 +01:00
										 |  |  |              description: "Run various additional style checks to determine if a new formula or cask is eligible " \ | 
					
						
							|  |  |  |                           "for Homebrew. This should be used when creating new formula and implies " \ | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |                           "`--strict` and `--online`." | 
					
						
							| 
									
										
										
										
											2022-12-06 11:00:59 +11:00
										 |  |  |       switch "--[no-]signing", | 
					
						
							| 
									
										
										
										
											2022-12-06 20:50:00 +11:00
										 |  |  |              description: "Audit for signed apps, which are required on ARM" | 
					
						
							| 
									
										
										
										
											2020-11-27 11:41:08 -05:00
										 |  |  |       switch "--token-conflicts", | 
					
						
							|  |  |  |              description: "Audit for token conflicts." | 
					
						
							| 
									
										
										
										
											2020-08-06 09:43:02 +01:00
										 |  |  |       flag   "--tap=", | 
					
						
							|  |  |  |              description: "Check the formulae within the given tap, specified as <user>`/`<repo>." | 
					
						
							| 
									
										
										
										
											2018-09-22 09:31:30 +05:30
										 |  |  |       switch "--fix", | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |              description: "Fix style violations automatically using RuboCop's auto-correct feature." | 
					
						
							| 
									
										
										
										
											2018-09-22 09:31:30 +05:30
										 |  |  |       switch "--display-cop-names", | 
					
						
							| 
									
										
										
										
											2023-04-11 00:19:09 +01:00
										 |  |  |              description: "Include the RuboCop cop name for each violation in the output. This is the default.", | 
					
						
							|  |  |  |              hidden:      true | 
					
						
							| 
									
										
										
										
											2018-09-22 09:31:30 +05:30
										 |  |  |       switch "--display-filename", | 
					
						
							| 
									
										
										
										
											2022-06-28 10:09:59 +01:00
										 |  |  |              description: "Prefix every line of output with the file or formula name being audited, to " \ | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |                           "make output easy to grep." | 
					
						
							| 
									
										
										
										
											2021-03-21 13:59:43 -04:00
										 |  |  |       switch "--display-failures-only", | 
					
						
							| 
									
										
										
										
											2023-04-03 17:23:02 +01:00
										 |  |  |              description: "Only display casks that fail the audit. This is the default for formulae and casks.", | 
					
						
							|  |  |  |              hidden:      true | 
					
						
							| 
									
										
										
										
											2020-04-16 08:24:38 +01:00
										 |  |  |       switch "--skip-style", | 
					
						
							| 
									
										
										
										
											2022-06-28 10:09:59 +01:00
										 |  |  |              description: "Skip running non-RuboCop style checks. Useful if you plan on running " \ | 
					
						
							| 
									
										
										
										
											2020-11-12 10:40:48 -05:00
										 |  |  |                           "`brew style` separately. Enabled by default unless a formula is specified by name." | 
					
						
							| 
									
										
										
										
											2018-09-22 09:31:30 +05:30
										 |  |  |       switch "-D", "--audit-debug", | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |              description: "Enable debugging and profiling of audit methods." | 
					
						
							| 
									
										
										
										
											2018-09-22 09:31:30 +05:30
										 |  |  |       comma_array "--only", | 
					
						
							| 
									
										
										
										
											2022-06-28 10:09:59 +01:00
										 |  |  |                   description: "Specify a comma-separated <method> list to only run the methods named " \ | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |                                "`audit_`<method>." | 
					
						
							| 
									
										
										
										
											2018-09-22 09:31:30 +05:30
										 |  |  |       comma_array "--except", | 
					
						
							| 
									
										
										
										
											2022-06-28 10:09:59 +01:00
										 |  |  |                   description: "Specify a comma-separated <method> list to skip running the methods named " \ | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |                                "`audit_`<method>." | 
					
						
							| 
									
										
										
										
											2018-09-22 09:31:30 +05:30
										 |  |  |       comma_array "--only-cops", | 
					
						
							| 
									
										
										
										
											2022-06-28 10:09:59 +01:00
										 |  |  |                   description: "Specify a comma-separated <cops> list to check for violations of only the listed " \ | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |                                "RuboCop cops." | 
					
						
							| 
									
										
										
										
											2018-09-22 09:31:30 +05:30
										 |  |  |       comma_array "--except-cops", | 
					
						
							| 
									
										
										
										
											2022-06-28 10:17:14 +01:00
										 |  |  |                   description: "Specify a comma-separated <cops> list to skip checking for violations of the " \ | 
					
						
							|  |  |  |                                "listed RuboCop cops." | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  |       switch "--formula", "--formulae", | 
					
						
							|  |  |  |              description: "Treat all named arguments as formulae." | 
					
						
							|  |  |  |       switch "--cask", "--casks", | 
					
						
							|  |  |  |              description: "Treat all named arguments as casks." | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-08 22:49:03 -04:00
										 |  |  |       conflicts "--only", "--except" | 
					
						
							| 
									
										
										
										
											2019-12-11 14:59:47 -05:00
										 |  |  |       conflicts "--only-cops", "--except-cops", "--strict" | 
					
						
							|  |  |  |       conflicts "--only-cops", "--except-cops", "--only" | 
					
						
							| 
									
										
										
										
											2020-11-27 11:41:08 -05:00
										 |  |  |       conflicts "--formula", "--cask" | 
					
						
							| 
									
										
										
										
											2022-03-08 19:24:55 +00:00
										 |  |  |       conflicts "--installed", "--all" | 
					
						
							| 
									
										
										
										
											2021-01-10 14:26:40 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 16:53:46 +01:00
										 |  |  |       named_args [:formula, :cask], without_api: true | 
					
						
							| 
									
										
										
										
											2018-03-25 17:48:22 +05:30
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-07-30 18:25:38 +05:30
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  |   sig { void } | 
					
						
							| 
									
										
										
										
											2023-03-13 18:31:26 -07:00
										 |  |  |   def self.audit | 
					
						
							| 
									
										
										
										
											2020-07-23 06:25:35 +02:00
										 |  |  |     args = audit_args.parse | 
					
						
							| 
									
										
										
										
											2018-02-04 22:09:35 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |     Formulary.enable_factory_cache! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     os_arch_combinations = args.os_arch_combinations | 
					
						
							| 
									
										
										
										
											2023-03-27 00:02:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-02 12:38:18 +05:30
										 |  |  |     Homebrew.auditing = true | 
					
						
							| 
									
										
										
										
											2018-02-04 22:09:35 +05:30
										 |  |  |     inject_dump_stats!(FormulaAuditor, /^audit_/) if args.audit_debug? | 
					
						
							| 
									
										
										
										
											2016-04-18 17:39:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-04 22:09:35 +05:30
										 |  |  |     new_formula = args.new_formula? | 
					
						
							|  |  |  |     strict = new_formula || args.strict? | 
					
						
							|  |  |  |     online = new_formula || args.online? | 
					
						
							| 
									
										
										
										
											2023-06-20 22:36:15 +08:00
										 |  |  |     tap_audit = args.tap.present? | 
					
						
							|  |  |  |     skip_style = args.skip_style? || args.no_named? || tap_audit | 
					
						
							| 
									
										
										
										
											2023-03-13 18:31:26 -07:00
										 |  |  |     no_named_args = T.let(false, T::Boolean) | 
					
						
							| 
									
										
										
										
											2015-07-09 12:31:17 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-28 02:04:50 +02:00
										 |  |  |     ENV.activate_extensions! | 
					
						
							|  |  |  |     ENV.setup_build_environment | 
					
						
							| 
									
										
										
										
											2013-05-07 18:39:45 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 16:53:46 +01:00
										 |  |  |     audit_formulae, audit_casks = Homebrew.with_no_api_env do # audit requires full Ruby source | 
					
						
							| 
									
										
										
										
											2023-02-24 12:29:36 +00:00
										 |  |  |       if args.tap | 
					
						
							|  |  |  |         Tap.fetch(args.tap).then do |tap| | 
					
						
							|  |  |  |           [ | 
					
						
							| 
									
										
										
										
											2023-09-26 20:37:41 -07:00
										 |  |  |             tap.formula_files.map { |path| Formulary.factory(path) }, | 
					
						
							| 
									
										
										
										
											2023-02-24 12:29:36 +00:00
										 |  |  |             tap.cask_files.map { |path| Cask::CaskLoader.load(path) }, | 
					
						
							|  |  |  |           ] | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       elsif args.installed? | 
					
						
							|  |  |  |         no_named_args = true | 
					
						
							|  |  |  |         [Formula.installed, Cask::Caskroom.casks] | 
					
						
							|  |  |  |       elsif args.no_named? | 
					
						
							|  |  |  |         if !args.eval_all? && !Homebrew::EnvConfig.eval_all? | 
					
						
							| 
									
										
										
										
											2023-07-06 16:47:09 +01:00
										 |  |  |           # This odisabled should probably stick around indefinitely. | 
					
						
							| 
									
										
										
										
											2023-02-24 12:29:36 +00:00
										 |  |  |           odisabled "brew audit", | 
					
						
							|  |  |  |                     "brew audit --eval-all or HOMEBREW_EVAL_ALL" | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         no_named_args = true | 
					
						
							| 
									
										
										
										
											2023-09-02 19:35:22 +09:00
										 |  |  |         [Formula.all(eval_all: args.eval_all?), Cask::Cask.all] | 
					
						
							| 
									
										
										
										
											2023-02-24 12:29:36 +00:00
										 |  |  |       else | 
					
						
							|  |  |  |         if args.named.any? { |named_arg| named_arg.end_with?(".rb") } | 
					
						
							| 
									
										
										
										
											2023-07-06 16:47:09 +01:00
										 |  |  |           odisabled "brew audit [path ...]", | 
					
						
							|  |  |  |                     "brew audit [name ...]" | 
					
						
							| 
									
										
										
										
											2023-02-24 12:29:36 +00:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2022-12-21 21:40:58 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-24 12:29:36 +00:00
										 |  |  |         args.named.to_formulae_and_casks | 
					
						
							|  |  |  |             .partition { |formula_or_cask| formula_or_cask.is_a?(Formula) } | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2020-08-06 09:43:02 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2022-09-26 10:49:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-11 21:52:31 +02:00
										 |  |  |     if audit_formulae.empty? && audit_casks.empty? && !args.tap | 
					
						
							| 
									
										
										
										
											2022-09-26 15:37:12 +02:00
										 |  |  |       ofail "No matching formulae or casks to audit!" | 
					
						
							| 
									
										
										
										
											2022-09-26 10:49:12 +02:00
										 |  |  |       return | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-27 19:44:02 +01:00
										 |  |  |     gem_groups = ["audit"] | 
					
						
							|  |  |  |     gem_groups << "style" unless skip_style | 
					
						
							|  |  |  |     Homebrew.install_bundler_gems!(groups: gem_groups) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  |     style_files = args.named.to_paths unless skip_style | 
					
						
							| 
									
										
										
										
											2016-08-16 17:00:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-04 22:09:35 +05:30
										 |  |  |     only_cops = args.only_cops | 
					
						
							|  |  |  |     except_cops = args.except_cops | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  |     style_options = { fix: args.fix?, debug: args.debug?, verbose: args.verbose? } | 
					
						
							| 
									
										
										
										
											2017-05-03 11:33:00 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-04 22:09:35 +05:30
										 |  |  |     if only_cops | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  |       style_options[:only_cops] = only_cops | 
					
						
							| 
									
										
										
										
											2018-02-04 22:09:35 +05:30
										 |  |  |     elsif args.new_formula? | 
					
						
							| 
									
										
										
										
											2017-07-28 05:01:01 +05:30
										 |  |  |       nil | 
					
						
							| 
									
										
										
										
											2018-02-04 22:09:35 +05:30
										 |  |  |     elsif except_cops | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  |       style_options[:except_cops] = except_cops | 
					
						
							| 
									
										
										
										
											2017-05-03 11:33:00 +05:30
										 |  |  |     elsif !strict | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  |       style_options[:except_cops] = [:FormulaAuditStrict] | 
					
						
							| 
									
										
										
										
											2012-08-07 01:37:46 -05:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-12-27 12:38:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 01:25:13 -05:00
										 |  |  |     # Run tap audits first | 
					
						
							| 
									
										
										
										
											2023-07-04 16:08:04 +01:00
										 |  |  |     named_arg_taps = [*audit_formulae, *audit_casks].map(&:tap).uniq if !args.tap && !no_named_args | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |     tap_problems = Tap.each_with_object({}) do |tap, problems| | 
					
						
							| 
									
										
										
										
											2020-11-06 10:12:09 -05:00
										 |  |  |       next if args.tap && tap != args.tap | 
					
						
							| 
									
										
										
										
											2023-07-04 16:08:04 +01:00
										 |  |  |       next if named_arg_taps&.exclude?(tap) | 
					
						
							| 
									
										
										
										
											2020-11-06 10:12:09 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  |       ta = TapAuditor.new(tap, strict: args.strict?) | 
					
						
							| 
									
										
										
										
											2020-11-05 01:25:13 -05:00
										 |  |  |       ta.audit | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |       problems[[tap.name, tap.path]] = ta.problems if ta.problems.any? | 
					
						
							| 
									
										
										
										
											2020-11-05 01:25:13 -05:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-23 04:09:13 +05:30
										 |  |  |     # Check style in a single batch run up front for performance | 
					
						
							| 
									
										
										
										
											2022-10-18 01:32:55 +01:00
										 |  |  |     style_offenses = Style.check_style_json(style_files, **style_options) if style_files | 
					
						
							| 
									
										
										
										
											2020-06-16 00:19:32 +08:00
										 |  |  |     # load licenses | 
					
						
							| 
									
										
										
										
											2020-08-18 11:00:17 -04:00
										 |  |  |     spdx_license_data = SPDX.license_data | 
					
						
							|  |  |  |     spdx_exception_data = SPDX.exception_data | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-09 18:47:29 -07:00
										 |  |  |     clear_formulary_cache = [args.os, args.arch].any? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |     formula_problems = audit_formulae.sort.each_with_object({}) do |f, problems| | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |       path = f.path | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-30 23:44:14 +05:30
										 |  |  |       only = only_cops ? ["style"] : args.only | 
					
						
							| 
									
										
										
										
											2020-06-08 15:00:09 +01:00
										 |  |  |       options = { | 
					
						
							| 
									
										
										
										
											2021-10-04 21:45:20 -04:00
										 |  |  |         new_formula:         new_formula, | 
					
						
							|  |  |  |         strict:              strict, | 
					
						
							|  |  |  |         online:              online, | 
					
						
							|  |  |  |         git:                 args.git?, | 
					
						
							|  |  |  |         only:                only, | 
					
						
							|  |  |  |         except:              args.except, | 
					
						
							|  |  |  |         spdx_license_data:   spdx_license_data, | 
					
						
							|  |  |  |         spdx_exception_data: spdx_exception_data, | 
					
						
							| 
									
										
										
										
											2022-12-13 10:54:22 +00:00
										 |  |  |         style_offenses:      style_offenses&.for_path(f.path), | 
					
						
							| 
									
										
										
										
											2023-06-20 22:36:15 +08:00
										 |  |  |         tap_audit:           tap_audit, | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  |       }.compact | 
					
						
							| 
									
										
										
										
											2019-09-02 10:48:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |       errors = os_arch_combinations.flat_map do |os, arch| | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |         SimulateSystem.with os: os, arch: arch do | 
					
						
							|  |  |  |           odebug "Auditing Formula #{f} on os #{os} and arch #{arch}" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-09 18:47:29 -07:00
										 |  |  |           Formulary.clear_cache if clear_formulary_cache | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |           audit_proc = proc { FormulaAuditor.new(Formulary.factory(path), **options).tap(&:audit) } | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |           # Audit requires full Ruby source so disable API. | 
					
						
							|  |  |  |           # We shouldn't do this for taps however so that we don't unnecessarily require a full Homebrew/core clone. | 
					
						
							|  |  |  |           fa = if f.core_formula? | 
					
						
							| 
									
										
										
										
											2023-06-22 16:53:46 +01:00
										 |  |  |             Homebrew.with_no_api_env(&audit_proc) | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |           else | 
					
						
							|  |  |  |             audit_proc.call | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |           fa.problems + fa.new_formula_problems | 
					
						
							| 
									
										
										
										
											2021-04-03 03:49:41 +02:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |       end.uniq | 
					
						
							| 
									
										
										
										
											2021-04-03 03:49:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |       problems[[f.full_name, path]] = errors if errors.any? | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if audit_casks.any? | 
					
						
							|  |  |  |       require "cask/auditor" | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-29 00:40:46 +01:00
										 |  |  |       if args.display_failures_only? | 
					
						
							| 
									
										
										
										
											2023-07-06 16:47:09 +01:00
										 |  |  |         odisabled "`brew audit <cask> --display-failures-only`", "`brew audit <cask>` without the argument" | 
					
						
							| 
									
										
										
										
											2023-03-29 00:40:46 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2023-03-29 00:40:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |     cask_problems = audit_casks.each_with_object({}) do |cask, problems| | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |       path = cask.sourcefile_path | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |       errors = os_arch_combinations.flat_map do |os, arch| | 
					
						
							|  |  |  |         next [] if os == :linux | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         SimulateSystem.with os: os, arch: arch do | 
					
						
							|  |  |  |           odebug "Auditing Cask #{cask} on os #{os} and arch #{arch}" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |           Cask::Auditor.audit( | 
					
						
							| 
									
										
										
										
											2023-09-06 22:30:43 -07:00
										 |  |  |             Cask::CaskLoader.load(path), | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |             # For switches, we add `|| nil` so that `nil` will be passed | 
					
						
							|  |  |  |             # instead of `false` if they aren't set. | 
					
						
							|  |  |  |             # This way, we can distinguish between "not set" and "set to false". | 
					
						
							|  |  |  |             audit_online:          (args.online? || nil), | 
					
						
							|  |  |  |             audit_strict:          (args.strict? || nil), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # No need for `|| nil` for `--[no-]signing` | 
					
						
							|  |  |  |             # because boolean switches are already `nil` if not passed | 
					
						
							|  |  |  |             audit_signing:         args.signing?, | 
					
						
							|  |  |  |             audit_new_cask:        (args.new_cask? || nil), | 
					
						
							|  |  |  |             audit_token_conflicts: (args.token_conflicts? || nil), | 
					
						
							|  |  |  |             quarantine:            true, | 
					
						
							|  |  |  |             any_named_args:        !no_named_args, | 
					
						
							|  |  |  |             only:                  args.only, | 
					
						
							|  |  |  |             except:                args.except, | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |           ).to_a | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |       end.uniq | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       problems[[cask.full_name, path]] = errors if errors.any? | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |     print_problems(tap_problems, display_filename: args.display_filename?) | 
					
						
							|  |  |  |     print_problems(formula_problems, display_filename: args.display_filename?) | 
					
						
							|  |  |  |     print_problems(cask_problems, display_filename: args.display_filename?) | 
					
						
							| 
									
										
										
										
											2018-04-30 01:22:04 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |     tap_count = tap_problems.keys.count | 
					
						
							|  |  |  |     formula_count = formula_problems.keys.count | 
					
						
							|  |  |  |     cask_count = cask_problems.keys.count | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |     corrected_problem_count = (formula_problems.values + cask_problems.values) | 
					
						
							|  |  |  |                               .sum { |problems| problems.count { |problem| problem.fetch(:corrected) } } | 
					
						
							| 
									
										
										
										
											2020-11-06 10:12:09 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |     tap_problem_count = tap_problems.sum { |_, problems| problems.count } | 
					
						
							|  |  |  |     formula_problem_count = formula_problems.sum { |_, problems| problems.count } | 
					
						
							|  |  |  |     cask_problem_count = cask_problems.sum { |_, problems| problems.count } | 
					
						
							|  |  |  |     total_problems_count = formula_problem_count + cask_problem_count + tap_problem_count | 
					
						
							| 
									
										
										
										
											2021-04-03 03:49:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |     if total_problems_count.positive? | 
					
						
							| 
									
										
										
										
											2023-03-20 07:23:17 -04:00
										 |  |  |       errors_summary = Utils.pluralize("problem", total_problems_count, include_count: true) | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-03 03:49:41 +02:00
										 |  |  |       error_sources = [] | 
					
						
							| 
									
										
										
										
											2023-02-24 08:53:04 -08:00
										 |  |  |       if formula_count.positive? | 
					
						
							| 
									
										
										
										
											2023-03-20 07:23:17 -04:00
										 |  |  |         error_sources << Utils.pluralize("formula", formula_count, plural: "e", include_count: true) | 
					
						
							| 
									
										
										
										
											2023-02-24 08:53:04 -08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-03-20 07:23:17 -04:00
										 |  |  |       error_sources << Utils.pluralize("cask", cask_count, include_count: true) if cask_count.positive? | 
					
						
							|  |  |  |       error_sources << Utils.pluralize("tap", tap_count, include_count: true) if tap_count.positive? | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-03 03:49:41 +02:00
										 |  |  |       errors_summary += " in #{error_sources.to_sentence}" if error_sources.any? | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-03 03:49:41 +02:00
										 |  |  |       errors_summary += " detected" | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-03 03:49:41 +02:00
										 |  |  |       if corrected_problem_count.positive? | 
					
						
							| 
									
										
										
										
											2023-03-20 07:23:17 -04:00
										 |  |  |         errors_summary += ", #{Utils.pluralize("problem", corrected_problem_count, include_count: true)} corrected" | 
					
						
							| 
									
										
										
										
											2021-04-03 03:49:41 +02:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |       ofail "#{errors_summary}." | 
					
						
							| 
									
										
										
										
											2021-04-03 03:49:41 +02:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2020-11-18 12:41:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-03 03:49:41 +02:00
										 |  |  |     return unless ENV["GITHUB_ACTIONS"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |     annotations = formula_problems.merge(cask_problems).flat_map do |(_, path), problems| | 
					
						
							| 
									
										
										
										
											2023-04-22 15:13:35 +08:00
										 |  |  |       problems.map do |problem| | 
					
						
							|  |  |  |         GitHub::Actions::Annotation.new( | 
					
						
							|  |  |  |           :error, | 
					
						
							|  |  |  |           problem[:message], | 
					
						
							|  |  |  |           file:   path, | 
					
						
							|  |  |  |           line:   problem[:location]&.line, | 
					
						
							|  |  |  |           column: problem[:location]&.column, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-04-19 16:09:45 +01:00
										 |  |  |     end.compact | 
					
						
							| 
									
										
										
										
											2018-05-22 18:16:46 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-03 03:49:41 +02:00
										 |  |  |     annotations.each do |annotation| | 
					
						
							|  |  |  |       puts annotation if annotation.relevant? | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-04-30 01:22:04 +05:30
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-09-22 20:12:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |   def self.print_problems(results, display_filename:) | 
					
						
							|  |  |  |     results.each do |(name, path), problems| | 
					
						
							|  |  |  |       problem_lines = format_problem_lines(problems) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if display_filename | 
					
						
							|  |  |  |         problem_lines.each do |l| | 
					
						
							|  |  |  |           puts "#{path}: #{l}" | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         puts name, problem_lines.map { |l| l.dup.prepend("  ") } | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2020-09-10 22:00:18 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |   def self.format_problem_lines(problems) | 
					
						
							| 
									
										
										
										
											2023-10-30 21:21:30 +00:00
										 |  |  |     problems.map do |problem| | 
					
						
							|  |  |  |       status = " #{Formatter.success("[corrected]")}" if problem.fetch(:corrected) | 
					
						
							|  |  |  |       location = problem.fetch(:location) | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |       location = "#{location.line&.to_s&.prepend("line ")}#{location.column&.to_s&.prepend(", col ")}: " if location | 
					
						
							| 
									
										
										
										
											2023-10-30 21:21:30 +00:00
										 |  |  |       message = problem.fetch(:message) | 
					
						
							| 
									
										
										
										
											2023-05-19 16:59:14 +02:00
										 |  |  |       "* #{location}#{message.chomp.gsub("\n", "\n    ")}#{status}" | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-08-07 01:37:46 -05:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-09-18 18:08:50 -05:00
										 |  |  | end |