diff options
-rw-r--r-- | meta/classes/copyleft_compliance.bbclass | 23 | ||||
-rw-r--r-- | meta/lib/oe/license.py | 36 | ||||
-rw-r--r-- | meta/lib/test.py | 3 |
3 files changed, 43 insertions, 19 deletions
diff --git a/meta/classes/copyleft_compliance.bbclass b/meta/classes/copyleft_compliance.bbclass index fd046381b..6f058e0f2 100644 --- a/meta/classes/copyleft_compliance.bbclass +++ b/meta/classes/copyleft_compliance.bbclass @@ -46,32 +46,17 @@ def copyleft_should_include(d): include = oe.data.typed_value('COPYLEFT_LICENSE_INCLUDE', d) exclude = oe.data.typed_value('COPYLEFT_LICENSE_EXCLUDE', d) - def include_license(license): - if any(fnmatch(license, pattern) for pattern in exclude): - return False - if any(fnmatch(license, pattern) for pattern in include): - return True - return False - - def choose_licenses(a, b): - """Select the left option in an OR if all its licenses are to be included""" - if all(include_license(lic) for lic in a): - return a - else: - return b - try: - licenses = oe.license.flattened_licenses(d.getVar('LICENSE', True), choose_licenses) + is_included, excluded = oe.license.is_included(d.getVar('LICENSE', True), include, exclude) except oe.license.InvalidLicense as exc: bb.fatal('%s: %s' % (d.getVar('PF', True), exc)) except SyntaxError as exc: bb.warn('%s: error when parsing the LICENSE variable: %s' % (d.getVar('P', True), exc)) else: - excluded = filter(lambda lic: not include_license(lic), licenses) - if excluded: - return False, 'recipe has excluded licenses: %s' % ', '.join(excluded) - else: + if is_included: return True, None + else: + return False, 'recipe has excluded licenses: %s' % ', '.join(excluded) python do_prepare_copyleft_sources () { """Populate a tree of the recipe sources and emit patch series files""" diff --git a/meta/lib/oe/license.py b/meta/lib/oe/license.py index 7ab66e762..3543cfe1f 100644 --- a/meta/lib/oe/license.py +++ b/meta/lib/oe/license.py @@ -3,6 +3,7 @@ import ast import re +from fnmatch import fnmatchcase as fnmatch class InvalidLicense(StandardError): def __init__(self, license): @@ -60,3 +61,38 @@ def flattened_licenses(licensestr, choose_licenses): flatten = FlattenVisitor(choose_licenses) flatten.visit_string(licensestr) return flatten.licenses + +def is_included(licensestr, whitelist=None, blacklist=None): + """Given a license string and whitelist and blacklist, determine if the + license string matches the whitelist and does not match the blacklist. + + Returns a tuple holding the boolean state and a list of the applicable + licenses which were excluded (or None, if the state is True) + """ + + def include_license(license): + return (any(fnmatch(license, pattern) for pattern in whitelist) and not + any(fnmatch(license, pattern) for pattern in blacklist)) + + def choose_licenses(alpha, beta): + """Select the option in an OR which is the 'best' (has the most + included licenses).""" + alpha_weight = len(filter(include_license, alpha)) + beta_weight = len(filter(include_license, beta)) + if alpha_weight > beta_weight: + return alpha + else: + return beta + + if not whitelist: + whitelist = ['*'] + + if not blacklist: + blacklist = [] + + licenses = flattened_licenses(licensestr, choose_licenses) + excluded = filter(lambda lic: not include_license(lic), licenses) + if excluded: + return False, excluded + else: + return True, None diff --git a/meta/lib/test.py b/meta/lib/test.py new file mode 100644 index 000000000..12f4d837d --- /dev/null +++ b/meta/lib/test.py @@ -0,0 +1,3 @@ +import oe.license + +print(oe.license.is_included('LGPLv2.1 | GPLv3', ['*'], [])) |