Skip to content

Commit 2a3733e

Browse files
author
Olivier Chédru
authored
Merge pull request #104 from thehale/master
fix: Limit multiple license splits to SPDX `OR`
2 parents 80421bc + da8d06e commit 2a3733e

File tree

3 files changed

+57
-8
lines changed

3 files changed

+57
-8
lines changed

liccheck/command_line.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -223,16 +223,16 @@ def check_one(license_str, license_rule="AUTHORIZED", as_regex=False):
223223

224224
at_least_one_unauthorized = False
225225
count_authorized = 0
226-
for license in pkg["licenses"]:
227-
lower = license.lower()
226+
licenses = get_license_names(pkg["licenses"])
227+
for license in licenses:
228228
if check_one(
229-
lower,
229+
license,
230230
license_rule="UNAUTHORIZED",
231231
as_regex=as_regex,
232232
):
233233
at_least_one_unauthorized = True
234234
if check_one(
235-
lower,
235+
license,
236236
license_rule="AUTHORIZED",
237237
as_regex=as_regex,
238238
):
@@ -247,7 +247,7 @@ def check_one(license_str, license_rule="AUTHORIZED", as_regex=False):
247247
)
248248
or (
249249
count_authorized
250-
and count_authorized == len(pkg["licenses"])
250+
and count_authorized == len(licenses)
251251
and level is Level.PARANOID
252252
)
253253
):
@@ -259,6 +259,13 @@ def check_one(license_str, license_rule="AUTHORIZED", as_regex=False):
259259

260260
return Reason.UNKNOWN
261261

262+
def get_license_names(licenses):
263+
names = []
264+
for license in licenses:
265+
options = license.split(" OR ")
266+
for option in options:
267+
names.append(option.lower())
268+
return names
262269

263270
def find_parents(package, all, seen):
264271
if package in seen:

test-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ pytest-cov
33
python-openid;python_version<="2.7"
44
python3-openid;python_version>="3.0"
55
pytest-mock>=1.10
6+
tox

tests/test_check_package.py

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ def packages():
2525
"version": "1",
2626
"licenses": ["authorized 1", "unauthorized 1"],
2727
},
28+
{
29+
"name": "auth_one_or_unauth_one",
30+
"version": "2",
31+
"licenses": ["authorized 1 OR unauthorized 1"],
32+
},
2833
{
2934
"name": "unauth_one",
3035
"version": "2",
@@ -52,6 +57,12 @@ def packages():
5257
},
5358
]
5459

60+
def strategy_with_one_auth(license):
61+
return Strategy(
62+
authorized_licenses=[license.lower()],
63+
unauthorized_licenses=[],
64+
authorized_packages={},
65+
)
5566

5667
@pytest.mark.parametrize(
5768
("strategy_params", "as_regex"),
@@ -77,13 +88,43 @@ def packages():
7788
@pytest.mark.parametrize(
7889
("level", "reasons"),
7990
[
80-
(Level.STANDARD, [OK, OK, OK, UNAUTH, OK, UNAUTH, OK, UNKNOWN]),
81-
(Level.CAUTIOUS, [OK, OK, UNAUTH, UNAUTH, OK, UNAUTH, OK, UNKNOWN]),
82-
(Level.PARANOID, [OK, OK, UNAUTH, UNAUTH, OK, UNAUTH, UNKNOWN, UNKNOWN]),
91+
(Level.STANDARD, [OK, OK, OK, OK, UNAUTH, OK, UNAUTH, OK, UNKNOWN]),
92+
(Level.CAUTIOUS, [OK, OK, UNAUTH, UNAUTH, UNAUTH, OK, UNAUTH, OK, UNKNOWN]),
93+
(Level.PARANOID, [OK, OK, UNAUTH, UNAUTH, UNAUTH, OK, UNAUTH, UNKNOWN, UNKNOWN]),
8394
],
8495
ids=[level.name for level in Level],
8596
)
8697
def test_check_package(strategy_params, packages, level, reasons, as_regex):
8798
strategy = Strategy(**strategy_params)
8899
for package, reason in zip(packages, reasons):
89100
assert check_package(strategy, package, level, as_regex) is reason
101+
102+
@pytest.mark.parametrize(
103+
"license", [
104+
"GNU Library or Lesser General Public License (LGPL)",
105+
"GNU Lesser General Public License v2 or later (LGPLv2+)"
106+
]
107+
)
108+
def test_check_package_respects_licences_with_a_lowercase_or(license):
109+
strategy = strategy_with_one_auth(license)
110+
package = {
111+
"name": "lgpl_example",
112+
"version": "2",
113+
"licenses": [license],
114+
}
115+
assert check_package(strategy, package, Level.STANDARD, False) is OK
116+
117+
def test_check_package_splits_licenses_with_SPDX_OR():
118+
# The SPDX standard allows packages to specific dual licenses with an OR operator.
119+
# See https://spdx.org/spdx-specification-21-web-version#h.jxpfx0ykyb60
120+
mit_strategy = strategy_with_one_auth("MIT")
121+
apache_strategy = strategy_with_one_auth("Apache-2.0")
122+
gpl_strategy = strategy_with_one_auth("GPL-2.0-or-later")
123+
package = {
124+
"name": "mit_example",
125+
"version": "2",
126+
"licenses": ["MIT OR Apache-2.0"],
127+
}
128+
assert check_package(mit_strategy, package, Level.STANDARD, False) is OK
129+
assert check_package(apache_strategy, package, Level.STANDARD, False) is OK
130+
assert check_package(gpl_strategy, package, Level.STANDARD, False) is UNKNOWN

0 commit comments

Comments
 (0)