summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorJoshua Watt <JPEWhacker@gmail.com>2021-09-01 13:44:50 (GMT)
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-09-03 08:53:28 (GMT)
commit902480107dd0db7b77ada4654d2e0f061a04765d (patch)
tree8078d3cb307999d69d1eba7360d1455b06d303fa /meta
parent0d5c2d9f352bb6e81d6e4f2592a074195c26f578 (diff)
downloadpoky-902480107dd0db7b77ada4654d2e0f061a04765d.tar.gz
classes/create-spdx: Fix up license reporting
Licenses reported in the SPDX documents should be either: A) A valid SPDX identifier cross referenced from the SPDX license database B) A "LicenseRef" to a license described in the SPDX document The licensing code will now add a placeholder extracted license with corresponding "LicenseRef" for any licenses that are not matched to the SPDX database Parenthesis in the license expression are now handled correctly (From OE-Core rev: 28d9d035c0ff8fcaf28bc96a976a43a602a47e94) Signed-off-by: Joshua Watt <JPEWhacker@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/classes/create-spdx.bbclass55
-rw-r--r--meta/lib/oe/spdx.py8
2 files changed, 55 insertions, 8 deletions
diff --git a/meta/classes/create-spdx.bbclass b/meta/classes/create-spdx.bbclass
index 72c1385..2e13b19 100644
--- a/meta/classes/create-spdx.bbclass
+++ b/meta/classes/create-spdx.bbclass
@@ -23,6 +23,8 @@ SPDX_ARCHIVE_PACKAGED ??= "0"
23SPDX_UUID_NAMESPACE ??= "sbom.openembedded.org" 23SPDX_UUID_NAMESPACE ??= "sbom.openembedded.org"
24SPDX_NAMESPACE_PREFIX ??= "http://spdx.org/spdxdoc" 24SPDX_NAMESPACE_PREFIX ??= "http://spdx.org/spdxdoc"
25 25
26SPDX_LICENSES ??= "${COREBASE}/meta/files/spdx-licenses.json"
27
26do_image_complete[depends] = "virtual/kernel:do_create_spdx" 28do_image_complete[depends] = "virtual/kernel:do_create_spdx"
27 29
28def get_doc_namespace(d, doc): 30def get_doc_namespace(d, doc):
@@ -36,21 +38,54 @@ def is_work_shared(d):
36 return bb.data.inherits_class('kernel', d) or pn.startswith('gcc-source') 38 return bb.data.inherits_class('kernel', d) or pn.startswith('gcc-source')
37 39
38 40
39def convert_license_to_spdx(lic, d): 41python() {
42 import json
43 if d.getVar("SPDX_LICENSE_DATA"):
44 return
45
46 with open(d.getVar("SPDX_LICENSES"), "r") as f:
47 d.setVar("SPDX_LICENSE_DATA", json.load(f))
48}
49
50def convert_license_to_spdx(lic, document, d):
51 import oe.spdx
52
53 license_data = d.getVar("SPDX_LICENSE_DATA")
40 def convert(l): 54 def convert(l):
55 if l == "(" or l == ")":
56 return l
57
41 if l == "&": 58 if l == "&":
42 return "AND" 59 return "AND"
43 60
44 if l == "|": 61 if l == "|":
45 return "OR" 62 return "OR"
46 63
47 spdx = d.getVarFlag('SPDXLICENSEMAP', l) 64 spdx_license = d.getVarFlag("SPDXLICENSEMAP", l) or l
48 if spdx is not None: 65 for lic_data in license_data["licenses"]:
49 return spdx 66 if lic_data["licenseId"] == spdx_license:
67 return spdx_license
68
69 spdx_license = "LicenseRef-" + l
70 for spdx_lic in document.hasExtractedLicensingInfos:
71 if spdx_lic.licenseId == spdx_license:
72 return spdx_license
73
74 bb.warn("No SPDX License found for %s. Creating a place holder" % l)
75
76 spdx_lic = oe.spdx.SPDXExtractedLicensingInfo()
77 spdx_lic.name = l
78 spdx_lic.licenseId = spdx_license
79 # TODO: Extract the actual license text from the common license files
80 spdx_lic.extractedText = "This software is licensed under the %s license" % l
81
82 document.hasExtractedLicensingInfos.append(spdx_lic)
83
84 return spdx_license
50 85
51 return l 86 lic_split = lic.replace("(", " ( ").replace(")", " ) ").split()
52 87
53 return ' '.join(convert(l) for l in lic.split()) 88 return ' '.join(convert(l) for l in lic_split)
54 89
55 90
56def process_sources(d): 91def process_sources(d):
@@ -334,6 +369,7 @@ python do_create_spdx() {
334 doc.documentNamespace = get_doc_namespace(d, doc) 369 doc.documentNamespace = get_doc_namespace(d, doc)
335 doc.creationInfo.created = creation_time 370 doc.creationInfo.created = creation_time
336 doc.creationInfo.comment = "This document was created by analyzing recipe files during the build." 371 doc.creationInfo.comment = "This document was created by analyzing recipe files during the build."
372 doc.creationInfo.licenseListVersion = d.getVar("SPDX_LICENSE_DATA")["licenseListVersion"]
337 doc.creationInfo.creators.append("Tool: OpenEmbedded Core create-spdx.bbclass") 373 doc.creationInfo.creators.append("Tool: OpenEmbedded Core create-spdx.bbclass")
338 doc.creationInfo.creators.append("Organization: OpenEmbedded ()") 374 doc.creationInfo.creators.append("Organization: OpenEmbedded ()")
339 doc.creationInfo.creators.append("Person: N/A ()") 375 doc.creationInfo.creators.append("Person: N/A ()")
@@ -353,7 +389,7 @@ python do_create_spdx() {
353 389
354 license = d.getVar("LICENSE") 390 license = d.getVar("LICENSE")
355 if license: 391 if license:
356 recipe.licenseDeclared = convert_license_to_spdx(license, d) 392 recipe.licenseDeclared = convert_license_to_spdx(license, doc, d)
357 393
358 summary = d.getVar("SUMMARY") 394 summary = d.getVar("SUMMARY")
359 if summary: 395 if summary:
@@ -422,6 +458,7 @@ python do_create_spdx() {
422 package_doc.documentNamespace = get_doc_namespace(d, package_doc) 458 package_doc.documentNamespace = get_doc_namespace(d, package_doc)
423 package_doc.creationInfo.created = creation_time 459 package_doc.creationInfo.created = creation_time
424 package_doc.creationInfo.comment = "This document was created by analyzing packages created during the build." 460 package_doc.creationInfo.comment = "This document was created by analyzing packages created during the build."
461 package_doc.creationInfo.licenseListVersion = d.getVar("SPDX_LICENSE_DATA")["licenseListVersion"]
425 package_doc.creationInfo.creators.append("Tool: OpenEmbedded Core create-spdx.bbclass") 462 package_doc.creationInfo.creators.append("Tool: OpenEmbedded Core create-spdx.bbclass")
426 package_doc.creationInfo.creators.append("Organization: OpenEmbedded ()") 463 package_doc.creationInfo.creators.append("Organization: OpenEmbedded ()")
427 package_doc.creationInfo.creators.append("Person: N/A ()") 464 package_doc.creationInfo.creators.append("Person: N/A ()")
@@ -441,7 +478,7 @@ python do_create_spdx() {
441 spdx_package.SPDXID = oe.sbom.get_package_spdxid(pkg_name) 478 spdx_package.SPDXID = oe.sbom.get_package_spdxid(pkg_name)
442 spdx_package.name = pkg_name 479 spdx_package.name = pkg_name
443 spdx_package.versionInfo = d.getVar("PV") 480 spdx_package.versionInfo = d.getVar("PV")
444 spdx_package.licenseDeclared = convert_license_to_spdx(package_license, d) 481 spdx_package.licenseDeclared = convert_license_to_spdx(package_license, package_doc, d)
445 482
446 package_doc.packages.append(spdx_package) 483 package_doc.packages.append(spdx_package)
447 484
@@ -561,6 +598,7 @@ python do_create_runtime_spdx() {
561 runtime_doc.documentNamespace = get_doc_namespace(localdata, runtime_doc) 598 runtime_doc.documentNamespace = get_doc_namespace(localdata, runtime_doc)
562 runtime_doc.creationInfo.created = creation_time 599 runtime_doc.creationInfo.created = creation_time
563 runtime_doc.creationInfo.comment = "This document was created by analyzing package runtime dependencies." 600 runtime_doc.creationInfo.comment = "This document was created by analyzing package runtime dependencies."
601 runtime_doc.creationInfo.licenseListVersion = d.getVar("SPDX_LICENSE_DATA")["licenseListVersion"]
564 runtime_doc.creationInfo.creators.append("Tool: OpenEmbedded Core create-spdx.bbclass") 602 runtime_doc.creationInfo.creators.append("Tool: OpenEmbedded Core create-spdx.bbclass")
565 runtime_doc.creationInfo.creators.append("Organization: OpenEmbedded ()") 603 runtime_doc.creationInfo.creators.append("Organization: OpenEmbedded ()")
566 runtime_doc.creationInfo.creators.append("Person: N/A ()") 604 runtime_doc.creationInfo.creators.append("Person: N/A ()")
@@ -720,6 +758,7 @@ python image_combine_spdx() {
720 doc.documentNamespace = get_doc_namespace(d, doc) 758 doc.documentNamespace = get_doc_namespace(d, doc)
721 doc.creationInfo.created = creation_time 759 doc.creationInfo.created = creation_time
722 doc.creationInfo.comment = "This document was created by analyzing the source of the Yocto recipe during the build." 760 doc.creationInfo.comment = "This document was created by analyzing the source of the Yocto recipe during the build."
761 doc.creationInfo.licenseListVersion = d.getVar("SPDX_LICENSE_DATA")["licenseListVersion"]
723 doc.creationInfo.creators.append("Tool: OpenEmbedded Core create-spdx.bbclass") 762 doc.creationInfo.creators.append("Tool: OpenEmbedded Core create-spdx.bbclass")
724 doc.creationInfo.creators.append("Organization: OpenEmbedded ()") 763 doc.creationInfo.creators.append("Organization: OpenEmbedded ()")
725 doc.creationInfo.creators.append("Person: N/A ()") 764 doc.creationInfo.creators.append("Person: N/A ()")
diff --git a/meta/lib/oe/spdx.py b/meta/lib/oe/spdx.py
index 3f569c6..9814fbf 100644
--- a/meta/lib/oe/spdx.py
+++ b/meta/lib/oe/spdx.py
@@ -189,6 +189,13 @@ class SPDXExternalDocumentRef(SPDXObject):
189 checksum = _Object(SPDXChecksum) 189 checksum = _Object(SPDXChecksum)
190 190
191 191
192class SPDXExtractedLicensingInfo(SPDXObject):
193 name = _String()
194 comment = _String()
195 licenseId = _String()
196 extractedText = _String()
197
198
192class SPDXDocument(SPDXObject): 199class SPDXDocument(SPDXObject):
193 spdxVersion = _String(default="SPDX-" + SPDX_VERSION) 200 spdxVersion = _String(default="SPDX-" + SPDX_VERSION)
194 dataLicense = _String(default="CC0-1.0") 201 dataLicense = _String(default="CC0-1.0")
@@ -200,6 +207,7 @@ class SPDXDocument(SPDXObject):
200 files = _ObjectList(SPDXFile) 207 files = _ObjectList(SPDXFile)
201 relationships = _ObjectList(SPDXRelationship) 208 relationships = _ObjectList(SPDXRelationship)
202 externalDocumentRefs = _ObjectList(SPDXExternalDocumentRef) 209 externalDocumentRefs = _ObjectList(SPDXExternalDocumentRef)
210 hasExtractedLicensingInfos = _ObjectList(SPDXExtractedLicensingInfo)
203 211
204 def __init__(self, **d): 212 def __init__(self, **d):
205 super().__init__(**d) 213 super().__init__(**d)