Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions Library/Homebrew/api/formula/formula_struct_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -247,18 +247,18 @@ def symbolize_dependency_hash(hash)
sig { params(deps_hash: DependencyHash).returns(T::Array[FormulaStruct::DependsOnArgs]) }
def process_dependencies(deps_hash)
no_linkage_names = deps_hash.fetch("no_linkage_dependencies", [])
dependencies = deps_hash.fetch("dependencies", []).map do |dep|
dependencies = deps_hash.fetch("dependencies", []).uniq.map do |dep|
next dep unless no_linkage_names.include?(dep)

{ dep => :no_linkage }
end
dependencies + [:build, :test, :recommended, :optional].filter_map do |type|
deps_hash["#{type}_dependencies"]&.map do |dep|
next { dep => type } unless no_linkage_names.include?(dep)
types = [:build, :test, :recommended, :optional]
dependencies + types.flat_map { |type| deps_hash.fetch("#{type}_dependencies", []) }.uniq.map do |dep|
tags = types.select { |type| deps_hash.fetch("#{type}_dependencies", []).include?(dep) }
tags << :no_linkage if no_linkage_names.include?(dep)

{ dep => [type, :no_linkage] }
end
end.flatten(1)
{ dep => (tags.one? ? tags.fetch(0) : tags) }
end
end

sig { params(requirements_array: RequirementsArray, spec: Symbol).returns(T::Array[FormulaStruct::DependsOnArgs]) }
Expand Down
51 changes: 51 additions & 0 deletions Library/Homebrew/test/api/formula/formula_struct_generator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,57 @@
expect(output).to eq dependency_args
end

describe "::process_dependencies" do
it "combines build and test tags into one dependency" do
expect(described_class.process_dependencies({
"build_dependencies" => ["foo"],
"test_dependencies" => ["foo"],
})).to eq [{ "foo" => [:build, :test] }]
end

it "appends no_linkage to combined dependency tags" do
expect(described_class.process_dependencies({
"build_dependencies" => ["foo"],
"test_dependencies" => ["foo"],
"no_linkage_dependencies" => ["foo"],
})).to eq [{ "foo" => [:build, :test, :no_linkage] }]
end

it "preserves runtime dependencies alongside combined build and test tags" do
expect(described_class.process_dependencies({
"dependencies" => ["foo"],
"build_dependencies" => ["foo"],
"test_dependencies" => ["foo"],
})).to eq ["foo", { "foo" => [:build, :test] }]
end

it "preserves no_linkage on runtime and tagged dependencies" do
expect(described_class.process_dependencies({
"dependencies" => ["foo"],
"test_dependencies" => ["foo"],
"no_linkage_dependencies" => ["foo"],
})).to eq [{ "foo" => :no_linkage }, { "foo" => [:test, :no_linkage] }]
end

it "preserves recommended and no_linkage tags" do
expect(described_class.process_dependencies({
"recommended_dependencies" => ["foo"],
"no_linkage_dependencies" => ["foo"],
})).to eq [{ "foo" => [:recommended, :no_linkage] }]
end

it "preserves first appearance and uses a fixed tag order" do
expect(described_class.process_dependencies({
"optional_dependencies" => ["multi", "optional"],
"recommended_dependencies" => ["multi", "recommended"],
"test_dependencies" => ["multi", "test"],
"build_dependencies" => ["build", "multi"],
"dependencies" => ["runtime"],
})).to eq ["runtime", { "build" => :build }, { "multi" => [:build, :test, :recommended, :optional] },
{ "test" => :test }, { "recommended" => :recommended }, { "optional" => :optional }]
end
end

specify "::process_uses_from_macos" do
output = described_class.process_uses_from_macos(symbolized_dependency_hash)
expect(output).to eq uses_from_macos_args
Expand Down
11 changes: 9 additions & 2 deletions Library/Homebrew/test/formulary_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,16 @@ class NoLinkageRoundTrip < Formula
license "MIT"
url "https://example.com/no-linkage-round-trip-1.0.tar.gz"
depends_on "shared" => :no_linkage
depends_on "runtime"

on_macos do
depends_on "platform" => :no_linkage
end
on_linux do
depends_on "platform"
end
depends_on "multi" => [:build, :test]
depends_on "runtime" => [:build, :test]

head do
url "https://example.com/no-linkage-round-trip.git", branch: "main"
Expand All @@ -210,15 +213,18 @@ class NoLinkageRoundTrip < Formula

before do
stub_const("OnSystem::VALID_OS_ARCH_TAGS", [mac_tag, linux_tag])
allow(CoreTap.instance).to receive(:git_head).and_return("0" * 40)
allow(Homebrew::API).to receive_messages(formula_names: [formula_name], formula_aliases: {},
formula_renames: {})
allow(CoreTap.instance).to receive_messages(git_head: "0" * 40, tap_migrations: {})
allow(CoreCaskTap.instance).to receive(:tap_migrations).and_return({})
allow(DevelopmentTools).to receive_messages(needs_libc_formula?: false, needs_compiler_formula?: false)
formula_path.dirname.mkpath
formula_path.write formula_content
end

test_each([:arm64_sequoia, :x86_64_linux].product([:stable, :head],
[:public, :internal])) do |(tag_symbol, spec, format)|
it "preserves #{spec} declarations through the #{format} API on #{tag_symbol}" do
it "preserves #{spec} declarations through the #{format} API on #{tag_symbol}", :aggregate_failures do
payload = json
tag = (tag_symbol == :arm64_sequoia) ? mac_tag : linux_tag
Homebrew::SimulateSystem.with_tag(tag) do
Expand All @@ -238,6 +244,7 @@ class NoLinkageRoundTrip < Formula

expect(restored.declared_deps.map { |dep| [dep.name, dep.tags] })
.to eq(source.declared_deps.map { |dep| [dep.name, dep.tags] })
expect(restored.to_hash.slice(*source.dependencies_hash.keys)).to eq(source.dependencies_hash)
end
end
end
Expand Down
Loading