oe.license: add license flattening code

This flattens a license tree by selecting one side of each OR operation
(chosen via the user supplied function).

(From OE-Core rev: 6984961314c8ba2aceab9acabb658f96ed249fef)

Signed-off-by: Christopher Larson <kergoth@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Christopher Larson 2011-12-04 20:03:51 -05:00 committed by Richard Purdie
parent a57de1ac9d
commit 9fb67f895c
2 changed files with 60 additions and 0 deletions

View File

@ -30,3 +30,33 @@ class LicenseVisitor(ast.NodeVisitor):
new_elements.append(element)
self.visit(ast.parse(' '.join(new_elements)))
class FlattenVisitor(LicenseVisitor):
"""Flatten a license tree (parsed from a string) by selecting one of each
set of OR options, in the way the user specifies"""
def __init__(self, choose_licenses):
self.choose_licenses = choose_licenses
self.licenses = []
LicenseVisitor.__init__(self)
def visit_Str(self, node):
self.licenses.append(node.s)
def visit_BinOp(self, node):
if isinstance(node.op, ast.BitOr):
left = FlattenVisitor(self.choose_licenses)
left.visit(node.left)
right = FlattenVisitor(self.choose_licenses)
right.visit(node.right)
selected = self.choose_licenses(left.licenses, right.licenses)
self.licenses.extend(selected)
else:
self.generic_visit(node)
def flattened_licenses(licensestr, choose_licenses):
"""Given a license string and choose_licenses function, return a flat list of licenses"""
flatten = FlattenVisitor(choose_licenses)
flatten.visit_string(licensestr)
return flatten.licenses

View File

@ -36,3 +36,33 @@ class TestSingleLicense(unittest.TestCase):
with self.assertRaises(oe.license.InvalidLicense) as cm:
self.parse(license)
self.assertEqual(cm.exception.license, license)
class TestSimpleCombinations(unittest.TestCase):
tests = {
"FOO&BAR": ["FOO", "BAR"],
"BAZ & MOO": ["BAZ", "MOO"],
"ALPHA|BETA": ["ALPHA"],
"BAZ&MOO|FOO": ["FOO"],
"FOO&BAR|BAZ": ["FOO", "BAR"],
}
preferred = ["ALPHA", "FOO", "BAR"]
def test_tests(self):
def choose(a, b):
if all(lic in self.preferred for lic in b):
return b
else:
return a
for license, expected in self.tests.items():
licenses = oe.license.flattened_licenses(license, choose)
self.assertListEqual(licenses, expected)
class TestComplexCombinations(TestSimpleCombinations):
tests = {
"FOO & (BAR | BAZ)&MOO": ["FOO", "BAR", "MOO"],
"(ALPHA|(BETA&THETA)|OMEGA)&DELTA": ["OMEGA", "DELTA"],
"((ALPHA|BETA)&FOO)|BAZ": ["BETA", "FOO"],
"(GPL-2.0|Proprietary)&BSD-4-clause&MIT": ["GPL-2.0", "BSD-4-clause", "MIT"],
}
preferred = ["BAR", "OMEGA", "BETA", "GPL-2.0"]