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 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 | ||
76 | python do_prepare_copyleft_sources () { | 61 | python 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 | ||
4 | import ast | 4 | import ast |
5 | import re | 5 | import re |
6 | from fnmatch import fnmatchcase as fnmatch | ||
6 | 7 | ||
7 | class InvalidLicense(StandardError): | 8 | class 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 | |||
65 | def 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 @@ | |||
1 | import oe.license | ||
2 | |||
3 | print(oe.license.is_included('LGPLv2.1 | GPLv3', ['*'], [])) | ||