Skip to content

Commit

Permalink
Merge pull request #14518 from Bo98/api-license
Browse files Browse the repository at this point in the history
Fix license handling for API formulae
  • Loading branch information
MikeMcQuaid committed Feb 6, 2023
2 parents bdc22fe + 83b23e6 commit 96cf41e
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Library/Homebrew/formulary.rb
Expand Up @@ -151,7 +151,7 @@ def self.load_formula_from_api(name, flags:)
klass = Class.new(::Formula) do
desc json_formula["desc"]
homepage json_formula["homepage"]
license json_formula["license"]
license SPDX.string_to_license_expression(json_formula["license"])
revision json_formula["revision"]
version_scheme json_formula["version_scheme"]

Expand Down
25 changes: 25 additions & 0 deletions Library/Homebrew/test/utils/spdx_spec.rb
Expand Up @@ -217,6 +217,31 @@
end
end

describe ".string_to_license_expression" do
it "returns the correct result for 'and', 'or' and 'with'" do
expr_string = "Apache-2.0 and (Apache-2.0 with LLVM-exception) and (MIT or NCSA)"
expect(described_class.string_to_license_expression(expr_string)).to eq({
all_of: [
"Apache-2.0",
{ "Apache-2.0" => { with: "LLVM-exception" } },
{ any_of: ["MIT", "NCSA"] },
],
})
end

it "handles nested brackets" do
expect(described_class.string_to_license_expression("A and (B or (C and D))")).to eq({
all_of: [
"A",
any_of: [
"B",
all_of: ["C", "D"],
],
],
})
end
end

describe ".license_version_info" do
it "returns license without version" do
expect(described_class.license_version_info("MIT")).to eq ["MIT"]
Expand Down
34 changes: 34 additions & 0 deletions Library/Homebrew/utils/spdx.rb
Expand Up @@ -129,6 +129,40 @@ def license_expression_to_string(license_expression, bracket: false, hash_type:
end
end

def string_to_license_expression(string)
return if string.blank?

result = string
result_type = nil

and_parts = string.split(/ and (?![^(]*\))/)
if and_parts.length > 1
result = and_parts
result_type = :all_of
else
or_parts = string.split(/ or (?![^(]*\))/)
if or_parts.length > 1
result = or_parts
result_type = :any_of
end
end

if result_type
result.map! do |part|
part = part[1..-2] if part[0] == "(" && part[-1] == ")"
string_to_license_expression(part)
end
{ result_type => result }
else
with_parts = string.split(" with ", 2)
if with_parts.length > 1
{ with_parts.first => { with: with_parts.second } }
else
result
end
end
end

def license_version_info(license)
return [license] if ALLOWED_LICENSE_SYMBOLS.include? license

Expand Down

0 comments on commit 96cf41e

Please sign in to comment.