From 6ad02b8e340e163ce90beccb33d0f297d96e7b03 Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Tue, 30 Apr 2024 23:12:07 -0700 Subject: [PATCH] formula: internal json v3 dependencies: address feedback - rename #dependencies_list to #internal_dependencies_hash - the initial implementation returned an array but now it doesn't - simplify usage of #tap in #internal_dependencies_hash - remove safe navigation operator usages in #internal_dependencies_hash - better document why implicit dependencies are not included in the API JSON - add new test fixture formula to better test generation of uses from macos bounds with the new internal json format --- Library/Homebrew/formula.rb | 31 +++--- .../api/internal_tap_json/formula_spec.rb | 26 ++++- .../internal_tap_json/homebrew-core.json | 99 +++++++++++++++++++ .../homebrew-core/Formula/i/inko.rb | 45 +++++++++ 4 files changed, 189 insertions(+), 12 deletions(-) create mode 100644 Library/Homebrew/test/support/fixtures/internal_tap_json/homebrew-core/Formula/i/inko.rb diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index c70f79e923..e7b519aa27 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -2382,11 +2382,11 @@ class Formula api_hash["versioned_formulae"] = versioned_formulae_list.map(&:name) end - if (dependencies = dependencies_list(:stable).presence) + if (dependencies = internal_dependencies_hash(:stable).presence) api_hash["dependencies"] = dependencies end - if (head_dependencies = dependencies_list(:head).presence) + if (head_dependencies = internal_dependencies_hash(:head).presence) api_hash["head_dependencies"] = head_dependencies end @@ -2554,7 +2554,11 @@ class Formula dependencies = self.class.spec_syms.to_h do |sym| [sym, send(sym)&.declared_deps] end - dependencies.transform_values! { |deps| deps&.reject(&:implicit?) } # Remove all implicit deps from all lists + + # Implicit dependencies are only needed when installing from source + # since they are only used to download and unpack source files. + # @see DependencyCollector + dependencies.transform_values! { |deps| deps&.reject(&:implicit?) } hash = {} @@ -2609,16 +2613,21 @@ class Formula hash end - def dependencies_list(spec_symbol) - return if spec_symbol != :stable && spec_symbol != :head + def internal_dependencies_hash(spec_symbol) + raise ArgumentError, "Unsupported spec: #{spec_symbol}" unless [:stable, :head].include?(spec_symbol) + return unless (spec = public_send(spec_symbol)) - send(spec_symbol)&.declared_deps&.each_with_object({}) do |dep, dep_hash| - next if dep.implicit? # Remove all implicit deps + spec.declared_deps.each_with_object({}) do |dep, dep_hash| + # Implicit dependencies are only needed when installing from source + # since they are only used to download and unpack source files. + # @see DependencyCollector + next if dep.implicit? - dep_hash[dep.name] = {}.tap do |info| - info[:tags] = dep.tags if dep.tags.present? - info[:uses_from_macos] = dep.bounds.presence if dep.uses_from_macos? - end.presence + metadata_hash = {} + metadata_hash[:tags] = dep.tags if dep.tags.present? + metadata_hash[:uses_from_macos] = dep.bounds.presence if dep.uses_from_macos? + + dep_hash[dep.name] = metadata_hash.presence end end diff --git a/Library/Homebrew/test/api/internal_tap_json/formula_spec.rb b/Library/Homebrew/test/api/internal_tap_json/formula_spec.rb index b6a495922c..2cfe78426d 100644 --- a/Library/Homebrew/test/api/internal_tap_json/formula_spec.rb +++ b/Library/Homebrew/test/api/internal_tap_json/formula_spec.rb @@ -107,7 +107,6 @@ RSpec.describe "Internal Tap JSON -- Formula", type: :system do "ruby_source_path" => "Formula/p/ponyc.rb", "tap" => "homebrew/core", "tap_git_head" => tap_git_head, - # TODO: improve this API before we ship internal API v3 to users "uses_from_macos" => [{ "llvm"=>[:build, :test] }, "zlib"], "uses_from_macos_bounds" => [{}, {}], "versions" => { "bottle"=>true, "head"=>nil, "stable"=>"0.58.1" }, @@ -117,6 +116,26 @@ RSpec.describe "Internal Tap JSON -- Formula", type: :system do } end + let(:inko_metadata) do + { + "desc" => "Safe and concurrent object-oriented programming language", + "full_name" => "inko", + "homepage" => "https://inko-lang.org/", + "license" => "MPL-2.0", + "name" => "inko", + "ruby_source_path" => "Formula/i/inko.rb", + "tap" => "homebrew/core", + "tap_git_head" => tap_git_head, + "dependencies" => ["llvm@15", "zstd"], + "uses_from_macos" => ["libffi", "ruby"], + "uses_from_macos_bounds" => [{ since: :catalina }, { since: :sierra }], + "versions" => { "bottle"=>true, "head"=>"HEAD", "stable"=>"0.14.0" }, + "ruby_source_checksum" => { + "sha256" => "843f6b5652483b971c83876201d68c95d5f32e67e55a75ac7c95d68c4350aa1c", + }, + } + end + it "loads fennel" do fennel = Formulary.factory("fennel") expect(fennel.to_hash).to include(**fennel_metadata) @@ -141,6 +160,11 @@ RSpec.describe "Internal Tap JSON -- Formula", type: :system do ponyc = Formulary.factory("ponyc-lang") expect(ponyc.to_hash).to include(**ponyc_metadata) end + + it "loads ink" do + inko = Formulary.factory("inko") + expect(inko.to_hash).to include(**inko_metadata) + end end end end diff --git a/Library/Homebrew/test/support/fixtures/internal_tap_json/homebrew-core.json b/Library/Homebrew/test/support/fixtures/internal_tap_json/homebrew-core.json index 9074219a04..b704184417 100644 --- a/Library/Homebrew/test/support/fixtures/internal_tap_json/homebrew-core.json +++ b/Library/Homebrew/test/support/fixtures/internal_tap_json/homebrew-core.json @@ -45,6 +45,105 @@ "lua": null } }, + "inko": { + "desc": "Safe and concurrent object-oriented programming language", + "license": "MPL-2.0", + "homepage": "https://inko-lang.org/", + "urls": { + "stable": { + "url": "https://releases.inko-lang.org/0.14.0.tar.gz", + "checksum": "4e2c82911d6026f76c42ccc164dc45b1b5e331db2e9557460d9319d682668e65" + }, + "head": { + "url": "https://github.com/inko-lang/inko.git", + "branch": "main" + } + }, + "post_install_defined": false, + "ruby_source_path": "Formula/i/inko.rb", + "ruby_source_sha256": "843f6b5652483b971c83876201d68c95d5f32e67e55a75ac7c95d68c4350aa1c", + "version": "0.14.0", + "bottle": { + "files": { + "arm64_sonoma": { + "cellar": ":any", + "sha256": "f6ff66fdfb3aac69263c32a8a29d13e9d28a80ae33807f34460e55d8c1b228c6" + }, + "arm64_ventura": { + "cellar": ":any", + "sha256": "be59d916d29d85bb8bc4474eb1c7d42a56236835c3c21b0e36fb9e9df0a25e6e" + }, + "arm64_monterey": { + "cellar": ":any", + "sha256": "9522c1f89b997dedaa3167ce4dbfa4a2d8c660acddecd32a99a515922e851b52" + }, + "sonoma": { + "cellar": ":any", + "sha256": "8e32d823ce9712ae2d5a2b9cbe0c9b727223098b3e66b003da087032be9f6818" + }, + "ventura": { + "cellar": ":any", + "sha256": "178865db1e2b60b4085a2465e8a3879794030a6d22c99b58c95e4bdf5418ef1b" + }, + "monterey": { + "cellar": ":any", + "sha256": "6ef924939c42d7bb2ec4e0d65cf293147a593f829619928d2580b419ec19b26c" + }, + "x86_64_linux": { + "cellar": ":any_skip_relocation", + "sha256": "14a02c119990d6a17062290439ac74e6667b41dcb90b18cd90b36d2a09715e10" + } + } + }, + "dependencies": { + "coreutils": { + "tags": [ + "build" + ] + }, + "rust": { + "tags": [ + "build" + ] + }, + "llvm@15": null, + "zstd": null, + "libffi": { + "uses_from_macos": { + "since": "catalina" + } + }, + "ruby": { + "uses_from_macos": { + "since": "sierra" + } + } + }, + "head_dependencies": { + "coreutils": { + "tags": [ + "build" + ] + }, + "rust": { + "tags": [ + "build" + ] + }, + "llvm@15": null, + "zstd": null, + "libffi": { + "uses_from_macos": { + "since": "catalina" + } + }, + "ruby": { + "uses_from_macos": { + "since": "sierra" + } + } + } + }, "ponyc": { "desc": "Object-oriented, actor-model, capabilities-secure programming language", "license": "BSD-2-Clause", diff --git a/Library/Homebrew/test/support/fixtures/internal_tap_json/homebrew-core/Formula/i/inko.rb b/Library/Homebrew/test/support/fixtures/internal_tap_json/homebrew-core/Formula/i/inko.rb new file mode 100644 index 0000000000..9f56b2d0f4 --- /dev/null +++ b/Library/Homebrew/test/support/fixtures/internal_tap_json/homebrew-core/Formula/i/inko.rb @@ -0,0 +1,45 @@ +class Inko < Formula + desc "Safe and concurrent object-oriented programming language" + homepage "https://inko-lang.org/" + url "https://releases.inko-lang.org/0.14.0.tar.gz" + sha256 "4e2c82911d6026f76c42ccc164dc45b1b5e331db2e9557460d9319d682668e65" + license "MPL-2.0" + head "https://github.com/inko-lang/inko.git", branch: "main" + + bottle do + sha256 cellar: :any, arm64_sonoma: "f6ff66fdfb3aac69263c32a8a29d13e9d28a80ae33807f34460e55d8c1b228c6" + sha256 cellar: :any, arm64_ventura: "be59d916d29d85bb8bc4474eb1c7d42a56236835c3c21b0e36fb9e9df0a25e6e" + sha256 cellar: :any, arm64_monterey: "9522c1f89b997dedaa3167ce4dbfa4a2d8c660acddecd32a99a515922e851b52" + sha256 cellar: :any, sonoma: "8e32d823ce9712ae2d5a2b9cbe0c9b727223098b3e66b003da087032be9f6818" + sha256 cellar: :any, ventura: "178865db1e2b60b4085a2465e8a3879794030a6d22c99b58c95e4bdf5418ef1b" + sha256 cellar: :any, monterey: "6ef924939c42d7bb2ec4e0d65cf293147a593f829619928d2580b419ec19b26c" + sha256 cellar: :any_skip_relocation, x86_64_linux: "14a02c119990d6a17062290439ac74e6667b41dcb90b18cd90b36d2a09715e10" + end + + depends_on "coreutils" => :build + depends_on "rust" => :build + depends_on "llvm@15" + depends_on "zstd" + + uses_from_macos "libffi", since: :catalina + uses_from_macos "ruby", since: :sierra + + def install + ENV.prepend_path "PATH", Formula["coreutils"].opt_libexec/"gnubin" + system "make", "build", "PREFIX=#{prefix}" + system "make", "install", "PREFIX=#{prefix}" + end + + test do + (testpath/"hello.inko").write <<~EOS + import std.stdio.STDOUT + + class async Main { + fn async main { + STDOUT.new.print('Hello, world!') + } + } + EOS + assert_equal "Hello, world!\n", shell_output("#{bin}/inko run hello.inko") + end +end