Fix license handling for API formulae

This commit is contained in:
Bo Anderson 2023-02-06 09:57:25 +00:00
parent b3a71ba7cd
commit 83b23e6d5e
No known key found for this signature in database
GPG Key ID: 3DB94E204E137D65
3 changed files with 60 additions and 1 deletions

View File

@ -151,7 +151,7 @@ module Formulary
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"]

View File

@ -217,6 +217,31 @@ describe SPDX do
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"]

View File

@ -129,6 +129,40 @@ module SPDX
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