Skip to content

Commit

Permalink
Merge pull request #400 from boegel/2023.06-software.eessi.io_licenses
Browse files Browse the repository at this point in the history
add JSON file + Python script to keep track of software licenses
  • Loading branch information
dagonzalezfo authored Jan 10, 2024
2 parents e838f3f + 0421bae commit f0deb14
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/test_licenses.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# documentation: https://help.github.com/en/articles/workflow-syntax-for-github-actions
name: Test software licenses
on: [push, pull_request]
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
build:
runs-on: ubuntu-20.04
steps:
- name: Check out software-layer repository
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0

- name: set up Python
uses: actions/setup-python@13ae5bb136fac2878aff31522b9efb785519f984 # v4.3.0
with:
python-version: '3.9'

- name: Check software licenses
run: |
python licenses/spdx.py licenses/licenses.json
3 changes: 3 additions & 0 deletions licenses/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
see https://spdx.org/licenses

Python function to download SPDX list of licenses is available in `spdx.py`
10 changes: 10 additions & 0 deletions licenses/licenses.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"EasyBuild": {
"spdx": "GPL-2.0-only",
"license_url": "https://easybuild.io"
},
"GCCcore": {
"spdx": "GPL-2.0-with-GCC-exception",
"license_url": "https://github.com/gcc-mirror/gcc/blob/master/COPYING"
}
}
100 changes: 100 additions & 0 deletions licenses/spdx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import json
import logging
import sys
import urllib.request

SPDX_LICENSE_LIST_URL = 'https://raw.githubusercontent.com/spdx/license-list-data/main/json/licenses.json'

LICENSE_URL = 'license_url'
SPDX = 'spdx'

spdx_license_list = None

# Configure the logging module
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")


def get_spdx_license_list():
"""
Download JSON file with current list of SPDX licenses, parse it, and return it as a Python dictionary.
"""
global spdx_license_list

if spdx_license_list is None:
with urllib.request.urlopen(SPDX_LICENSE_LIST_URL) as fp:
spdx_license_list = json.load(fp)
version, release_date = spdx_license_list['licenseListVersion'], spdx_license_list['releaseDate']
logging.info(f"Downloaded version {version} of SPDX license list (release date: {release_date})")
licenses = spdx_license_list['licenses']
logging.info(f"Found info on {len(licenses)} licenses!")

return spdx_license_list


def license_info(spdx_id):
"""Find license with specified SPDX identifier."""

spdx_license_list = get_spdx_license_list()

licenses = spdx_license_list['licenses']
for lic in licenses:
if lic['licenseId'] == spdx_id:
return lic

# if no match is found, return None as result
return None


def read_licenses(path):
"""
Read software project to license mapping from specified path
"""
with open(path) as fp:
licenses = json.loads(fp.read())

return licenses


def check_licenses(licenses):
"""
Check mapping of software licenses: make sure SPDX identifiers are valid.
"""
faulty_licenses = {}

for software_name in licenses:
spdx_lic_id = licenses[software_name][SPDX]
lic_info = license_info(spdx_lic_id)
if lic_info:
lic_url = licenses[software_name][LICENSE_URL]
logging.info(f"License for software '{software_name}': {lic_info['name']} (see {lic_url})")
else:
logging.warning(f"Found faulty SPDX license ID for {software_name}: {spdx_lic_id}")
faulty_licenses[software_name] = spdx_lic_id

if faulty_licenses:
logging.warning(f"Found {len(faulty_licenses)} faulty SPDIX license IDs (out of {len(licenses)})!")
result = False
else:
logging.info(f"License check passed for {len(licenses)} licenses!")
result = True

return result


def main(args):
if len(args) == 1:
licenses_path = args[0]
else:
logging.error("Usage: python spdx.py <path to licenses.json>")
sys.exit(1)

licenses = read_licenses(licenses_path)
if check_licenses(licenses):
logging.info("All license checks PASSED!")
else:
logging.error("One or more licence checks failed!")
sys.exit(2)


if __name__ == '__main__':
main(sys.argv[1:])

0 comments on commit f0deb14

Please sign in to comment.