| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  | # typed: strict | 
					
						
							| 
									
										
										
										
											2020-06-29 10:16:58 -05:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  | require "bump_version_parser" | 
					
						
							| 
									
										
										
										
											2020-06-29 09:47:19 -05:00
										 |  |  | require "cli/parser" | 
					
						
							| 
									
										
										
										
											2021-01-11 08:29:34 +05:30
										 |  |  | require "livecheck/livecheck" | 
					
						
							| 
									
										
										
										
											2020-06-29 09:47:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | module Homebrew | 
					
						
							|  |  |  |   module_function | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |   class VersionBumpInfo < T::Struct | 
					
						
							|  |  |  |     const :type, Symbol | 
					
						
							|  |  |  |     const :multiple_versions, T::Boolean | 
					
						
							|  |  |  |     const :version_name, String | 
					
						
							|  |  |  |     const :current_version, BumpVersionParser | 
					
						
							|  |  |  |     const :repology_latest, T.any(String, Version) | 
					
						
							|  |  |  |     const :new_version, BumpVersionParser | 
					
						
							|  |  |  |     const :open_pull_requests, T.nilable(T.any(T::Array[String], String)) | 
					
						
							|  |  |  |     const :closed_pull_requests, T.nilable(T.any(T::Array[String], String)) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   sig { returns(CLI::Parser) } | 
					
						
							| 
									
										
										
										
											2020-06-29 09:47:19 -05:00
										 |  |  |   def bump_args | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     CLI::Parser.new do | 
					
						
							| 
									
										
										
										
											2021-01-15 15:04:02 -05:00
										 |  |  |       description <<~EOS | 
					
						
							| 
									
										
										
										
											2021-09-24 22:44:27 -04:00
										 |  |  |         Display out-of-date brew formulae and the latest version available. If the | 
					
						
							|  |  |  |         returned current and livecheck versions differ or when querying specific | 
					
						
							|  |  |  |         formulae, also displays whether a pull request has been opened with the URL. | 
					
						
							| 
									
										
										
										
											2020-06-29 09:47:19 -05:00
										 |  |  |       EOS | 
					
						
							| 
									
										
										
										
											2021-03-04 01:39:37 +05:30
										 |  |  |       switch "--full-name", | 
					
						
							|  |  |  |              description: "Print formulae/casks with fully-qualified names." | 
					
						
							| 
									
										
										
										
											2021-02-17 00:09:02 +05:30
										 |  |  |       switch "--no-pull-requests", | 
					
						
							|  |  |  |              description: "Do not retrieve pull requests from GitHub." | 
					
						
							|  |  |  |       switch "--formula", "--formulae", | 
					
						
							|  |  |  |              description: "Check only formulae." | 
					
						
							|  |  |  |       switch "--cask", "--casks", | 
					
						
							|  |  |  |              description: "Check only casks." | 
					
						
							| 
									
										
										
										
											2023-08-05 09:51:54 -07:00
										 |  |  |       switch "--installed", | 
					
						
							|  |  |  |              description: "Check formulae and casks that are currently installed." | 
					
						
							| 
									
										
										
										
											2022-01-12 17:31:55 +00:00
										 |  |  |       switch "--open-pr", | 
					
						
							| 
									
										
										
										
											2023-01-19 17:06:42 -08:00
										 |  |  |              description: "Open a pull request for the new version if none have been opened yet." | 
					
						
							| 
									
										
										
										
											2020-11-12 10:40:41 -05:00
										 |  |  |       flag   "--limit=", | 
					
						
							|  |  |  |              description: "Limit number of package results returned." | 
					
						
							| 
									
										
										
										
											2021-09-24 22:44:27 -04:00
										 |  |  |       flag   "--start-with=", | 
					
						
							|  |  |  |              description: "Letter or word that the list of package results should alphabetically follow." | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |       switch "-f", "--force", | 
					
						
							|  |  |  |              description: "Ignore duplicate open PRs.", | 
					
						
							|  |  |  |              hidden:      true | 
					
						
							| 
									
										
										
										
											2021-01-15 15:46:24 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-17 00:09:02 +05:30
										 |  |  |       conflicts "--cask", "--formula" | 
					
						
							| 
									
										
										
										
											2022-01-12 17:31:55 +00:00
										 |  |  |       conflicts "--no-pull-requests", "--open-pr" | 
					
						
							| 
									
										
										
										
											2021-02-17 00:09:02 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 16:53:46 +01:00
										 |  |  |       named_args [:formula, :cask], without_api: true | 
					
						
							| 
									
										
										
										
											2020-06-29 09:47:19 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |   sig { void } | 
					
						
							| 
									
										
										
										
											2020-06-29 09:47:19 -05:00
										 |  |  |   def bump | 
					
						
							| 
									
										
										
										
											2020-08-05 10:10:05 -05:00
										 |  |  |     args = bump_args.parse | 
					
						
							| 
									
										
										
										
											2020-07-01 10:21:57 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-17 00:09:02 +05:30
										 |  |  |     if args.limit.present? && !args.formula? && !args.cask? | 
					
						
							|  |  |  |       raise UsageError, "`--limit` must be used with either `--formula` or `--cask`." | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2020-07-28 09:30:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-05 09:51:54 -07:00
										 |  |  |     Homebrew.with_no_api_env do | 
					
						
							|  |  |  |       formulae_and_casks = if args.installed? | 
					
						
							|  |  |  |         formulae = args.cask? ? [] : Formula.installed | 
					
						
							|  |  |  |         casks = args.formula? ? [] : Cask::Caskroom.casks | 
					
						
							|  |  |  |         formulae + casks | 
					
						
							|  |  |  |       elsif args.named.present? | 
					
						
							|  |  |  |         if args.formula? | 
					
						
							|  |  |  |           args.named.to_formulae | 
					
						
							|  |  |  |         elsif args.cask? | 
					
						
							|  |  |  |           args.named.to_casks | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           args.named.to_formulae_and_casks | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2020-08-16 20:38:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-05 09:51:54 -07:00
										 |  |  |       formulae_and_casks = formulae_and_casks&.sort_by do |formula_or_cask| | 
					
						
							|  |  |  |         formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       unless Utils::Curl.curl_supports_tls13? | 
					
						
							|  |  |  |         begin | 
					
						
							|  |  |  |           ensure_formula_installed!("curl", reason: "Repology queries") unless HOMEBREW_BREWED_CURL_PATH.exist? | 
					
						
							|  |  |  |         rescue FormulaUnavailableError | 
					
						
							|  |  |  |           opoo "A newer `curl` is required for Repology queries." | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2021-09-24 22:44:27 -04:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-04 19:08:22 -07:00
										 |  |  |       if formulae_and_casks.present? | 
					
						
							|  |  |  |         handle_formula_and_casks(formulae_and_casks, args) | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         handle_api_response(args) | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2021-03-04 01:39:37 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |   sig { params(formulae_and_casks: T::Array[T.any(Formula, Cask::Cask)], args: CLI::Args).void } | 
					
						
							|  |  |  |   def handle_formula_and_casks(formulae_and_casks, args) | 
					
						
							|  |  |  |     Livecheck.load_other_tap_strategies(formulae_and_casks) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ambiguous_casks = [] | 
					
						
							|  |  |  |     if !args.formula? && !args.cask? | 
					
						
							|  |  |  |       ambiguous_casks = formulae_and_casks | 
					
						
							|  |  |  |                         .group_by { |item| Livecheck.package_or_resource_name(item, full_name: true) } | 
					
						
							|  |  |  |                         .values | 
					
						
							|  |  |  |                         .select { |items| items.length > 1 } | 
					
						
							|  |  |  |                         .flatten | 
					
						
							|  |  |  |                         .select { |item| item.is_a?(Cask::Cask) } | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2020-07-02 17:06:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     ambiguous_names = [] | 
					
						
							|  |  |  |     unless args.full_name? | 
					
						
							|  |  |  |       ambiguous_names = (formulae_and_casks - ambiguous_casks) | 
					
						
							|  |  |  |                         .group_by { |item| Livecheck.package_or_resource_name(item) } | 
					
						
							|  |  |  |                         .values | 
					
						
							|  |  |  |                         .select { |items| items.length > 1 } | 
					
						
							|  |  |  |                         .flatten | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2021-02-17 00:09:02 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     formulae_and_casks.each_with_index do |formula_or_cask, i| | 
					
						
							|  |  |  |       puts if i.positive? | 
					
						
							| 
									
										
										
										
											2020-07-28 09:30:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |       use_full_name = args.full_name? || ambiguous_names.include?(formula_or_cask) | 
					
						
							|  |  |  |       name = Livecheck.package_or_resource_name(formula_or_cask, full_name: use_full_name) | 
					
						
							|  |  |  |       repository = if formula_or_cask.is_a?(Formula) | 
					
						
							| 
									
										
										
										
											2023-09-13 18:02:12 -04:00
										 |  |  |         next if skip_ineligible_formulae(formula_or_cask) | 
					
						
							| 
									
										
										
										
											2022-01-31 04:22:55 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |         Repology::HOMEBREW_CORE | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         Repology::HOMEBREW_CASK | 
					
						
							| 
									
										
										
										
											2020-08-16 20:38:03 -05:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |       package_data = if formula_or_cask.is_a?(Formula) && formula_or_cask.versioned_formula? | 
					
						
							|  |  |  |         nil | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         Repology.single_package_query(name, repository: repository) | 
					
						
							| 
									
										
										
										
											2021-02-17 02:04:13 +05:30
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2021-02-17 00:09:02 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |       retrieve_and_display_info_and_open_pr( | 
					
						
							|  |  |  |         formula_or_cask, | 
					
						
							|  |  |  |         name, | 
					
						
							|  |  |  |         package_data&.values&.first, | 
					
						
							|  |  |  |         args:           args, | 
					
						
							|  |  |  |         ambiguous_cask: ambiguous_casks.include?(formula_or_cask), | 
					
						
							|  |  |  |       ) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2021-01-11 08:29:34 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |   sig { params(args: CLI::Args).void } | 
					
						
							|  |  |  |   def handle_api_response(args) | 
					
						
							|  |  |  |     limit = args.limit.to_i if args.limit.present? | 
					
						
							| 
									
										
										
										
											2021-09-24 22:44:27 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     api_response = {} | 
					
						
							|  |  |  |     unless args.cask? | 
					
						
							|  |  |  |       api_response[:formulae] = | 
					
						
							|  |  |  |         Repology.parse_api_response(limit, args.start_with, repository: Repology::HOMEBREW_CORE) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     unless args.formula? | 
					
						
							|  |  |  |       api_response[:casks] = | 
					
						
							|  |  |  |         Repology.parse_api_response(limit, args.start_with, repository: Repology::HOMEBREW_CASK) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2021-01-11 08:29:34 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     api_response.each_with_index do |(package_type, outdated_packages), idx| | 
					
						
							|  |  |  |       repository = if package_type == :formulae | 
					
						
							|  |  |  |         Repology::HOMEBREW_CORE | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         Repology::HOMEBREW_CASK | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       puts if idx.positive? | 
					
						
							|  |  |  |       oh1 package_type.capitalize if api_response.size > 1
 | 
					
						
							| 
									
										
										
										
											2021-02-17 00:09:02 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |       outdated_packages.each_with_index do |(_name, repositories), i| | 
					
						
							|  |  |  |         break if limit && i >= limit | 
					
						
							| 
									
										
										
										
											2020-08-16 20:38:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |         homebrew_repo = repositories.find do |repo| | 
					
						
							|  |  |  |           repo["repo"] == repository | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         next if homebrew_repo.blank? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         formula_or_cask = begin | 
					
						
							|  |  |  |           if repository == Repology::HOMEBREW_CORE | 
					
						
							|  |  |  |             Formula[homebrew_repo["srcname"]] | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             Cask::CaskLoader.load(homebrew_repo["srcname"]) | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         rescue | 
					
						
							|  |  |  |           next | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         name = Livecheck.package_or_resource_name(formula_or_cask) | 
					
						
							|  |  |  |         ambiguous_cask = begin | 
					
						
							|  |  |  |           formula_or_cask.is_a?(Cask::Cask) && !args.cask? && Formula[name] | 
					
						
							|  |  |  |         rescue FormulaUnavailableError | 
					
						
							|  |  |  |           false | 
					
						
							| 
									
										
										
										
											2021-02-17 00:09:02 +05:30
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         puts if i.positive? | 
					
						
							| 
									
										
										
										
											2023-09-13 18:02:12 -04:00
										 |  |  |         next if formula_or_cask.is_a?(Formula) && skip_ineligible_formulae(formula_or_cask) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |         retrieve_and_display_info_and_open_pr( | 
					
						
							|  |  |  |           formula_or_cask, | 
					
						
							|  |  |  |           name, | 
					
						
							|  |  |  |           repositories, | 
					
						
							|  |  |  |           args:           args, | 
					
						
							|  |  |  |           ambiguous_cask: ambiguous_cask, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-08-16 20:38:03 -05:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2021-01-11 08:29:34 +05:30
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2020-08-16 20:38:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-13 18:02:12 -04:00
										 |  |  |   sig { | 
					
						
							|  |  |  |     params(formula: Formula).returns(T::Boolean) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   def skip_ineligible_formulae(formula) | 
					
						
							|  |  |  |     return false if !formula.disabled? && !formula.head_only? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ohai formula.name | 
					
						
							|  |  |  |     puts "Formula is #{formula.disabled? ? "disabled" : "HEAD-only"}.\n" | 
					
						
							|  |  |  |     true | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |   sig { | 
					
						
							|  |  |  |     params(formula_or_cask: T.any(Formula, Cask::Cask)).returns(T.any(Version, String)) | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-02-17 00:09:02 +05:30
										 |  |  |   def livecheck_result(formula_or_cask) | 
					
						
							| 
									
										
										
										
											2022-09-14 03:42:12 +02:00
										 |  |  |     name = Livecheck.package_or_resource_name(formula_or_cask) | 
					
						
							| 
									
										
										
										
											2021-07-19 12:55:57 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     referenced_formula_or_cask, = Livecheck.resolve_livecheck_reference( | 
					
						
							|  |  |  |       formula_or_cask, | 
					
						
							|  |  |  |       full_name: false, | 
					
						
							|  |  |  |       debug:     false, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-07-19 12:55:57 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Check skip conditions for a referenced formula/cask | 
					
						
							|  |  |  |     if referenced_formula_or_cask | 
					
						
							|  |  |  |       skip_info = Livecheck::SkipConditions.referenced_skip_information( | 
					
						
							|  |  |  |         referenced_formula_or_cask, | 
					
						
							|  |  |  |         name, | 
					
						
							|  |  |  |         full_name: false, | 
					
						
							|  |  |  |         verbose:   false, | 
					
						
							|  |  |  |       ) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     skip_info ||= Livecheck::SkipConditions.skip_information( | 
					
						
							|  |  |  |       formula_or_cask, | 
					
						
							|  |  |  |       full_name: false, | 
					
						
							|  |  |  |       verbose:   false, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-19 12:55:57 -04:00
										 |  |  |     if skip_info.present? | 
					
						
							|  |  |  |       return "#{skip_info[:status]}#{" - #{skip_info[:messages].join(", ")}" if skip_info[:messages].present?}" | 
					
						
							| 
									
										
										
										
											2020-08-05 10:10:05 -05:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2020-08-16 19:22:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-11 08:29:34 +05:30
										 |  |  |     version_info = Livecheck.latest_version( | 
					
						
							| 
									
										
										
										
											2021-02-17 00:09:02 +05:30
										 |  |  |       formula_or_cask, | 
					
						
							| 
									
										
										
										
											2021-07-19 12:55:57 -04:00
										 |  |  |       referenced_formula_or_cask: referenced_formula_or_cask, | 
					
						
							| 
									
										
										
										
											2022-02-19 21:03:02 +00:00
										 |  |  |       json: true, full_name: false, verbose: true, debug: false | 
					
						
							| 
									
										
										
										
											2021-01-11 08:29:34 +05:30
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2022-02-19 21:03:02 +00:00
										 |  |  |     return "unable to get versions" if version_info.blank? | 
					
						
							| 
									
										
										
										
											2021-01-11 08:29:34 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 21:03:02 +00:00
										 |  |  |     latest = version_info[:latest] | 
					
						
							| 
									
										
										
										
											2021-01-11 08:29:34 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-30 08:30:05 +01:00
										 |  |  |     Version.new(latest) | 
					
						
							| 
									
										
										
										
											2021-02-17 02:36:29 +05:30
										 |  |  |   rescue => e | 
					
						
							|  |  |  |     "error: #{e}" | 
					
						
							| 
									
										
										
										
											2020-07-02 17:06:39 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |   sig { | 
					
						
							|  |  |  |     params( | 
					
						
							|  |  |  |       formula_or_cask: T.any(Formula, Cask::Cask), | 
					
						
							|  |  |  |       name:            String, | 
					
						
							|  |  |  |       state:           String, | 
					
						
							|  |  |  |       version:         T.nilable(String), | 
					
						
							|  |  |  |     ).returns T.nilable(T.any(T::Array[String], String)) | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-01-19 17:06:42 -08:00
										 |  |  |   def retrieve_pull_requests(formula_or_cask, name, state:, version: nil) | 
					
						
							| 
									
										
										
										
											2021-03-21 12:35:45 -04:00
										 |  |  |     tap_remote_repo = formula_or_cask.tap&.remote_repo || formula_or_cask.tap&.full_name | 
					
						
							| 
									
										
										
										
											2023-01-19 17:06:42 -08:00
										 |  |  |     pull_requests = GitHub.fetch_pull_requests(name, tap_remote_repo, state: state, version: version) | 
					
						
							| 
									
										
										
										
											2023-10-08 09:36:08 -07:00
										 |  |  |     if pull_requests&.any? | 
					
						
							| 
									
										
										
										
											2021-01-11 08:29:34 +05:30
										 |  |  |       pull_requests = pull_requests.map { |pr| "#{pr["title"]} (#{Formatter.url(pr["html_url"])})" }.join(", ") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pull_requests | 
					
						
							| 
									
										
										
										
											2020-07-06 03:32:18 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |   sig { | 
					
						
							|  |  |  |     params( | 
					
						
							|  |  |  |       formula_or_cask: T.any(Formula, Cask::Cask), | 
					
						
							|  |  |  |       repositories:    T::Array[T.untyped], | 
					
						
							|  |  |  |       args:            T.untyped, | 
					
						
							|  |  |  |       name:            String, | 
					
						
							|  |  |  |     ).returns(VersionBumpInfo) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   def retrieve_versions_by_arch(formula_or_cask:, repositories:, args:, name:) | 
					
						
							|  |  |  |     is_cask_with_blocks = formula_or_cask.is_a?(Cask::Cask) && formula_or_cask.on_system_blocks_exist? | 
					
						
							|  |  |  |     type, version_name = formula_or_cask.is_a?(Formula) ? [:formula, "formula version:"] : [:cask, "cask version:   "] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     old_versions = {} | 
					
						
							|  |  |  |     new_versions = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     repology_latest = repositories.present? ? Repology.latest_version(repositories) : "not found" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # When blocks are absent, arch is not relevant. For consistency, we simulate the arm architecture. | 
					
						
							|  |  |  |     arch_options = is_cask_with_blocks ? OnSystem::ARCH_OPTIONS : [:arm] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     arch_options.each do |arch| | 
					
						
							|  |  |  |       SimulateSystem.with arch: arch do | 
					
						
							|  |  |  |         version_key = is_cask_with_blocks ? arch : :general | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # We reload the formula/cask here to ensure we're getting the correct version for the current arch | 
					
						
							|  |  |  |         if formula_or_cask.is_a?(Formula) | 
					
						
							|  |  |  |           loaded_formula_or_cask = formula_or_cask | 
					
						
							|  |  |  |           current_version_value = T.must(loaded_formula_or_cask.stable).version | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           loaded_formula_or_cask = Cask::CaskLoader.load(formula_or_cask.sourcefile_path) | 
					
						
							|  |  |  |           current_version_value = Version.new(loaded_formula_or_cask.version) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         livecheck_latest = livecheck_result(loaded_formula_or_cask) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         new_version_value = if (livecheck_latest.is_a?(Version) && livecheck_latest >= current_version_value) || | 
					
						
							|  |  |  |                                current_version_value == "latest" | 
					
						
							|  |  |  |           livecheck_latest | 
					
						
							|  |  |  |         elsif repology_latest.is_a?(Version) && | 
					
						
							|  |  |  |               repology_latest > current_version_value && | 
					
						
							|  |  |  |               !loaded_formula_or_cask.livecheckable? && | 
					
						
							|  |  |  |               current_version_value != "latest" | 
					
						
							|  |  |  |           repology_latest | 
					
						
							|  |  |  |         end.presence | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Store old and new versions | 
					
						
							|  |  |  |         old_versions[version_key] = current_version_value | 
					
						
							|  |  |  |         new_versions[version_key] = new_version_value | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2021-02-17 00:09:02 +05:30
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2021-01-25 17:12:43 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     # If arm and intel versions are identical, as it happens with casks where only the checksums differ, | 
					
						
							|  |  |  |     # we consolidate them into a single version. | 
					
						
							|  |  |  |     if old_versions[:arm].present? && old_versions[:arm] == old_versions[:intel] | 
					
						
							|  |  |  |       old_versions = { general: old_versions[:arm] } | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     if new_versions[:arm].present? && new_versions[:arm] == new_versions[:intel] | 
					
						
							|  |  |  |       new_versions = { general: new_versions[:arm] } | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2022-01-12 17:31:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     multiple_versions = old_versions.values_at(:arm, :intel).all?(&:present?) || | 
					
						
							|  |  |  |                         new_versions.values_at(:arm, :intel).all?(&:present?) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     current_version = BumpVersionParser.new(general: old_versions[:general], | 
					
						
							|  |  |  |                                             arm:     old_versions[:arm], | 
					
						
							|  |  |  |                                             intel:   old_versions[:intel]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     begin | 
					
						
							|  |  |  |       new_version = BumpVersionParser.new(general: new_versions[:general], | 
					
						
							|  |  |  |                                           arm:     new_versions[:arm], | 
					
						
							|  |  |  |                                           intel:   new_versions[:intel]) | 
					
						
							|  |  |  |     rescue | 
					
						
							|  |  |  |       # When livecheck fails, we fail gracefully. Otherwise VersionParser will | 
					
						
							|  |  |  |       # raise a usage error | 
					
						
							|  |  |  |       new_version = BumpVersionParser.new(general: "unable to get versions") | 
					
						
							| 
									
										
										
										
											2021-01-25 17:12:43 +05:30
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     # We use the arm version for the pull request version. This is consistent | 
					
						
							|  |  |  |     # with the behavior of bump-cask-pr. | 
					
						
							|  |  |  |     pull_request_version = if multiple_versions && new_version.general != "unable to get versions" | 
					
						
							|  |  |  |       new_version.arm.to_s | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       new_version.general.to_s | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2022-01-12 17:31:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     open_pull_requests = if !args.no_pull_requests? && (args.named.present? || new_version.present?) | 
					
						
							| 
									
										
										
										
											2023-01-19 17:06:42 -08:00
										 |  |  |       retrieve_pull_requests(formula_or_cask, name, state: "open") | 
					
						
							|  |  |  |     end.presence | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     closed_pull_requests = if !args.no_pull_requests? && open_pull_requests.blank? && new_version.present? | 
					
						
							|  |  |  |       retrieve_pull_requests(formula_or_cask, name, state: "closed", version: pull_request_version) | 
					
						
							| 
									
										
										
										
											2022-01-12 17:31:55 +00:00
										 |  |  |     end.presence | 
					
						
							| 
									
										
										
										
											2020-07-31 10:52:37 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     VersionBumpInfo.new( | 
					
						
							|  |  |  |       type:                 type, | 
					
						
							|  |  |  |       multiple_versions:    multiple_versions, | 
					
						
							|  |  |  |       version_name:         version_name, | 
					
						
							|  |  |  |       current_version:      current_version, | 
					
						
							|  |  |  |       repology_latest:      repology_latest, | 
					
						
							|  |  |  |       new_version:          new_version, | 
					
						
							|  |  |  |       open_pull_requests:   open_pull_requests, | 
					
						
							|  |  |  |       closed_pull_requests: closed_pull_requests, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sig { | 
					
						
							|  |  |  |     params( | 
					
						
							|  |  |  |       formula_or_cask: T.any(Formula, Cask::Cask), | 
					
						
							|  |  |  |       name:            String, | 
					
						
							|  |  |  |       repositories:    T::Array[T.untyped], | 
					
						
							|  |  |  |       args:            T.untyped, | 
					
						
							|  |  |  |       ambiguous_cask:  T::Boolean, | 
					
						
							|  |  |  |     ).void | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   def retrieve_and_display_info_and_open_pr(formula_or_cask, name, repositories, args:, ambiguous_cask: false) | 
					
						
							|  |  |  |     version_info = retrieve_versions_by_arch(formula_or_cask: formula_or_cask, | 
					
						
							|  |  |  |                                              repositories:    repositories, | 
					
						
							|  |  |  |                                              args:            args, | 
					
						
							|  |  |  |                                              name:            name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     current_version = version_info.current_version | 
					
						
							|  |  |  |     new_version = version_info.new_version | 
					
						
							|  |  |  |     repology_latest = version_info.repology_latest | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Check if all versions are equal | 
					
						
							|  |  |  |     versions_equal = [:arm, :intel, :general].all? do |key| | 
					
						
							|  |  |  |       current_version.send(key) == new_version.send(key) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-12 17:31:55 +00:00
										 |  |  |     title_name = ambiguous_cask ? "#{name} (cask)" : name | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     title = if (repology_latest == current_version.general || !repology_latest.is_a?(Version)) && versions_equal | 
					
						
							| 
									
										
										
										
											2022-01-12 17:31:55 +00:00
										 |  |  |       "#{title_name} #{Tty.green}is up to date!#{Tty.reset}" | 
					
						
							| 
									
										
										
										
											2021-01-11 08:29:34 +05:30
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2022-01-12 17:31:55 +00:00
										 |  |  |       title_name | 
					
						
							| 
									
										
										
										
											2020-07-02 17:06:39 +00:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2021-01-11 08:29:34 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     # Conditionally format output based on type of formula_or_cask | 
					
						
							|  |  |  |     current_versions = if version_info.multiple_versions | 
					
						
							| 
									
										
										
										
											2023-08-03 09:58:59 -04:00
										 |  |  |       "arm:   #{current_version.arm}
 | 
					
						
							|  |  |  |                           intel: #{current_version.intel}" | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     else | 
					
						
							|  |  |  |       current_version.general | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     new_versions = if version_info.multiple_versions && new_version.arm && new_version.intel | 
					
						
							| 
									
										
										
										
											2023-08-03 09:58:59 -04:00
										 |  |  |       "arm:   #{new_version.arm}
 | 
					
						
							|  |  |  |                           intel: #{new_version.intel}" | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     else | 
					
						
							|  |  |  |       new_version.general | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     version_label = version_info.version_name | 
					
						
							|  |  |  |     open_pull_requests = version_info.open_pull_requests.presence | 
					
						
							|  |  |  |     closed_pull_requests = version_info.closed_pull_requests.presence | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-11 08:29:34 +05:30
										 |  |  |     ohai title | 
					
						
							| 
									
										
										
										
											2021-01-24 21:25:12 -05:00
										 |  |  |     puts <<~EOS | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |       Current #{version_label}  #{current_versions} | 
					
						
							|  |  |  |       Latest livecheck version: #{new_versions} | 
					
						
							| 
									
										
										
										
											2021-09-24 22:44:27 -04:00
										 |  |  |       Latest Repology version:  #{repology_latest} | 
					
						
							| 
									
										
										
										
											2023-09-13 17:59:11 -04:00
										 |  |  |     EOS | 
					
						
							|  |  |  |     puts <<~EOS unless args.no_pull_requests? | 
					
						
							| 
									
										
										
										
											2023-01-19 17:06:42 -08:00
										 |  |  |       Open pull requests:       #{open_pull_requests || "none"} | 
					
						
							|  |  |  |       Closed pull requests:     #{closed_pull_requests || "none"} | 
					
						
							| 
									
										
										
										
											2021-01-24 21:25:12 -05:00
										 |  |  |     EOS | 
					
						
							| 
									
										
										
										
											2022-01-12 17:31:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return unless args.open_pr? | 
					
						
							| 
									
										
										
										
											2022-02-20 17:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-05 16:20:35 +01:00
										 |  |  |     if repology_latest.is_a?(Version) && | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |        repology_latest > current_version.general && | 
					
						
							|  |  |  |        repology_latest > new_version.general && | 
					
						
							| 
									
										
										
										
											2022-11-30 08:30:05 +01:00
										 |  |  |        formula_or_cask.livecheckable? | 
					
						
							|  |  |  |       puts "#{title_name} was not bumped to the Repology version because it's livecheckable." | 
					
						
							| 
									
										
										
										
											2022-02-20 17:10:44 +00:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     if new_version.blank? || versions_equal || | 
					
						
							|  |  |  |        (!new_version.general.is_a?(Version) && !version_info.multiple_versions) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return if !args.force? && (open_pull_requests.present? || closed_pull_requests.present?) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     version_args = if version_info.multiple_versions | 
					
						
							|  |  |  |       %W[--version-arm=#{new_version.arm} --version-intel=#{new_version.intel}] | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       "--version=#{new_version.general}" | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2022-02-20 17:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     bump_cask_pr_args = [ | 
					
						
							|  |  |  |       "bump-#{version_info.type}-pr", | 
					
						
							|  |  |  |       name, | 
					
						
							|  |  |  |       *version_args, | 
					
						
							|  |  |  |       "--no-browse", | 
					
						
							|  |  |  |       "--message=Created by `brew bump`", | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     bump_cask_pr_args << "--force" if args.force? | 
					
						
							| 
									
										
										
										
											2022-01-12 17:31:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 07:52:36 -04:00
										 |  |  |     system HOMEBREW_BREW_FILE, *bump_cask_pr_args | 
					
						
							| 
									
										
										
										
											2020-06-29 09:47:19 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | end |