Merge pull request #17153 from apainintheneck/new-formula-json-dependencies-format

New formula internal json v3 dependencies format
This commit is contained in:
Mike McQuaid 2024-05-01 08:45:18 +01:00 committed by GitHub
commit 7c0b989740
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 289 additions and 54 deletions

View File

@ -2366,13 +2366,6 @@ class Formula
"ruby_source_sha256" => ruby_source_checksum&.hexdigest,
}
dep_hash = dependencies_hash
.except("recommended_dependencies", "optional_dependencies")
.transform_values(&:presence)
.compact
api_hash.merge!(dep_hash)
# Exclude default values.
api_hash["revision"] = revision unless revision.zero?
api_hash["version_scheme"] = version_scheme unless version_scheme.zero?
@ -2394,6 +2387,14 @@ class Formula
api_hash["versioned_formulae"] = versioned_formulae_list.map(&:name)
end
if (dependencies = internal_dependencies_hash(:stable).presence)
api_hash["dependencies"] = dependencies
end
if (head_dependencies = internal_dependencies_hash(:head).presence)
api_hash["head_dependencies"] = head_dependencies
end
if (requirements_array = serialized_requirements.presence)
api_hash["requirements"] = requirements_array
end
@ -2558,7 +2559,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 = {}
@ -2613,6 +2618,24 @@ class Formula
hash
end
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))
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?
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
def on_system_blocks_exist?
self.class.on_system_blocks_exist? || @on_system_blocks_exist
end

View File

@ -211,7 +211,39 @@ module Formulary
end
end
add_deps = lambda do |spec|
add_deps = if Homebrew::API.internal_json_v3?
lambda do |deps|
T.bind(self, SoftwareSpec)
deps&.each do |name, info|
tags = case info&.dig("tags")
in Array => tag_list
tag_list.map(&:to_sym)
in String => tag
tag.to_sym
else
nil
end
if info&.key?("uses_from_macos")
bounds = info["uses_from_macos"] || {}
bounds.deep_transform_keys!(&:to_sym)
bounds.deep_transform_values!(&:to_sym)
if tags
uses_from_macos name => tags, **bounds
else
uses_from_macos name, **bounds
end
elsif tags
depends_on name => tags
else
depends_on name
end
end
end
else
lambda do |spec|
T.bind(self, SoftwareSpec)
dep_json = json_formula.fetch("#{spec}_dependencies", json_formula)
@ -246,6 +278,7 @@ module Formulary
end
end
end
end
klass = Class.new(::Formula) do
@loaded_from_api = true
@ -267,7 +300,11 @@ module Formulary
version Homebrew::API.internal_json_v3? ? json_formula["version"] : json_formula["versions"]["stable"]
sha256 urls_stable["checksum"] if urls_stable["checksum"].present?
if Homebrew::API.internal_json_v3?
instance_exec(json_formula["dependencies"], &add_deps)
else
instance_exec(:stable, &add_deps)
end
requirements[:stable]&.each do |req|
depends_on req
@ -283,7 +320,11 @@ module Formulary
}.compact
url urls_head["url"], **url_spec
if Homebrew::API.internal_json_v3?
instance_exec(json_formula["head_dependencies"], &add_deps)
else
instance_exec(:head, &add_deps)
end
requirements[:head]&.each do |req|
depends_on req

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

@ -32,9 +32,6 @@
"post_install_defined": false,
"ruby_source_path": "Formula/f/fennel.rb",
"ruby_source_sha256": "5856e655fd1cea11496d67bc27fb14fee5cfbdea63c697c3773c7f247581197d",
"dependencies": [
"lua"
],
"version": "1.4.0",
"bottle": {
"files": {
@ -43,6 +40,108 @@
"sha256": "f46028597883cbc38864c61bd3fa402da9cb90ce97415d51a7b5279bc17f7bd0"
}
}
},
"dependencies": {
"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": {
@ -59,25 +158,6 @@
"post_install_defined": false,
"ruby_source_path": "Formula/p/ponyc.rb",
"ruby_source_sha256": "81d51c25d18710191beb62f9f380bae3d878aad815a65ec1ee2a3b132c1fadb3",
"build_dependencies": [
"cmake",
"python@3.12"
],
"uses_from_macos": [
{
"llvm": [
"build",
"test"
]
},
"zlib"
],
"uses_from_macos_bounds": [
{
},
{
}
],
"version": "0.58.1",
"bottle": {
"files": {
@ -110,6 +190,28 @@
"sha256": "ab49318d75eed3ee932c8e5add22f252ec0c852aad94945022877f926e93899f"
}
}
},
"dependencies": {
"cmake": {
"tags": [
"build"
]
},
"python@3.12": {
"tags": [
"build"
]
},
"llvm": {
"tags": [
"build",
"test"
],
"uses_from_macos": null
},
"zlib": {
"uses_from_macos": null
}
}
}
}

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