123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- # Copyright (c) 2020, 2021 The Linux Foundation
- #
- # SPDX-License-Identifier: Apache-2.0
- from datetime import datetime
- from west import log
- from zspdx.util import getHashes
- # Output tag-value SPDX 2.2 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.
- # Arguments:
- # 1) f: file handle for SPDX document
- # 2) bf: File object being described
- def writeFileSPDX(f, bf):
- f.write(f"""FileName: ./{bf.relpath}
- SPDXID: {bf.spdxID}
- FileChecksum: SHA1: {bf.sha1}
- """)
- if bf.sha256 != "":
- f.write(f"FileChecksum: SHA256: {bf.sha256}\n")
- if bf.md5 != "":
- f.write(f"FileChecksum: MD5: {bf.md5}\n")
- f.write(f"LicenseConcluded: {bf.concludedLicense}\n")
- if len(bf.licenseInfoInFile) == 0:
- f.write(f"LicenseInfoInFile: NONE\n")
- else:
- for licInfoInFile in bf.licenseInfoInFile:
- f.write(f"LicenseInfoInFile: {licInfoInFile}\n")
- f.write(f"FileCopyrightText: {bf.copyrightText}\n\n")
- # write file relationships
- if len(bf.rlns) > 0:
- for rln in bf.rlns:
- writeRelationshipSPDX(f, rln)
- f.write("\n")
- # Output tag-value SPDX 2.2 content for the given Package object.
- # Arguments:
- # 1) f: file handle for SPDX document
- # 2) pkg: Package object being described
- def writePackageSPDX(f, pkg):
- f.write(f"""##### Package: {pkg.cfg.name}
- PackageName: {pkg.cfg.name}
- SPDXID: {pkg.cfg.spdxID}
- PackageDownloadLocation: NOASSERTION
- PackageLicenseConcluded: {pkg.concludedLicense}
- """)
- for licFromFiles in pkg.licenseInfoFromFiles:
- f.write(f"PackageLicenseInfoFromFiles: {licFromFiles}\n")
- f.write(f"""PackageLicenseDeclared: {pkg.cfg.declaredLicense}
- PackageCopyrightText: {pkg.cfg.copyrightText}
- """)
- # flag whether files analyzed / any files present
- if len(pkg.files) > 0:
- f.write(f"FilesAnalyzed: true\nPackageVerificationCode: {pkg.verificationCode}\n\n")
- else:
- f.write(f"FilesAnalyzed: false\nPackageComment: Utility target; no files\n\n")
- # write package relationships
- if len(pkg.rlns) > 0:
- for rln in pkg.rlns:
- writeRelationshipSPDX(f, rln)
- f.write("\n")
- # write package files, if any
- if len(pkg.files) > 0:
- bfs = list(pkg.files.values())
- bfs.sort(key = lambda x: x.relpath)
- for bf in bfs:
- writeFileSPDX(f, bf)
- # Output tag-value SPDX 2.2 content for a custom license.
- # Arguments:
- # 1) f: file handle for SPDX document
- # 2) lic: custom license ID being described
- def writeOtherLicenseSPDX(f, lic):
- f.write(f"""LicenseID: {lic}
- ExtractedText: {lic}
- 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.
- # 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
- DataLicense: CC0-1.0
- SPDXID: SPDXRef-DOCUMENT
- DocumentName: {doc.cfg.name}
- DocumentNamespace: {doc.cfg.namespace}
- Creator: Tool: Zephyr SPDX builder
- Created: {datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")}
- """)
- # write any external document references
- if len(doc.externalDocuments) > 0:
- extDocs = list(doc.externalDocuments)
- extDocs.sort(key = lambda x: x.cfg.docRefID)
- for extDoc in extDocs:
- f.write(f"ExternalDocumentRef: {extDoc.cfg.docRefID} {extDoc.cfg.namespace} SHA1: {extDoc.myDocSHA1}\n")
- f.write(f"\n")
- # write relationships owned by this Document (not by its Packages, etc.), if any
- if len(doc.relationships) > 0:
- for rln in doc.relationships:
- writeRelationshipSPDX(f, rln)
- f.write(f"\n")
- # write packages
- for pkg in doc.pkgs.values():
- writePackageSPDX(f, pkg)
- # write other license info, if any
- if len(doc.customLicenseIDs) > 0:
- for lic in list(doc.customLicenseIDs).sort():
- writeOtherLicenseSPDX(f, lic)
- # Open SPDX document file for writing, write the document, and calculate
- # its hash for other referring documents to use.
- # Arguments:
- # 1) spdxPath: path to write SPDX document
- # 2) doc: SPDX Document object to write
- def writeSPDX(spdxPath, doc):
- # create and write document to disk
- try:
- log.inf(f"Writing SPDX document {doc.cfg.name} to {spdxPath}")
- with open(spdxPath, "w") as f:
- writeDocumentSPDX(f, doc)
- except OSError as e:
- log.err(f"Error: Unable to write to {spdxPath}: {str(e)}")
- return False
- # calculate hash of the document we just wrote
- hashes = getHashes(spdxPath)
- if not hashes:
- log.err(f"Error: created document but unable to calculate hash values")
- return False
- doc.myDocSHA1 = hashes[0]
- return True
|