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
This commit is contained in:
apainintheneck 2024-04-30 23:12:07 -07:00
parent 541305ae98
commit 6ad02b8e34
4 changed files with 189 additions and 12 deletions

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -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