Skip to content

Commit 63a968b

Browse files
committed
add JSON file + Python script to keep track of software licenses
1 parent 7eb455c commit 63a968b

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed

Diff for: licenses/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
see https://spdx.org/licenses
2+
3+
Python function to download SPDX list of licenses is available in `spdx.py`

Diff for: licenses/licenses.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"EasyBuild": {
3+
"spdx": "GPL-2.0-only",
4+
"license_url": "https://easybuild.io"
5+
},
6+
"GCCcore": {
7+
"spdx": "GPL-2.0-with-GCC-exception",
8+
"license_url": "https://github.com/gcc-mirror/gcc/blob/master/COPYING"
9+
}
10+
}

Diff for: licenses/spdx.py

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import json
2+
import logging
3+
import sys
4+
import urllib.request
5+
6+
SPDX_LICENSE_LIST_URL = 'https://raw.githubusercontent.com/spdx/license-list-data/main/json/licenses.json'
7+
8+
LICENSE_URL = 'license_url'
9+
SPDX = 'spdx'
10+
11+
spdx_license_list = None
12+
13+
# Configure the logging module
14+
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
15+
16+
17+
def get_spdx_license_list():
18+
"""
19+
Download JSON file with current list of SPDX licenses, parse it, and return it as a Python dictionary.
20+
"""
21+
global spdx_license_list
22+
23+
if spdx_license_list is None:
24+
with urllib.request.urlopen(SPDX_LICENSE_LIST_URL) as fp:
25+
spdx_license_list = json.load(fp)
26+
version, release_date = spdx_license_list['licenseListVersion'], spdx_license_list['releaseDate']
27+
logging.info(f"Downloaded version {version} of SPDX license list (release date: {release_date})")
28+
licenses = spdx_license_list['licenses']
29+
logging.info(f"Found info on {len(licenses)} licenses!")
30+
31+
return spdx_license_list
32+
33+
34+
def license_info(spdx_id):
35+
"""Find license with specified SPDX identifier."""
36+
37+
spdx_license_list = get_spdx_license_list()
38+
39+
licenses = spdx_license_list['licenses']
40+
for lic in licenses:
41+
if lic['licenseId'] == spdx_id:
42+
return lic
43+
44+
# if no match is found, return None as result
45+
return None
46+
47+
48+
def read_licenses(path):
49+
"""
50+
Read software project to license mapping from specified path
51+
"""
52+
with open(path) as fp:
53+
licenses = json.loads(fp.read())
54+
55+
return licenses
56+
57+
58+
def check_licenses(licenses):
59+
"""
60+
Check mapping of software licenses: make sure SPDX identifiers are valid.
61+
"""
62+
faulty_licenses = {}
63+
64+
for software_name in licenses:
65+
spdx_lic_id = licenses[software_name][SPDX]
66+
lic_info = license_info(spdx_lic_id)
67+
if lic_info:
68+
lic_url = licenses[software_name][LICENSE_URL]
69+
logging.info(f"License for software '{software_name}': {lic_info['name']} (see {lic_url})")
70+
else:
71+
logging.warning(f"Found faulty SPDX license ID for {software_name}: {spdx_lic_id}")
72+
faulty_licenses[software_name] = spdx_lic_id
73+
74+
if faulty_licenses:
75+
logging.warning(f"Found {len(faulty_licenses)} faulty SPDIX license IDs (out of {len(licenses)})!")
76+
result = False
77+
else:
78+
logging.info(f"License check passed for {len(licenses)} licenses!")
79+
result = True
80+
81+
return result
82+
83+
84+
def main(args):
85+
if len(args) == 1:
86+
licenses_path = args[0]
87+
else:
88+
logging.error("Usage: python spdx.py <path to licenses.json>")
89+
sys.exit(1)
90+
91+
licenses = read_licenses(licenses_path)
92+
if check_licenses(licenses):
93+
logging.info("All license checks PASSED!")
94+
else:
95+
logging.error("One or more licence checks failed!")
96+
sys.exit(2)
97+
98+
99+
if __name__ == '__main__':
100+
main(sys.argv[1:])

0 commit comments

Comments
 (0)