File indexing completed on 2024-04-21 14:53:11

0001 #!/usr/bin/env python3
0002 # SPDX-FileCopyrightText: 2020 Andreas Cord-Landwehr <cordlandwehr@kde.org>
0003 # SPDX-License-Identifier: BSD-3-Clause
0004 
0005 # key    : outbound license identifier
0006 # values : list of acceptable licenses that are compatible with outbound license
0007 compatibilityMatrix = {
0008     "MIT": [
0009         "CC0-1.0",
0010         "MIT"],
0011     "BSD-2-Clause": [
0012         "CC0-1.0",
0013         "MIT",
0014         "BSD-2-Clause"],
0015     "BSD-3-Clause": [
0016         "CC0-1.0",
0017         "MIT",
0018         "BSD-2-Clause",
0019         "BSD-3-Clause"],
0020     "LGPL-2.0-only": [
0021         "CC0-1.0",
0022         "LGPL-2.0-only",
0023         "LGPL-2.0-or-later",
0024         "MIT",
0025         "BSD-2-Clause",
0026         "BSD-3-Clause",
0027         "bzip2-1.0.6"],
0028     "LGPL-2.1-only": [
0029         "CC0-1.0",
0030         "LGPL-2.0-or-later",
0031         "LGPL-2.1-only",
0032         "LGPL-2.1-or-later",
0033         "MIT",
0034         "BSD-2-Clause",
0035         "BSD-3-Clause",
0036         "bzip2-1.0.6"],
0037     "LGPL-3.0-only": [
0038         "CC0-1.0",
0039         "LGPL-2.0-or-later",
0040         "LGPL-2.1-or-later",
0041         "LGPL-3.0-only",
0042         "LGPL-3.0-or-later",
0043         "LicenseRef-KDE-Accepted-LGPL",
0044         "MIT",
0045         "BSD-2-Clause",
0046         "BSD-3-Clause",
0047         "bzip2-1.0.6"],
0048     "GPL-2.0-only": [
0049         "CC0-1.0",
0050         "LGPL-2.0-only",
0051         "LGPL-2.1-only",
0052         "LGPL-2.0-or-later",
0053         "LGPL-2.1-or-later",
0054         "GPL-2.0-only",
0055         "GPL-2.0-or-later",
0056         "MIT",
0057         "BSD-2-Clause",
0058         "BSD-3-Clause",
0059         "bzip2-1.0.6"],
0060     "GPL-3.0-only": [
0061         "CC0-1.0",
0062         "LGPL-2.0-or-later",
0063         "LGPL-2.1-or-later",
0064         "LGPL-3.0-only",
0065         "LGPL-3.0-or-later",
0066         "GPL-2.0-or-later",
0067         "GPL-3.0-only",
0068         "GPL-3.0-or-later",
0069         "LicenseRef-KDE-Accepted-GPL",
0070         "LicenseRef-KDE-Accepted-LGPL",
0071         "MIT",
0072         "BSD-2-Clause",
0073         "BSD-3-Clause",
0074         "bzip2-1.0.6"]
0075 }
0076 
0077 def check_outbound_license(license, files, spdxDictionary):
0078     """
0079     Asserts that the list of source files @p files, when combined into
0080     a library or executable, can be delivered under the combined license @p license .
0081     """
0082     print("Checking Target License: " + license)
0083     if not license in compatibilityMatrix:
0084         print("Error: unknown license selected")
0085         return False
0086 
0087     allLicensesAreCompatible = True
0088 
0089     for sourceFile in files:
0090         compatible = False
0091         sourceFileStripped = sourceFile.strip()
0092         for fileLicense in spdxDictionary[sourceFileStripped]:
0093             if fileLicense in compatibilityMatrix[license]:
0094                 compatible = True
0095                 print("OK " + sourceFileStripped + " : " + fileLicense)
0096         if not compatible:
0097             allLicensesAreCompatible = False
0098             print("-- " + sourceFileStripped + " : ( " + ", ".join([str(i) for i in spdxDictionary[sourceFileStripped]]) + " )")
0099     return allLicensesAreCompatible
0100 
0101 if __name__ == '__main__':
0102     print("Parsing SPDX BOM file")
0103     import sys
0104     import argparse
0105 
0106     # parse commands
0107     parser = argparse.ArgumentParser()
0108     parser.add_argument("-l", "--license", help="set outbound license to test")
0109     parser.add_argument("-s", "--spdx", help="spdx bill-of-materials file")
0110     parser.add_argument("-i", "--input", help="input file with list of source files to test")
0111     args = parser.parse_args()
0112 
0113     # TODO check if required arguments are present and give meaningful feedback
0114 
0115     # collect name and licenses from SPDX blocks
0116     spdxDictionary = {}
0117     fileName = ""
0118     licenses = []
0119     f = open(args.spdx, "r")
0120     for line in f:
0121         if line.startswith("FileName:"):
0122             # strip "FileName: "
0123             # thus name expected to start with "./", which is relative to CMAKE_SOURCE_DIR
0124             fileName = line[10:].strip()
0125         if line.startswith("LicenseInfoInFile:"):
0126             licenses.append(line[19:].strip())
0127         if line == '' or line == "\n":
0128             spdxDictionary[fileName] = licenses
0129             fileName = ""
0130             licenses = []
0131     f.close()
0132 
0133     spdxDictionary[fileName] = licenses
0134 
0135     # read file with list of test files
0136     f = open(args.input, "r")
0137     testfiles = f.readlines()
0138     f.close()
0139 
0140     if check_outbound_license(args.license, testfiles, spdxDictionary) is True:
0141         sys.exit(0)
0142 
0143     # in any other case, return error code
0144     sys.exit(1)