Skip to content

Commit 580c538

Browse files
committed
start organising the repo
1 parent c012bf3 commit 580c538

File tree

2 files changed

+230
-0
lines changed

2 files changed

+230
-0
lines changed
+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
"""Define a foss compatability license_matrix.
2+
3+
Standard disclaimer:: I am not a lawyer and there is no guarantee that the
4+
information provided here is complete or correct. Do not take this as legal
5+
advice on foss license compatability
6+
7+
https://en.wikipedia.org/wiki/IANAL
8+
9+
10+
Types of license/ compatability
11+
12+
Public Domain
13+
- Unlicense
14+
15+
Permissive Compatible
16+
Permissive license compatible with gpl
17+
- Mit
18+
- Boost
19+
- Bsd
20+
- Isc
21+
- Ncsa
22+
23+
Permissive Not Compatible
24+
Permissive license NOT compatible with gpl
25+
- Apache
26+
- Eclipse
27+
- Academic Free
28+
29+
30+
Copyleft
31+
permissive -> lgpl 2.1 -> gpl 2
32+
permissive -> lgpl 3 -> gpl 3 -> agpl
33+
permissive -> mpl -> gpl -> agpl (3 only)
34+
35+
permissive (any) -> EU
36+
EU -> gpl -> agpl (3 only)
37+
"""
38+
39+
from __future__ import annotations
40+
41+
import csv
42+
from pathlib import Path
43+
44+
from loguru import logger
45+
46+
from licensecheck.types import JOINS, ucstr
47+
from licensecheck.types import License as L
48+
49+
THISDIR = Path(__file__).resolve().parent
50+
51+
with Path(THISDIR / "matrix.csv").open(mode="r", newline="", encoding="utf-8") as csv_file:
52+
LICENSE_MATRIX = list(csv.reader(csv_file))
53+
54+
55+
termToLicense = {
56+
"PUBLIC DOMAIN": L.PUBLIC,
57+
"CC-PDDC": L.PUBLIC,
58+
"CC0-1.0": L.PUBLIC,
59+
"UNLICENSE": L.UNLICENSE,
60+
"WTFPL": L.UNLICENSE,
61+
"BOOST": L.BOOST,
62+
"BSL-1.0": L.BOOST,
63+
"MIT": L.MIT,
64+
"BSD": L.BSD,
65+
"ISC": L.ISC,
66+
"NCSA": L.NCSA,
67+
"PYTHON": L.PSFL,
68+
"PSF-2.0": L.PSFL,
69+
"APACHE": L.APACHE,
70+
"ECLIPSE": L.ECLIPSE,
71+
"AFL": L.ACADEMIC_FREE,
72+
"LGPLV2+": L.LGPL_2_PLUS,
73+
"LGPL-2.0-OR-LATER": L.LGPL_2_PLUS,
74+
"LGPLV3+": L.LGPL_3_PLUS,
75+
"LGPL-3.0-OR-LATER": L.LGPL_3_PLUS,
76+
"LGPL-2.0-ONLY": L.LGPL_2,
77+
"LGPLV2": L.LGPL_2,
78+
"LGPL-3.0-ONLY": L.LGPL_3,
79+
"LGPLV3": L.LGPL_3,
80+
"LGPL": L.LGPL_X,
81+
"AGPL": L.AGPL_3_PLUS,
82+
"GNU AFFERO GENERAL PUBLIC LICENSE V3": L.AGPL_3_PLUS,
83+
"GPL-2.0-OR-LATER": L.GPL_2_PLUS,
84+
"GPLV2+": L.GPL_2_PLUS,
85+
"GPL-3.0-OR-LATER": L.GPL_3_PLUS,
86+
"GPLV3+": L.GPL_3_PLUS,
87+
"GPLV2": L.GPL_2,
88+
"GPL-2.0": L.GPL_2,
89+
"GPLV3": L.GPL_3,
90+
"GPL-3.0": L.GPL_3,
91+
"GPL": L.GPL_X,
92+
"MPL": L.MPL,
93+
"EUPL": L.EU,
94+
"PROPRIETARY": L.PROPRIETARY,
95+
}
96+
97+
98+
def licenseLookup(licenseStr: ucstr, ignoreLicenses: list[ucstr] | None = None) -> L:
99+
"""Identify a license from an uppercase string representation of a license.
100+
101+
:param ucstr licenseStr: uppercase string representation of a license
102+
:param list[ucstr] | None ignoreLicenses: licenses to ignore, defaults to None
103+
:return L: License represented by licenseStr
104+
"""
105+
106+
for liceStr, lice in termToLicense.items():
107+
if liceStr.strip() in licenseStr:
108+
return lice
109+
110+
111+
if licenseStr not in (ignoreLicenses or ""):
112+
logger.warning(f"'{licenseStr}' License not identified so falling back to NO_LICENSE")
113+
return L.NO_LICENSE
114+
115+
116+
117+
def licenseType(lice: ucstr, ignoreLicenses: list[ucstr] | None = None) -> list[L]:
118+
"""Return a list of license types from a license string.
119+
120+
Args:
121+
----
122+
lice (ucstr): license name
123+
ignoreLicenses (list[ucstr]): a list of licenses to ignore (skipped, compat may still be
124+
False)
125+
126+
Returns:
127+
-------
128+
list[L]: the license
129+
130+
"""
131+
if len(lice or "") < 1:
132+
return [L.NO_LICENSE]
133+
return [licenseLookup(ucstr(x), ignoreLicenses) for x in lice.split(JOINS)]
134+
135+
136+
def depCompatWMyLice(
137+
myLicense: L,
138+
depLice: list[L],
139+
ignoreLicenses: list[L] | None = None,
140+
failLicenses: list[L] | None = None,
141+
onlyLicenses: list[L] | None = None,
142+
) -> bool:
143+
"""Identify if the end user license is compatible with the dependency license(s).
144+
145+
Args:
146+
----
147+
myLicense (L): end user license to check
148+
depLice (list[L]): dependency license
149+
ignoreLicenses (list[L], optional): list of licenses to ignore. Defaults to None.
150+
failLicenses (list[L], optional): list of licenses to fail on. Defaults to None.
151+
onlyLicenses (list[L], optional): list of allowed licenses. Defaults to None.
152+
153+
Returns:
154+
-------
155+
bool: True if compatible, otherwise False
156+
157+
"""
158+
159+
# Protect against None
160+
failLicenses = failLicenses or []
161+
ignoreLicenses = ignoreLicenses or []
162+
onlyLicenses = onlyLicenses or []
163+
164+
return any(
165+
liceCompat(
166+
myLicense,
167+
lice,
168+
ignoreLicenses,
169+
failLicenses,
170+
onlyLicenses,
171+
)
172+
for lice in depLice
173+
)
174+
175+
176+
def liceCompat(
177+
myLicense: L,
178+
lice: L,
179+
ignoreLicenses: list[L],
180+
failLicenses: list[L],
181+
onlyLicenses: list[L],
182+
) -> bool:
183+
"""Identify if the end user license is compatible with the dependency license.
184+
185+
:param L myLicense: end user license
186+
:param L lice: dependency license
187+
:param list[L] ignoreLicenses: list of licenses to ignore. Defaults to None.
188+
:param list[L] failLicenses: list of licenses to fail on. Defaults to None.
189+
:param list[L] onlyLicenses: list of allowed licenses. Defaults to None.
190+
:return bool: True if compatible, otherwise False
191+
"""
192+
if lice in failLicenses:
193+
return False
194+
if lice in ignoreLicenses:
195+
return True
196+
if len(onlyLicenses) > 0 and (lice not in onlyLicenses):
197+
return False
198+
licenses = list(L)
199+
row, col = licenses.index(myLicense) + 1, licenses.index(lice) + 1
200+
201+
if LICENSE_MATRIX[row][col] == "1":
202+
return True
203+
return False
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
my/deps,PUBLIC,UNLICENSE,MIT,BOOST,BSD,ISC,NCSA,PSFL,APACHE,ECLIPSE,ACADEMIC_FREE,LGPL_X,LGPL_2,LGPL_3,LGPL_2_PLUS,LGPL_3_PLUS,GPL_X,GPL_2,GPL_3,GPL_2_PLUS,GPL_3_PLUS,AGPL_3_PLUS,MPL,EU,PROPRIETARY,NO_LICENSE
2+
PUBLIC,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3+
UNLICENSE,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
4+
MIT,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0
5+
BOOST,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0
6+
BSD,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0
7+
ISC,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0
8+
NCSA,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0
9+
PSFL,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0
10+
APACHE,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0
11+
ECLIPSE,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0
12+
ACADEMIC_FREE,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0
13+
LGPL_X,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
14+
LGPL_2,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
15+
LGPL_3,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
16+
LGPL_2_PLUS,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
17+
LGPL_3_PLUS,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
18+
GPL_X,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0
19+
GPL_2,1,1,1,1,1,1,1,1,0,0,0,1,1,0,1,0,1,1,0,1,0,0,1,1,0,0
20+
GPL_3,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,0,1,1,0,0
21+
GPL_2_PLUS,1,1,1,1,1,1,1,1,0,0,0,1,1,0,1,0,1,1,0,1,0,0,1,1,0,0
22+
GPL_3_PLUS,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,0,1,1,0,0
23+
AGPL_3_PLUS,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
24+
MPL,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0
25+
EU,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0
26+
PROPRIETARY,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
27+
NO_LICENSE,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0

0 commit comments

Comments
 (0)