oe.license: add is_included convenience function

Given a license string and whitelist and blacklist, determine if the
license string matches the whitelist and does not match the blacklist.

When encountering an OR, it prefers the side with the highest weight (more
included licenses). It then checks the inclusion of the flattened list of
licenses from there.

Returns a tuple holding the boolean state and a list of the applicable
licenses which were excluded (or None, if the state is True)

Examples:

    is_included, excluded = oe.license.is_included(licensestr, ['GPL*', 'LGPL*'])
    is_included, excluded = oe.license.is_included(licensestr, blacklist=['Proprietary', 'CLOSED'])

(From OE-Core rev: 7903433898b4683a1c09cc9a6a379421bc9bbd58)

Signed-off-by: Christopher Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Christopher Larson 2012-01-09 15:02:34 -06:00 committed by Richard Purdie
parent 49a0821376
commit 7ce97336aa
3 changed files with 43 additions and 19 deletions

View File

@ -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"""

View File

@ -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

3
meta/lib/test.py Normal file
View File

@ -0,0 +1,3 @@
import oe.license
print(oe.license.is_included('LGPLv2.1 | GPLv3', ['*'], []))