utils/spdx: fix invalid SPDX syntax for symbols

Also use more common uppercase operators for backwards compatibility
This commit is contained in:
Michael Cho 2024-08-26 10:09:25 -04:00
parent 0c3104a8f2
commit 82fbbcc88b
No known key found for this signature in database
GPG Key ID: 55E85E28A7CD1E85
2 changed files with 39 additions and 16 deletions

View File

@ -175,20 +175,20 @@ RSpec.describe SPDX do
end
it "returns multiple licenses with :any" do
expect(described_class.license_expression_to_string({ any_of: ["MIT", "0BSD"] })).to eq "MIT or 0BSD"
expect(described_class.license_expression_to_string({ any_of: ["MIT", "0BSD"] })).to eq "MIT OR 0BSD"
end
it "returns multiple licenses with :all" do
expect(described_class.license_expression_to_string({ all_of: ["MIT", "0BSD"] })).to eq "MIT and 0BSD"
expect(described_class.license_expression_to_string({ all_of: ["MIT", "0BSD"] })).to eq "MIT AND 0BSD"
end
it "returns multiple licenses with plus" do
expect(described_class.license_expression_to_string({ any_of: ["MIT", "EPL-1.0+"] })).to eq "MIT or EPL-1.0+"
expect(described_class.license_expression_to_string({ any_of: ["MIT", "EPL-1.0+"] })).to eq "MIT OR EPL-1.0+"
end
it "returns license and exception" do
license_expression = { "MIT" => { with: "LLVM-exception" } }
expect(described_class.license_expression_to_string(license_expression)).to eq "MIT with LLVM-exception"
expect(described_class.license_expression_to_string(license_expression)).to eq "MIT WITH LLVM-exception"
end
it "returns licenses and exceptions for complex license expressions" do
@ -198,16 +198,17 @@ RSpec.describe SPDX do
all_of: ["0BSD", "Zlib"], # rubocop:disable Style/HashAsLastArrayItem
"curl" => { with: "LLVM-exception" },
] }
result = "MIT or Public Domain or (0BSD and Zlib) or (curl with LLVM-exception)"
result = "MIT OR LicenseRef-Homebrew-public-domain OR (0BSD AND Zlib) OR (curl WITH LLVM-exception)"
expect(described_class.license_expression_to_string(license_expression)).to eq result
end
it "returns :public_domain" do
expect(described_class.license_expression_to_string(:public_domain)).to eq "Public Domain"
expect(described_class.license_expression_to_string(:public_domain)).to eq "LicenseRef-Homebrew-public-domain"
end
it "returns :cannot_represent" do
expect(described_class.license_expression_to_string(:cannot_represent)).to eq "Cannot Represent"
result = "LicenseRef-Homebrew-cannot-represent"
expect(described_class.license_expression_to_string(:cannot_represent)).to eq result
end
end
@ -223,9 +224,20 @@ RSpec.describe SPDX do
})
end
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
# rubocop:disable Style/HashAsLastArrayItem
it "handles nested brackets" do
expect(described_class.string_to_license_expression("A and (B or (C and D))")).to eq({
expect(described_class.string_to_license_expression("A AND (B OR (C AND D))")).to eq({
all_of: [
"A",
any_of: [
@ -236,6 +248,15 @@ RSpec.describe SPDX do
})
end
# rubocop:enable Style/HashAsLastArrayItem
it "returns :public_domain" do
expect(described_class.string_to_license_expression("LicenseRef-Homebrew-public-domain")).to eq :public_domain
end
it "returns :cannot_represent" do
expr_string = "LicenseRef-Homebrew-cannot-represent"
expect(described_class.string_to_license_expression(expr_string)).to eq :cannot_represent
end
end
describe ".license_version_info" do

View File

@ -10,6 +10,7 @@ module SPDX
DATA_PATH = (HOMEBREW_DATA_PATH/"spdx").freeze
API_URL = "https://api.github.com/repos/spdx/license-list-data/releases/latest"
LICENSEREF_PREFIX = "LicenseRef-Homebrew-"
ALLOWED_LICENSE_SYMBOLS = [
:public_domain,
:cannot_represent,
@ -90,14 +91,14 @@ module SPDX
when String
license_expression
when Symbol
license_expression.to_s.tr("_", " ").gsub(/\b(?<!\w['`()])[a-z]/, &:capitalize)
LICENSEREF_PREFIX + license_expression.to_s.tr("_", "-")
when Hash
expressions = []
if license_expression.keys.length == 1
hash_type = license_expression.keys.first
if hash_type.is_a? String
expressions.push "#{hash_type} with #{license_expression[hash_type][:with]}"
expressions.push "#{hash_type} WITH #{license_expression[hash_type][:with]}"
else
expressions += license_expression[hash_type].map do |license|
license_expression_to_string license, bracket: true, hash_type:
@ -111,9 +112,9 @@ module SPDX
end
operator = if hash_type == :any_of
" or "
" OR "
else
" and "
" AND "
end
if bracket
@ -130,12 +131,12 @@ module SPDX
result = string
result_type = nil
and_parts = string.split(/ and (?![^(]*\))/)
and_parts = string.split(/ and (?![^(]*\))/i)
if and_parts.length > 1
result = and_parts
result_type = :all_of
else
or_parts = string.split(/ or (?![^(]*\))/)
or_parts = string.split(/ or (?![^(]*\))/i)
if or_parts.length > 1
result = or_parts
result_type = :any_of
@ -149,11 +150,12 @@ module SPDX
end
{ result_type => result }
else
with_parts = string.split(" with ", 2)
with_parts = string.split(/ with /i, 2)
if with_parts.length > 1
{ with_parts.first => { with: with_parts.second } }
else
result
license_sym = result[/^#{LICENSEREF_PREFIX}(.+)/o, 1]&.downcase&.tr("-", "_")&.to_sym
ALLOWED_LICENSE_SYMBOLS.include?(license_sym) ? license_sym : result
end
end
end