From 9ebf3419772f715d8dead595524798c4085e3b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 21 Mar 2024 21:58:48 +0100 Subject: [PATCH] west: spdx: introduce support for SPDX 2.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Minor update to existing zspdx implementation to add support for PrimaryPackagePurpose introduced in SPDX 2.3. Signed-off-by: Benjamin Cabé --- doc/develop/west/zephyr-cmds.rst | 2 +- scripts/west_commands/zspdx/datatypes.py | 9 ++++++--- scripts/west_commands/zspdx/scanner.py | 2 +- scripts/west_commands/zspdx/walker.py | 6 ++++++ scripts/west_commands/zspdx/writer.py | 15 +++++++++------ 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/doc/develop/west/zephyr-cmds.rst b/doc/develop/west/zephyr-cmds.rst index 6037cb422b2..f10c4abe36b 100644 --- a/doc/develop/west/zephyr-cmds.rst +++ b/doc/develop/west/zephyr-cmds.rst @@ -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. diff --git a/scripts/west_commands/zspdx/datatypes.py b/scripts/west_commands/zspdx/datatypes.py index 1e65d96e995..ca7b92d1cbf 100644 --- a/scripts/west_commands/zspdx/datatypes.py +++ b/scripts/west_commands/zspdx/datatypes.py @@ -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 diff --git a/scripts/west_commands/zspdx/scanner.py b/scripts/west_commands/zspdx/scanner.py index 02987c0cd8e..9f81ede6c7c 100644 --- a/scripts/west_commands/zspdx/scanner.py +++ b/scripts/west_commands/zspdx/scanner.py @@ -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? diff --git a/scripts/west_commands/zspdx/walker.py b/scripts/west_commands/zspdx/walker.py index 0c6469444ed..45e63b29543 100644 --- a/scripts/west_commands/zspdx/walker.py +++ b/scripts/west_commands/zspdx/walker.py @@ -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: diff --git a/scripts/west_commands/zspdx/writer.py b/scripts/west_commands/zspdx/writer.py index b8afaa47953..a6bdddae52d 100644 --- a/scripts/west_commands/zspdx/writer.py +++ b/scripts/west_commands/zspdx/writer.py @@ -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}