diff options
Diffstat (limited to 'meta/lib')
| -rw-r--r-- | meta/lib/oe/license.py | 32 | ||||
| -rw-r--r-- | meta/lib/oe/tests/test_license.py | 38 |
2 files changed, 70 insertions, 0 deletions
diff --git a/meta/lib/oe/license.py b/meta/lib/oe/license.py new file mode 100644 index 0000000000..b230d3ef45 --- /dev/null +++ b/meta/lib/oe/license.py | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | # vi:sts=4:sw=4:et | ||
| 2 | """Code for parsing OpenEmbedded license strings""" | ||
| 3 | |||
| 4 | import ast | ||
| 5 | import re | ||
| 6 | |||
| 7 | class InvalidLicense(StandardError): | ||
| 8 | def __init__(self, license): | ||
| 9 | self.license = license | ||
| 10 | StandardError.__init__(self) | ||
| 11 | |||
| 12 | def __str__(self): | ||
| 13 | return "invalid license '%s'" % self.license | ||
| 14 | |||
| 15 | license_operator = re.compile('([&|() ])') | ||
| 16 | license_pattern = re.compile('[a-zA-Z0-9.+_\-]+$') | ||
| 17 | |||
| 18 | class LicenseVisitor(ast.NodeVisitor): | ||
| 19 | """Syntax tree visitor which can accept OpenEmbedded license strings""" | ||
| 20 | def visit_string(self, licensestr): | ||
| 21 | new_elements = [] | ||
| 22 | elements = filter(lambda x: x.strip(), license_operator.split(licensestr)) | ||
| 23 | for pos, element in enumerate(elements): | ||
| 24 | if license_pattern.match(element): | ||
| 25 | if pos > 0 and license_pattern.match(elements[pos-1]): | ||
| 26 | new_elements.append('&') | ||
| 27 | element = '"' + element + '"' | ||
| 28 | elif not license_operator.match(element): | ||
| 29 | raise InvalidLicense(element) | ||
| 30 | new_elements.append(element) | ||
| 31 | |||
| 32 | self.visit(ast.parse(' '.join(new_elements))) | ||
diff --git a/meta/lib/oe/tests/test_license.py b/meta/lib/oe/tests/test_license.py new file mode 100644 index 0000000000..cb949fc76f --- /dev/null +++ b/meta/lib/oe/tests/test_license.py | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | import unittest | ||
| 2 | import oe.license | ||
| 3 | |||
| 4 | class SeenVisitor(oe.license.LicenseVisitor): | ||
| 5 | def __init__(self): | ||
| 6 | self.seen = [] | ||
| 7 | oe.license.LicenseVisitor.__init__(self) | ||
| 8 | |||
| 9 | def visit_Str(self, node): | ||
| 10 | self.seen.append(node.s) | ||
| 11 | |||
| 12 | class TestSingleLicense(unittest.TestCase): | ||
| 13 | licenses = [ | ||
| 14 | "GPLv2", | ||
| 15 | "LGPL-2.0", | ||
| 16 | "Artistic", | ||
| 17 | "MIT", | ||
| 18 | "GPLv3+", | ||
| 19 | "FOO_BAR", | ||
| 20 | ] | ||
| 21 | invalid_licenses = ["GPL/BSD"] | ||
| 22 | |||
| 23 | @staticmethod | ||
| 24 | def parse(licensestr): | ||
| 25 | visitor = SeenVisitor() | ||
| 26 | visitor.visit_string(licensestr) | ||
| 27 | return visitor.seen | ||
| 28 | |||
| 29 | def test_single_licenses(self): | ||
| 30 | for license in self.licenses: | ||
| 31 | licenses = self.parse(license) | ||
| 32 | self.assertListEqual(licenses, [license]) | ||
| 33 | |||
| 34 | def test_invalid_licenses(self): | ||
| 35 | for license in self.invalid_licenses: | ||
| 36 | with self.assertRaises(oe.license.InvalidLicense) as cm: | ||
| 37 | self.parse(license) | ||
| 38 | self.assertEqual(cm.exception.license, license) | ||
