| 
									
										
										
										
											2020-10-10 14:16:11 +02:00
										 |  |  | # typed: false | 
					
						
							| 
									
										
										
										
											2020-04-20 10:17:42 +02:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | require "cli/parser" | 
					
						
							| 
									
										
										
										
											2021-02-21 22:12:17 -08:00
										 |  |  | require "archive" | 
					
						
							| 
									
										
										
										
											2020-04-20 10:17:42 +02:00
										 |  |  | require "bintray" | 
					
						
							| 
									
										
										
										
											2021-03-11 15:15:35 +00:00
										 |  |  | require "github_packages" | 
					
						
							| 
									
										
										
										
											2021-03-10 16:08:45 +00:00
										 |  |  | require "github_releases" | 
					
						
							| 
									
										
										
										
											2020-04-20 10:17:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   extend T::Sig | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-20 10:17:42 +02:00
										 |  |  |   module_function | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   sig { returns(CLI::Parser) } | 
					
						
							| 
									
										
										
										
											2020-04-20 10:17:42 +02:00
										 |  |  |   def pr_upload_args | 
					
						
							|  |  |  |     Homebrew::CLI::Parser.new do | 
					
						
							| 
									
										
										
										
											2021-01-15 15:04:02 -05:00
										 |  |  |       description <<~EOS | 
					
						
							| 
									
										
										
										
											2021-03-10 16:08:45 +00:00
										 |  |  |         Apply the bottle commit and publish bottles to a host. | 
					
						
							| 
									
										
										
										
											2020-04-20 10:17:42 +02:00
										 |  |  |       EOS | 
					
						
							|  |  |  |       switch "--no-publish", | 
					
						
							|  |  |  |              description: "Apply the bottle commit and upload the bottles, but don't publish them." | 
					
						
							| 
									
										
										
										
											2020-07-06 17:41:07 +02:00
										 |  |  |       switch "--keep-old", | 
					
						
							|  |  |  |              description: "If the formula specifies a rebuild version, " \ | 
					
						
							|  |  |  |                           "attempt to preserve its value in the generated DSL." | 
					
						
							| 
									
										
										
										
											2020-06-25 12:01:52 -04:00
										 |  |  |       switch "-n", "--dry-run", | 
					
						
							| 
									
										
										
										
											2020-04-20 10:17:42 +02:00
										 |  |  |              description: "Print what would be done rather than doing it." | 
					
						
							| 
									
										
										
										
											2020-10-03 12:33:47 -04:00
										 |  |  |       switch "--no-commit", | 
					
						
							|  |  |  |              description: "Do not generate a new commit before uploading." | 
					
						
							| 
									
										
										
										
											2020-07-02 00:11:55 +10:00
										 |  |  |       switch "--warn-on-upload-failure", | 
					
						
							|  |  |  |              description: "Warn instead of raising an error if the bottle upload fails. "\ | 
					
						
							|  |  |  |                           "Useful for repairing bottle uploads that previously failed." | 
					
						
							| 
									
										
										
										
											2021-02-21 22:12:17 -08:00
										 |  |  |       flag   "--archive-item=", | 
					
						
							| 
									
										
										
										
											2021-02-23 11:22:55 -08:00
										 |  |  |              description: "Upload to the specified Internet Archive item (default: `homebrew`)." | 
					
						
							| 
									
										
										
										
											2020-06-25 12:01:52 -04:00
										 |  |  |       flag   "--bintray-org=", | 
					
						
							|  |  |  |              description: "Upload to the specified Bintray organisation (default: `homebrew`)." | 
					
						
							| 
									
										
										
										
											2021-03-11 15:15:35 +00:00
										 |  |  |       flag   "--github-org=", | 
					
						
							|  |  |  |              description: "Upload to the specified GitHub organisation's GitHub Packages (default: `homebrew`)." | 
					
						
							| 
									
										
										
										
											2020-06-25 12:01:52 -04:00
										 |  |  |       flag   "--root-url=", | 
					
						
							|  |  |  |              description: "Use the specified <URL> as the root of the bottle's URL instead of Homebrew's default." | 
					
						
							| 
									
										
										
										
											2021-01-10 14:26:40 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |       named_args :none | 
					
						
							| 
									
										
										
										
											2020-04-20 10:17:42 +02:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-20 14:21:55 +02:00
										 |  |  |   def check_bottled_formulae(bottles_hash) | 
					
						
							|  |  |  |     bottles_hash.each do |name, bottle_hash| | 
					
						
							|  |  |  |       formula_path = HOMEBREW_REPOSITORY/bottle_hash["formula"]["path"] | 
					
						
							| 
									
										
										
										
											2020-07-29 09:22:09 +02:00
										 |  |  |       formula_version = Formulary.factory(formula_path).pkg_version | 
					
						
							| 
									
										
										
										
											2020-08-20 14:21:55 +02:00
										 |  |  |       bottle_version = PkgVersion.parse bottle_hash["formula"]["pkg_version"] | 
					
						
							| 
									
										
										
										
											2020-07-26 21:46:37 +10:00
										 |  |  |       next if formula_version == bottle_version | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       odie "Bottles are for #{name} #{bottle_version} but formula is version #{formula_version}!" | 
					
						
							| 
									
										
										
										
											2020-07-26 19:03:02 +10:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-10 16:08:45 +00:00
										 |  |  |   def internet_archive?(bottles_hash) | 
					
						
							|  |  |  |     @internet_archive ||= bottles_hash.values.all? do |bottle_hash| | 
					
						
							|  |  |  |       bottle_hash["bottle"]["root_url"].start_with? "#{Archive::URL_PREFIX}/" | 
					
						
							| 
									
										
										
										
											2021-02-21 22:12:17 -08:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def bintray?(bottles_hash) | 
					
						
							|  |  |  |     @bintray ||= bottles_hash.values.all? do |bottle_hash| | 
					
						
							| 
									
										
										
										
											2021-03-10 16:08:45 +00:00
										 |  |  |       bottle_hash["bottle"]["root_url"].match? Bintray::URL_REGEX | 
					
						
							| 
									
										
										
										
											2021-02-21 22:12:17 -08:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-20 14:21:55 +02:00
										 |  |  |   def github_releases?(bottles_hash) | 
					
						
							|  |  |  |     @github_releases ||= bottles_hash.values.all? do |bottle_hash| | 
					
						
							|  |  |  |       root_url = bottle_hash["bottle"]["root_url"] | 
					
						
							| 
									
										
										
										
											2021-03-10 16:08:45 +00:00
										 |  |  |       url_match = root_url.match GitHubReleases::URL_REGEX | 
					
						
							| 
									
										
										
										
											2020-08-20 14:21:55 +02:00
										 |  |  |       _, _, _, tag = *url_match | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       tag | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-11 15:15:35 +00:00
										 |  |  |   def github_packages?(bottles_hash) | 
					
						
							|  |  |  |     @github_packages ||= bottles_hash.values.all? do |bottle_hash| | 
					
						
							|  |  |  |       bottle_hash["bottle"]["root_url"].match? GitHubPackages::URL_REGEX | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-20 10:17:42 +02:00
										 |  |  |   def pr_upload | 
					
						
							| 
									
										
										
										
											2020-07-23 01:22:25 +02:00
										 |  |  |     args = pr_upload_args.parse | 
					
						
							| 
									
										
										
										
											2020-04-20 10:17:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-12 22:55:50 +01:00
										 |  |  |     json_files = Dir["*.bottle.json"] | 
					
						
							|  |  |  |     odie "No bottle JSON files found in the current working directory" if json_files.empty? | 
					
						
							| 
									
										
										
										
											2020-07-26 19:03:02 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-20 14:21:55 +02:00
										 |  |  |     bottles_hash = json_files.reduce({}) do |hash, json_file| | 
					
						
							|  |  |  |       hash.deep_merge(JSON.parse(IO.read(json_file))) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-20 10:31:59 -07:00
										 |  |  |     bottle_args = ["bottle", "--merge", "--write"] | 
					
						
							| 
									
										
										
										
											2020-06-22 00:21:22 +10:00
										 |  |  |     bottle_args << "--verbose" if args.verbose? | 
					
						
							|  |  |  |     bottle_args << "--debug" if args.debug? | 
					
						
							| 
									
										
										
										
											2020-07-06 17:41:07 +02:00
										 |  |  |     bottle_args << "--keep-old" if args.keep_old? | 
					
						
							| 
									
										
										
										
											2020-04-20 10:31:59 -07:00
										 |  |  |     bottle_args << "--root-url=#{args.root_url}" if args.root_url | 
					
						
							| 
									
										
										
										
											2020-10-03 12:33:47 -04:00
										 |  |  |     bottle_args << "--no-commit" if args.no_commit? | 
					
						
							| 
									
										
										
										
											2020-07-26 19:03:02 +10:00
										 |  |  |     bottle_args += json_files | 
					
						
							| 
									
										
										
										
											2020-04-20 10:31:59 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-20 10:17:42 +02:00
										 |  |  |     if args.dry_run? | 
					
						
							| 
									
										
										
										
											2021-02-21 22:12:17 -08:00
										 |  |  |       service = | 
					
						
							| 
									
										
										
										
											2021-03-10 16:08:45 +00:00
										 |  |  |         if internet_archive?(bottles_hash) | 
					
						
							| 
									
										
										
										
											2021-02-23 11:22:55 -08:00
										 |  |  |           "Internet Archive" | 
					
						
							| 
									
										
										
										
											2021-02-21 22:12:17 -08:00
										 |  |  |         elsif bintray?(bottles_hash) | 
					
						
							|  |  |  |           "Bintray" | 
					
						
							|  |  |  |         elsif github_releases?(bottles_hash) | 
					
						
							|  |  |  |           "GitHub Releases" | 
					
						
							| 
									
										
										
										
											2021-03-11 15:15:35 +00:00
										 |  |  |         elsif github_packages?(bottles_hash) | 
					
						
							|  |  |  |           "GitHub Packages" | 
					
						
							| 
									
										
										
										
											2021-02-21 22:12:17 -08:00
										 |  |  |         else | 
					
						
							|  |  |  |           odie "Service specified by root_url is not recognized" | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2021-01-24 21:25:12 -05:00
										 |  |  |       puts <<~EOS | 
					
						
							|  |  |  |         brew #{bottle_args.join " "} | 
					
						
							|  |  |  |         Upload bottles described by these JSON files to #{service}: | 
					
						
							|  |  |  |           #{json_files.join("\n  ")} | 
					
						
							|  |  |  |       EOS | 
					
						
							| 
									
										
										
										
											2020-08-20 14:21:55 +02:00
										 |  |  |       return | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     check_bottled_formulae(bottles_hash) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     safe_system HOMEBREW_BREW_FILE, *bottle_args | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-09 09:59:59 +00:00
										 |  |  |     # Check the bottle commits did not break `brew audit` | 
					
						
							|  |  |  |     unless args.no_commit? | 
					
						
							| 
									
										
										
										
											2020-11-09 13:49:40 +00:00
										 |  |  |       audit_args = ["audit", "--skip-style"] | 
					
						
							| 
									
										
										
										
											2020-11-09 09:59:59 +00:00
										 |  |  |       audit_args << "--verbose" if args.verbose? | 
					
						
							|  |  |  |       audit_args << "--debug" if args.debug? | 
					
						
							| 
									
										
										
										
											2020-11-12 20:04:20 +01:00
										 |  |  |       audit_args += bottles_hash.keys | 
					
						
							| 
									
										
										
										
											2020-11-09 09:59:59 +00:00
										 |  |  |       safe_system HOMEBREW_BREW_FILE, *audit_args | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-10 16:08:45 +00:00
										 |  |  |     if internet_archive?(bottles_hash) | 
					
						
							| 
									
										
										
										
											2021-02-21 22:12:17 -08:00
										 |  |  |       archive_item = args.archive_item || "homebrew" | 
					
						
							|  |  |  |       archive = Archive.new(item: archive_item) | 
					
						
							|  |  |  |       archive.upload_bottles(bottles_hash, | 
					
						
							|  |  |  |                              warn_on_error: args.warn_on_upload_failure?) | 
					
						
							|  |  |  |     elsif bintray?(bottles_hash) | 
					
						
							|  |  |  |       bintray_org = args.bintray_org || "homebrew" | 
					
						
							|  |  |  |       bintray = Bintray.new(org: bintray_org) | 
					
						
							|  |  |  |       bintray.upload_bottles(bottles_hash, | 
					
						
							|  |  |  |                              publish_package: !args.no_publish?, | 
					
						
							|  |  |  |                              warn_on_error:   args.warn_on_upload_failure?) | 
					
						
							|  |  |  |     elsif github_releases?(bottles_hash) | 
					
						
							| 
									
										
										
										
											2021-03-10 16:08:45 +00:00
										 |  |  |       github_releases = GitHubReleases.new | 
					
						
							|  |  |  |       github_releases.upload_bottles(bottles_hash) | 
					
						
							| 
									
										
										
										
											2021-03-11 15:15:35 +00:00
										 |  |  |     elsif github_packages?(bottles_hash) | 
					
						
							|  |  |  |       github_org = args.github_org || "homebrew" | 
					
						
							|  |  |  |       github_packages = GitHubPackages.new(org: github_org) | 
					
						
							|  |  |  |       github_packages.upload_bottles(bottles_hash) | 
					
						
							| 
									
										
										
										
											2020-04-20 10:17:42 +02:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2021-02-21 22:12:17 -08:00
										 |  |  |       odie "Service specified by root_url is not recognized" | 
					
						
							| 
									
										
										
										
											2020-04-20 10:17:42 +02:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |