summaryrefslogtreecommitdiffstats
path: root/meta/lib
diff options
context:
space:
mode:
authorPeter Kjellerstedt <peter.kjellerstedt@axis.com>2017-09-29 17:52:34 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2017-10-07 23:20:39 +0100
commit16f1a14f83353b809650ce5fe50b35e38b6c6d7e (patch)
treeda594c3ffd5d88960efe82dc2977f1bbb7dd5ec5 /meta/lib
parent03839a7ffa395edaf85e74a86799a44b217b79d3 (diff)
downloadpoky-16f1a14f83353b809650ce5fe50b35e38b6c6d7e.tar.gz
license.py: Correct selection of licenses in is_included()
When faced with multiple sets of licenses combined with | (OR), it was possible for oe.license.is_included() to choose a set of licenses with a blacklisted license and then report failure, even if choosing another set of licenses would have resulted in a successful result. This happened when the chosen set still contained more whitelisted licenses than the other set. This change makes sure a set with any blacklisted license is always considered with a lower weight than a set with only whitelisted licenses. Example: Faced with the license string "GPL-3.0 & GPL-2.0 & LGPL-2.1 | Proprietary" and with "GPL-3.0" being blacklisted, the old code would report a failure since "GPL-3.0 & GPL-2.0 & LGPL-2.1" still contains more whitelisted licenses than "Proprietary" does. This change also adds a unit test for oe.license.is_included(). (From OE-Core rev: 312b4d6175e189852c0787ca2fe99b99ce92d1bd) Signed-off-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib')
-rw-r--r--meta/lib/oe/license.py18
-rw-r--r--meta/lib/oeqa/selftest/cases/oelib/license.py31
2 files changed, 44 insertions, 5 deletions
diff --git a/meta/lib/oe/license.py b/meta/lib/oe/license.py
index 8d2fd1709c..ca385d5187 100644
--- a/meta/lib/oe/license.py
+++ b/meta/lib/oe/license.py
@@ -106,7 +106,8 @@ def is_included(licensestr, whitelist=None, blacklist=None):
106 license string matches the whitelist and does not match the blacklist. 106 license string matches the whitelist and does not match the blacklist.
107 107
108 Returns a tuple holding the boolean state and a list of the applicable 108 Returns a tuple holding the boolean state and a list of the applicable
109 licenses which were excluded (or None, if the state is True) 109 licenses that were excluded if state is False, or the licenses that were
110 included if the state is True.
110 """ 111 """
111 112
112 def include_license(license): 113 def include_license(license):
@@ -117,10 +118,17 @@ def is_included(licensestr, whitelist=None, blacklist=None):
117 118
118 def choose_licenses(alpha, beta): 119 def choose_licenses(alpha, beta):
119 """Select the option in an OR which is the 'best' (has the most 120 """Select the option in an OR which is the 'best' (has the most
120 included licenses).""" 121 included licenses and no excluded licenses)."""
121 alpha_weight = len(list(filter(include_license, alpha))) 122 # The factor 1000 below is arbitrary, just expected to be much larger
122 beta_weight = len(list(filter(include_license, beta))) 123 # that the number of licenses actually specified. That way the weight
123 if alpha_weight > beta_weight: 124 # will be negative if the list of licenses contains an excluded license,
125 # but still gives a higher weight to the list with the most included
126 # licenses.
127 alpha_weight = (len(list(filter(include_license, alpha))) -
128 1000 * (len(list(filter(exclude_license, alpha))) > 0))
129 beta_weight = (len(list(filter(include_license, beta))) -
130 1000 * (len(list(filter(exclude_license, beta))) > 0))
131 if alpha_weight >= beta_weight:
124 return alpha 132 return alpha
125 else: 133 else:
126 return beta 134 return beta
diff --git a/meta/lib/oeqa/selftest/cases/oelib/license.py b/meta/lib/oeqa/selftest/cases/oelib/license.py
index bfd9ed9c29..d7f91fb2f4 100644
--- a/meta/lib/oeqa/selftest/cases/oelib/license.py
+++ b/meta/lib/oeqa/selftest/cases/oelib/license.py
@@ -66,3 +66,34 @@ class TestComplexCombinations(TestSimpleCombinations):
66 "(GPL-2.0|Proprietary)&BSD-4-clause&MIT": ["GPL-2.0", "BSD-4-clause", "MIT"], 66 "(GPL-2.0|Proprietary)&BSD-4-clause&MIT": ["GPL-2.0", "BSD-4-clause", "MIT"],
67 } 67 }
68 preferred = ["BAR", "OMEGA", "BETA", "GPL-2.0"] 68 preferred = ["BAR", "OMEGA", "BETA", "GPL-2.0"]
69
70class TestIsIncluded(TestCase):
71 tests = {
72 ("FOO | BAR", None, None):
73 [True, ["FOO"]],
74 ("FOO | BAR", None, "FOO"):
75 [True, ["BAR"]],
76 ("FOO | BAR", "BAR", None):
77 [True, ["BAR"]],
78 ("FOO | BAR & FOOBAR", "*BAR", None):
79 [True, ["BAR", "FOOBAR"]],
80 ("FOO | BAR & FOOBAR", None, "FOO*"):
81 [False, ["FOOBAR"]],
82 ("(FOO | BAR) & FOOBAR | BARFOO", None, "FOO"):
83 [True, ["BAR", "FOOBAR"]],
84 ("(FOO | BAR) & FOOBAR | BAZ & MOO & BARFOO", None, "FOO"):
85 [True, ["BAZ", "MOO", "BARFOO"]],
86 ("GPL-3.0 & GPL-2.0 & LGPL-2.1 | Proprietary", None, None):
87 [True, ["GPL-3.0", "GPL-2.0", "LGPL-2.1"]],
88 ("GPL-3.0 & GPL-2.0 & LGPL-2.1 | Proprietary", None, "GPL-3.0"):
89 [True, ["Proprietary"]],
90 ("GPL-3.0 & GPL-2.0 & LGPL-2.1 | Proprietary", None, "GPL-3.0 Proprietary"):
91 [False, ["GPL-3.0"]]
92 }
93
94 def test_tests(self):
95 for args, expected in self.tests.items():
96 is_included, licenses = oe.license.is_included(
97 args[0], (args[1] or '').split(), (args[2] or '').split())
98 self.assertEqual(is_included, expected[0])
99 self.assertListEqual(licenses, expected[1])