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:
parent
a57de1ac9d
commit
9fb67f895c
|
@ -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
|
||||
|
|
|
@ -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"]
|
||||
|
|
Loading…
Reference in New Issue