summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Larson <chris_larson@mentor.com>2012-01-09 15:02:34 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-01-17 14:53:19 +0000
commit7ce97336aad5e6ecefb5e735a13e345d1b8bd8fb (patch)
tree270b4abfa31518895add0e9f2fbea7722288d07c
parent49a0821376ef6146345d673b1e9eddd34aee931a (diff)
downloadpoky-7ce97336aad5e6ecefb5e735a13e345d1b8bd8fb.tar.gz
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>
-rw-r--r--meta/classes/copyleft_compliance.bbclass23
-rw-r--r--meta/lib/oe/license.py36
-rw-r--r--meta/lib/test.py3
3 files changed, 43 insertions, 19 deletions
diff --git a/meta/classes/copyleft_compliance.bbclass b/meta/classes/copyleft_compliance.bbclass
index fd046381b6..6f058e0f20 100644
--- a/meta/classes/copyleft_compliance.bbclass
+++ b/meta/classes/copyleft_compliance.bbclass
@@ -46,32 +46,17 @@ def copyleft_should_include(d):
46 include = oe.data.typed_value('COPYLEFT_LICENSE_INCLUDE', d) 46 include = oe.data.typed_value('COPYLEFT_LICENSE_INCLUDE', d)
47 exclude = oe.data.typed_value('COPYLEFT_LICENSE_EXCLUDE', d) 47 exclude = oe.data.typed_value('COPYLEFT_LICENSE_EXCLUDE', d)
48 48
49 def include_license(license):
50 if any(fnmatch(license, pattern) for pattern in exclude):
51 return False
52 if any(fnmatch(license, pattern) for pattern in include):
53 return True
54 return False
55
56 def choose_licenses(a, b):
57 """Select the left option in an OR if all its licenses are to be included"""
58 if all(include_license(lic) for lic in a):
59 return a
60 else:
61 return b
62
63 try: 49 try:
64 licenses = oe.license.flattened_licenses(d.getVar('LICENSE', True), choose_licenses) 50 is_included, excluded = oe.license.is_included(d.getVar('LICENSE', True), include, exclude)
65 except oe.license.InvalidLicense as exc: 51 except oe.license.InvalidLicense as exc:
66 bb.fatal('%s: %s' % (d.getVar('PF', True), exc)) 52 bb.fatal('%s: %s' % (d.getVar('PF', True), exc))
67 except SyntaxError as exc: 53 except SyntaxError as exc:
68 bb.warn('%s: error when parsing the LICENSE variable: %s' % (d.getVar('P', True), exc)) 54 bb.warn('%s: error when parsing the LICENSE variable: %s' % (d.getVar('P', True), exc))
69 else: 55 else:
70 excluded = filter(lambda lic: not include_license(lic), licenses) 56 if is_included:
71 if excluded:
72 return False, 'recipe has excluded licenses: %s' % ', '.join(excluded)
73 else:
74 return True, None 57 return True, None
58 else:
59 return False, 'recipe has excluded licenses: %s' % ', '.join(excluded)
75 60
76python do_prepare_copyleft_sources () { 61python do_prepare_copyleft_sources () {
77 """Populate a tree of the recipe sources and emit patch series files""" 62 """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 7ab66e762f..3543cfe1f6 100644
--- a/meta/lib/oe/license.py
+++ b/meta/lib/oe/license.py
@@ -3,6 +3,7 @@
3 3
4import ast 4import ast
5import re 5import re
6from fnmatch import fnmatchcase as fnmatch
6 7
7class InvalidLicense(StandardError): 8class InvalidLicense(StandardError):
8 def __init__(self, license): 9 def __init__(self, license):
@@ -60,3 +61,38 @@ def flattened_licenses(licensestr, choose_licenses):
60 flatten = FlattenVisitor(choose_licenses) 61 flatten = FlattenVisitor(choose_licenses)
61 flatten.visit_string(licensestr) 62 flatten.visit_string(licensestr)
62 return flatten.licenses 63 return flatten.licenses
64
65def is_included(licensestr, whitelist=None, blacklist=None):
66 """Given a license string and whitelist and blacklist, determine if the
67 license string matches the whitelist and does not match the blacklist.
68
69 Returns a tuple holding the boolean state and a list of the applicable
70 licenses which were excluded (or None, if the state is True)
71 """
72
73 def include_license(license):
74 return (any(fnmatch(license, pattern) for pattern in whitelist) and not
75 any(fnmatch(license, pattern) for pattern in blacklist))
76
77 def choose_licenses(alpha, beta):
78 """Select the option in an OR which is the 'best' (has the most
79 included licenses)."""
80 alpha_weight = len(filter(include_license, alpha))
81 beta_weight = len(filter(include_license, beta))
82 if alpha_weight > beta_weight:
83 return alpha
84 else:
85 return beta
86
87 if not whitelist:
88 whitelist = ['*']
89
90 if not blacklist:
91 blacklist = []
92
93 licenses = flattened_licenses(licensestr, choose_licenses)
94 excluded = filter(lambda lic: not include_license(lic), licenses)
95 if excluded:
96 return False, excluded
97 else:
98 return True, None
diff --git a/meta/lib/test.py b/meta/lib/test.py
new file mode 100644
index 0000000000..12f4d837dd
--- /dev/null
+++ b/meta/lib/test.py
@@ -0,0 +1,3 @@
1import oe.license
2
3print(oe.license.is_included('LGPLv2.1 | GPLv3', ['*'], []))