| 
									
										
										
										
											2024-06-30 19:29:22 +01:00
										 |  |  | # typed: strict | 
					
						
							| 
									
										
										
										
											2023-02-22 15:33:16 +00:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:31:25 -07:00
										 |  |  | require "abstract_command" | 
					
						
							|  |  |  | require "fileutils" | 
					
						
							| 
									
										
										
										
											2023-02-22 15:33:16 +00:00
										 |  |  | require "formula" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2024-03-21 10:20:08 -07:00
										 |  |  |   module DevCmd | 
					
						
							|  |  |  |     class GenerateFormulaApi < AbstractCommand | 
					
						
							|  |  |  |       FORMULA_JSON_TEMPLATE = <<~EOS | 
					
						
							|  |  |  |         --- | 
					
						
							|  |  |  |         layout: formula_json | 
					
						
							|  |  |  |         --- | 
					
						
							|  |  |  |         {{ content }} | 
					
						
							| 
									
										
										
										
											2023-02-22 15:33:16 +00:00
										 |  |  |       EOS | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 10:20:08 -07:00
										 |  |  |       cmd_args do | 
					
						
							|  |  |  |         description <<~EOS | 
					
						
							|  |  |  |           Generate `homebrew/core` API data files for <#{HOMEBREW_API_WWW}>. | 
					
						
							|  |  |  |           The generated files are written to the current directory. | 
					
						
							|  |  |  |         EOS | 
					
						
							| 
									
										
										
										
											2025-06-03 13:01:49 -04:00
										 |  |  |         switch "-n", "--dry-run", | 
					
						
							|  |  |  |                description: "Generate API data without writing it to files." | 
					
						
							| 
									
										
										
										
											2023-02-22 15:33:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 10:20:08 -07:00
										 |  |  |         named_args :none | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-02-22 15:33:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 10:20:08 -07:00
										 |  |  |       sig { override.void } | 
					
						
							|  |  |  |       def run | 
					
						
							|  |  |  |         tap = CoreTap.instance | 
					
						
							|  |  |  |         raise TapUnavailableError, tap.name unless tap.installed? | 
					
						
							| 
									
										
										
										
											2023-02-22 15:33:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 10:20:08 -07:00
										 |  |  |         unless args.dry_run? | 
					
						
							| 
									
										
										
										
											2025-06-02 22:15:28 -04:00
										 |  |  |           directories = ["_data/formula", "api/formula", "formula", "api/internal"] | 
					
						
							| 
									
										
										
										
											2024-03-21 10:20:08 -07:00
										 |  |  |           FileUtils.rm_rf directories + ["_data/formula_canonical.json"] | 
					
						
							|  |  |  |           FileUtils.mkdir_p directories | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2023-02-22 15:33:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 10:20:08 -07:00
										 |  |  |         Homebrew.with_no_api_env do | 
					
						
							|  |  |  |           tap_migrations_json = JSON.dump(tap.tap_migrations) | 
					
						
							|  |  |  |           File.write("api/formula_tap_migrations.json", tap_migrations_json) unless args.dry_run? | 
					
						
							| 
									
										
										
										
											2023-02-22 15:33:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 10:20:08 -07:00
										 |  |  |           Formulary.enable_factory_cache! | 
					
						
							|  |  |  |           Formula.generating_hash! | 
					
						
							| 
									
										
										
										
											2023-07-14 02:04:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-02 22:15:28 -04:00
										 |  |  |           all_formulae = {} | 
					
						
							| 
									
										
										
										
											2025-05-15 00:03:25 -04:00
										 |  |  |           latest_macos = MacOSVersion.new((HOMEBREW_MACOS_NEWEST_UNSUPPORTED.to_i - 1).to_s).to_sym | 
					
						
							|  |  |  |           Homebrew::SimulateSystem.with(os: latest_macos, arch: :arm) do | 
					
						
							|  |  |  |             tap.formula_names.each do |name| | 
					
						
							|  |  |  |               formula = Formulary.factory(name) | 
					
						
							|  |  |  |               name = formula.name | 
					
						
							| 
									
										
										
										
											2025-06-02 22:15:28 -04:00
										 |  |  |               all_formulae[name] = formula.to_hash_with_variations | 
					
						
							|  |  |  |               json = JSON.pretty_generate(all_formulae[name]) | 
					
						
							| 
									
										
										
										
											2025-05-15 00:03:25 -04:00
										 |  |  |               html_template_name = html_template(name) | 
					
						
							| 
									
										
										
										
											2023-02-22 15:33:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 00:03:25 -04:00
										 |  |  |               unless args.dry_run? | 
					
						
							|  |  |  |                 File.write("_data/formula/#{name.tr("+", "_")}.json", "#{json}\n") | 
					
						
							|  |  |  |                 File.write("api/formula/#{name}.json", FORMULA_JSON_TEMPLATE) | 
					
						
							|  |  |  |                 File.write("formula/#{name}.html", html_template_name) | 
					
						
							|  |  |  |               end | 
					
						
							|  |  |  |             rescue | 
					
						
							|  |  |  |               onoe "Error while generating data for formula '#{name}'." | 
					
						
							|  |  |  |               raise | 
					
						
							| 
									
										
										
										
											2024-03-21 10:20:08 -07:00
										 |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2023-02-22 15:33:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 10:20:08 -07:00
										 |  |  |           canonical_json = JSON.pretty_generate(tap.formula_renames.merge(tap.alias_table)) | 
					
						
							|  |  |  |           File.write("_data/formula_canonical.json", "#{canonical_json}\n") unless args.dry_run? | 
					
						
							| 
									
										
										
										
											2025-06-02 22:15:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-03 11:57:17 -04:00
										 |  |  |           OnSystem::VALID_OS_ARCH_TAGS.each do |bottle_tag| | 
					
						
							| 
									
										
										
										
											2025-08-11 00:31:00 -04:00
										 |  |  |             aliases = {} | 
					
						
							|  |  |  |             renames = {} | 
					
						
							| 
									
										
										
										
											2025-06-05 03:15:44 -04:00
										 |  |  |             variation_formulae = all_formulae.to_h do |name, formula| | 
					
						
							| 
									
										
										
										
											2025-06-05 02:08:29 -04:00
										 |  |  |               formula = Homebrew::API.merge_variations(formula, bottle_tag:) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-11 00:31:00 -04:00
										 |  |  |               formula["aliases"]&.each do |alias_name| | 
					
						
							|  |  |  |                 aliases[alias_name] = name | 
					
						
							|  |  |  |               end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               formula["oldnames"]&.each do |oldname| | 
					
						
							|  |  |  |                 renames[oldname] = name | 
					
						
							|  |  |  |               end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-05 02:08:29 -04:00
										 |  |  |               version = Version.new(formula.dig("versions", "stable")) | 
					
						
							|  |  |  |               pkg_version = PkgVersion.new(version, formula["revision"]) | 
					
						
							|  |  |  |               rebuild = formula.dig("bottle", "stable", "rebuild") || 0
 | 
					
						
							| 
									
										
										
										
											2025-06-05 12:38:15 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |               bottle_collector = Utils::Bottles::Collector.new | 
					
						
							|  |  |  |               formula.dig("bottle", "stable", "files")&.each do |tag, data| | 
					
						
							|  |  |  |                 tag = Utils::Bottles::Tag.from_symbol(tag) | 
					
						
							|  |  |  |                 bottle_collector.add tag, checksum: Checksum.new(data["sha256"]), cellar: :any | 
					
						
							|  |  |  |               end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               sha256 = bottle_collector.specification_for(bottle_tag)&.checksum&.to_s | 
					
						
							| 
									
										
										
										
											2025-06-05 02:08:29 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-05 03:15:44 -04:00
										 |  |  |               [name, [pkg_version.to_s, rebuild, sha256]] | 
					
						
							| 
									
										
										
										
											2025-06-02 22:15:28 -04:00
										 |  |  |             end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-11 00:31:00 -04:00
										 |  |  |             json_contents = { | 
					
						
							|  |  |  |               formulae:       variation_formulae, | 
					
						
							|  |  |  |               aliases:        aliases, | 
					
						
							|  |  |  |               renames:        renames, | 
					
						
							|  |  |  |               tap_migrations: CoreTap.instance.tap_migrations, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             File.write("api/internal/formula.#{bottle_tag}.json", JSON.generate(json_contents)) unless args.dry_run? | 
					
						
							| 
									
										
										
										
											2025-06-02 22:15:28 -04:00
										 |  |  |           end | 
					
						
							| 
									
										
										
										
											2023-06-22 16:53:46 +01:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2023-05-13 14:49:33 -07:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-02-22 15:33:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 10:20:08 -07:00
										 |  |  |       private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-30 19:29:22 +01:00
										 |  |  |       sig { params(title: String).returns(String) } | 
					
						
							| 
									
										
										
										
											2024-03-21 10:20:08 -07:00
										 |  |  |       def html_template(title) | 
					
						
							|  |  |  |         <<~EOS | 
					
						
							|  |  |  |           --- | 
					
						
							| 
									
										
										
										
											2024-04-10 04:51:23 +01:00
										 |  |  |           title: '#{title}' | 
					
						
							| 
									
										
										
										
											2024-03-21 10:20:08 -07:00
										 |  |  |           layout: formula | 
					
						
							|  |  |  |           redirect_from: /formula-linux/#{title} | 
					
						
							|  |  |  |           --- | 
					
						
							|  |  |  |           {{ content }} | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-06-22 16:53:46 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2023-02-22 15:33:16 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | end |