mirror of
git://git.yoctoproject.org/poky.git
synced 2025-07-19 21:09:03 +02:00
license: split license parsing into oe.license
In addition to moving this functionality to oe.license, makes the string preparation more picky before passing it off to the ast compilation. This ensures that LICENSE entries like 'GPL/BSD' are seen as invalid (due to the presence of the unsupported '/'). (From OE-Core rev: 20d4068045c76e9dc2aff0c152dd02d6a109c9dd) Signed-off-by: Christopher Larson <kergoth@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
parent
91378835c6
commit
a57de1ac9d
|
@ -57,12 +57,9 @@ python do_populate_lic() {
|
||||||
import os
|
import os
|
||||||
import bb
|
import bb
|
||||||
import shutil
|
import shutil
|
||||||
import ast
|
import oe.license
|
||||||
|
|
||||||
class LicenseVisitor(ast.NodeVisitor):
|
|
||||||
def generic_visit(self, node):
|
|
||||||
ast.NodeVisitor.generic_visit(self, node)
|
|
||||||
|
|
||||||
|
class FindVisitor(oe.license.LicenseVisitor):
|
||||||
def visit_Str(self, node):
|
def visit_Str(self, node):
|
||||||
#
|
#
|
||||||
# Until I figure out what to do with
|
# Until I figure out what to do with
|
||||||
|
@ -71,16 +68,7 @@ python do_populate_lic() {
|
||||||
# we'll just strip out the modifier and put
|
# we'll just strip out the modifier and put
|
||||||
# the base license.
|
# the base license.
|
||||||
find_license(node.s.replace("+", "").replace("*", ""))
|
find_license(node.s.replace("+", "").replace("*", ""))
|
||||||
ast.NodeVisitor.generic_visit(self, node)
|
self.generic_visit(node)
|
||||||
|
|
||||||
def visit_BinOp(self, node):
|
|
||||||
op = node.op
|
|
||||||
if isinstance(op, ast.BitOr):
|
|
||||||
x = LicenseVisitor()
|
|
||||||
x.visit(node.left)
|
|
||||||
x.visit(node.right)
|
|
||||||
else:
|
|
||||||
ast.NodeVisitor.generic_visit(self, node)
|
|
||||||
|
|
||||||
def copy_license(source, destination, file_name):
|
def copy_license(source, destination, file_name):
|
||||||
try:
|
try:
|
||||||
|
@ -156,18 +144,11 @@ python do_populate_lic() {
|
||||||
|
|
||||||
gen_lic_dest = os.path.join(d.getVar('LICENSE_DIRECTORY', True), "common-licenses")
|
gen_lic_dest = os.path.join(d.getVar('LICENSE_DIRECTORY', True), "common-licenses")
|
||||||
|
|
||||||
clean_licenses = ""
|
v = FindVisitor()
|
||||||
|
try:
|
||||||
for x in license_types.replace("(", " ( ").replace(")", " ) ").split():
|
v.visit_string(license_types)
|
||||||
if ((x != "(") and (x != ")") and (x != "&") and (x != "|")):
|
except oe.license.InvalidLicense as exc:
|
||||||
clean_licenses += "'" + x + "'"
|
bb.fatal("%s: %s" % (d.getVar('PF', True), exc))
|
||||||
else:
|
|
||||||
clean_licenses += " " + x + " "
|
|
||||||
|
|
||||||
# lstrip any possible indents, since ast needs python syntax.
|
|
||||||
node = ast.parse(clean_licenses.lstrip())
|
|
||||||
v = LicenseVisitor()
|
|
||||||
v.visit(node)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SSTATETASKS += "do_populate_lic"
|
SSTATETASKS += "do_populate_lic"
|
||||||
|
|
32
meta/lib/oe/license.py
Normal file
32
meta/lib/oe/license.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# vi:sts=4:sw=4:et
|
||||||
|
"""Code for parsing OpenEmbedded license strings"""
|
||||||
|
|
||||||
|
import ast
|
||||||
|
import re
|
||||||
|
|
||||||
|
class InvalidLicense(StandardError):
|
||||||
|
def __init__(self, license):
|
||||||
|
self.license = license
|
||||||
|
StandardError.__init__(self)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "invalid license '%s'" % self.license
|
||||||
|
|
||||||
|
license_operator = re.compile('([&|() ])')
|
||||||
|
license_pattern = re.compile('[a-zA-Z0-9.+_\-]+$')
|
||||||
|
|
||||||
|
class LicenseVisitor(ast.NodeVisitor):
|
||||||
|
"""Syntax tree visitor which can accept OpenEmbedded license strings"""
|
||||||
|
def visit_string(self, licensestr):
|
||||||
|
new_elements = []
|
||||||
|
elements = filter(lambda x: x.strip(), license_operator.split(licensestr))
|
||||||
|
for pos, element in enumerate(elements):
|
||||||
|
if license_pattern.match(element):
|
||||||
|
if pos > 0 and license_pattern.match(elements[pos-1]):
|
||||||
|
new_elements.append('&')
|
||||||
|
element = '"' + element + '"'
|
||||||
|
elif not license_operator.match(element):
|
||||||
|
raise InvalidLicense(element)
|
||||||
|
new_elements.append(element)
|
||||||
|
|
||||||
|
self.visit(ast.parse(' '.join(new_elements)))
|
38
meta/lib/oe/tests/test_license.py
Normal file
38
meta/lib/oe/tests/test_license.py
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import unittest
|
||||||
|
import oe.license
|
||||||
|
|
||||||
|
class SeenVisitor(oe.license.LicenseVisitor):
|
||||||
|
def __init__(self):
|
||||||
|
self.seen = []
|
||||||
|
oe.license.LicenseVisitor.__init__(self)
|
||||||
|
|
||||||
|
def visit_Str(self, node):
|
||||||
|
self.seen.append(node.s)
|
||||||
|
|
||||||
|
class TestSingleLicense(unittest.TestCase):
|
||||||
|
licenses = [
|
||||||
|
"GPLv2",
|
||||||
|
"LGPL-2.0",
|
||||||
|
"Artistic",
|
||||||
|
"MIT",
|
||||||
|
"GPLv3+",
|
||||||
|
"FOO_BAR",
|
||||||
|
]
|
||||||
|
invalid_licenses = ["GPL/BSD"]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse(licensestr):
|
||||||
|
visitor = SeenVisitor()
|
||||||
|
visitor.visit_string(licensestr)
|
||||||
|
return visitor.seen
|
||||||
|
|
||||||
|
def test_single_licenses(self):
|
||||||
|
for license in self.licenses:
|
||||||
|
licenses = self.parse(license)
|
||||||
|
self.assertListEqual(licenses, [license])
|
||||||
|
|
||||||
|
def test_invalid_licenses(self):
|
||||||
|
for license in self.invalid_licenses:
|
||||||
|
with self.assertRaises(oe.license.InvalidLicense) as cm:
|
||||||
|
self.parse(license)
|
||||||
|
self.assertEqual(cm.exception.license, license)
|
Loading…
Reference in New Issue
Block a user