west: spdx: introduce support for SPDX 2.3

Minor update to existing zspdx implementation to add support for
PrimaryPackagePurpose introduced in SPDX 2.3.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
This commit is contained in:
Benjamin Cabé 2024-03-21 21:58:48 +01:00 committed by Carles Cufí
parent b4eac67b8b
commit 9ebf341977
5 changed files with 23 additions and 11 deletions

View file

@ -74,7 +74,7 @@ See :zephyr_file:`share/zephyr-package/cmake` for details.
Software bill of materials: ``west spdx``
*****************************************
This command generates SPDX 2.2 tag-value documents, creating relationships
This command generates SPDX 2.3 tag-value documents, creating relationships
from source files to the corresponding generated build files.
``SPDX-License-Identifier`` comments in source files are scanned and filled
into the SPDX documents.

View file

@ -68,6 +68,9 @@ class PackageConfig:
# SPDX ID, including "SPDXRef-"
self.spdxID = ""
# primary package purpose (ex. "LIBRARY", "APPLICATION", etc.)
self.primaryPurpose = ""
# the Package's declared license
self.declaredLicense = "NOASSERTION"
@ -95,7 +98,7 @@ class Package:
# Document that owns this Package
self.doc = doc
# verification code, calculated per section 3.9 of SPDX spec v2.2
# verification code, calculated per section 7.9 of SPDX spec v2.3
self.verificationCode = ""
# concluded license for this Package, if
@ -161,7 +164,7 @@ class RelationshipData:
self.otherPackageID = ""
# text string with Relationship type
# from table in section 7.1 of SPDX spec v2.2
# from table 68 in section 11.1 of SPDX spec v2.3
self.rlnType = ""
# Relationship contains the post-analysis, processed data about a relationship
@ -180,7 +183,7 @@ class Relationship:
self.refB = ""
# text string with Relationship type
# from table in section 7.1 of SPDX spec v2.2
# from table 68 in section 11.1 of SPDX spec v2.3
self.rlnType = ""
# File contains the data needed to create a File element in the context of a

View file

@ -30,7 +30,7 @@ class ScannerConfig:
self.numLinesScanned = 20
# should we calculate SHA256 hashes for each Package's Files?
# note that SHA1 hashes are mandatory, per SPDX 2.2
# note that SHA1 hashes are mandatory, per SPDX 2.3
self.doSHA256 = True
# should we calculate MD5 hashes for each Package's Files?

View file

@ -157,6 +157,7 @@ class Walker:
cfgPackageApp = PackageConfig()
cfgPackageApp.name = "app-sources"
cfgPackageApp.spdxID = "SPDXRef-app-sources"
cfgPackageApp.primaryPurpose = "SOURCE"
# relativeBaseDir is app sources dir
cfgPackageApp.relativeBaseDir = self.cm.paths_source
pkgApp = Package(cfgPackageApp, self.docApp)
@ -235,6 +236,7 @@ class Walker:
cfgPackageZephyrModule.name = module_name
cfgPackageZephyrModule.spdxID = "SPDXRef-" + module_name + "-sources"
cfgPackageZephyrModule.relativeBaseDir = module_path
cfgPackageZephyrModule.primaryPurpose = "SOURCE"
pkgZephyrModule = Package(cfgPackageZephyrModule, self.docZephyr)
self.docZephyr.pkgs[pkgZephyrModule.cfg.spdxID] = pkgZephyrModule
@ -313,6 +315,10 @@ class Walker:
if len(cfgTarget.target.artifacts) > 0:
# add its build file
bf = self.addBuildFile(cfgTarget, pkg)
if pkg.cfg.name == "zephyr_final":
pkg.cfg.primaryPurpose = "APPLICATION"
else:
pkg.cfg.primaryPurpose = "LIBRARY"
# get its source files if build file is found
if bf:

View file

@ -8,14 +8,14 @@ from west import log
from zspdx.util import getHashes
# Output tag-value SPDX 2.2 content for the given Relationship object.
# Output tag-value SPDX 2.3 content for the given Relationship object.
# Arguments:
# 1) f: file handle for SPDX document
# 2) rln: Relationship object being described
def writeRelationshipSPDX(f, rln):
f.write(f"Relationship: {rln.refA} {rln.rlnType} {rln.refB}\n")
# Output tag-value SPDX 2.2 content for the given File object.
# Output tag-value SPDX 2.3 content for the given File object.
# Arguments:
# 1) f: file handle for SPDX document
# 2) bf: File object being described
@ -42,7 +42,7 @@ FileChecksum: SHA1: {bf.sha1}
writeRelationshipSPDX(f, rln)
f.write("\n")
# Output tag-value SPDX 2.2 content for the given Package object.
# Output tag-value SPDX 2.3 content for the given Package object.
# Arguments:
# 1) f: file handle for SPDX document
# 2) pkg: Package object being described
@ -58,6 +58,9 @@ PackageLicenseConcluded: {pkg.concludedLicense}
PackageCopyrightText: {pkg.cfg.copyrightText}
""")
if pkg.cfg.primaryPurpose != "":
f.write(f"PrimaryPackagePurpose: {pkg.cfg.primaryPurpose}\n")
# flag whether files analyzed / any files present
if len(pkg.files) > 0:
if len(pkg.licenseInfoFromFiles) > 0:
@ -82,7 +85,7 @@ PackageCopyrightText: {pkg.cfg.copyrightText}
for bf in bfs:
writeFileSPDX(f, bf)
# Output tag-value SPDX 2.2 content for a custom license.
# Output tag-value SPDX 2.3 content for a custom license.
# Arguments:
# 1) f: file handle for SPDX document
# 2) lic: custom license ID being described
@ -93,12 +96,12 @@ LicenseName: {lic}
LicenseComment: Corresponds to the license ID `{lic}` detected in an SPDX-License-Identifier: tag.
""")
# Output tag-value SPDX 2.2 content for the given Document object.
# Output tag-value SPDX 2.3 content for the given Document object.
# Arguments:
# 1) f: file handle for SPDX document
# 2) doc: Document object being described
def writeDocumentSPDX(f, doc):
f.write(f"""SPDXVersion: SPDX-2.2
f.write(f"""SPDXVersion: SPDX-2.3
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: {doc.cfg.name}