--- a/src/eric7/CycloneDXInterface/CycloneDXUtilities.py Sat Nov 12 17:49:08 2022 +0100 +++ b/src/eric7/CycloneDXInterface/CycloneDXUtilities.py Sun Nov 13 14:10:57 2022 +0100 @@ -7,8 +7,12 @@ Module implementing the interface to CycloneDX. """ +import contextlib +import json import os +from xml.etree import ElementTree + from cyclonedx.model import ( ExternalReference, ExternalReferenceType, @@ -91,6 +95,7 @@ sbomFile, withVulnerabilities, withDependencies, + readableOutput, metadataDict, ) = dlg.getData() @@ -162,16 +167,68 @@ "V{0}".format(schemaVersion.replace(".", "_")) ], ) - output.output_to_file(filename=sbomFile, allow_overwrite=True) + outputStr = output.output_as_string() + if readableOutput: + if fileFormat == "XML": + outputStr = _prettifyXML(outputStr) + elif fileFormat == "JSON": + outputStr = _prettifyJSON(outputStr) + + try: + with open(sbomFile, "w", encoding="utf-8") as f: + f.write(outputStr) + EricMessageBox.information( + None, + QCoreApplication.translate("CycloneDX", "CycloneDX - SBOM Creation"), + QCoreApplication.translate( + "CycloneDX", "<p>The SBOM data was written to file <b>{0}</b>.</p>" + ).format(sbomFile), + ) + except OSError as err: + EricMessageBox.critical( + None, + QCoreApplication.translate("CycloneDX", "CycloneDX - SBOM Creation"), + QCoreApplication.translate( + "CycloneDX", + "<p>The SBOM file <b>{0}</b> could not be written.</p>" + "<p>Reason: {1}</p>", + ).format(sbomFile, str(err)), + ) + - EricMessageBox.information( - None, - QCoreApplication.translate("CycloneDX", "CycloneDX - SBOM Creation"), - QCoreApplication.translate( - "CycloneDX", "<p>The SBOM data was written to file <b>{0}</b>.</p>" - ).format(sbomFile), +def _prettifyXML(inputStr): + """ + Function to prettify the SBOM XML output generated by CycloneDX. + + Note: Prettifying an XML tree works only with Python 3.9 and above! + + @param inputStr output generated by CycloneDX + @type str + @return prettified SBOM string + @rtype str + """ + tree = ElementTree.fromstring(inputStr) + with contextlib.suppress(AttributeError): + ElementTree.indent(tree) + return '<?xml version="1.0" encoding="UTF-8"?>\n' + ElementTree.tostring( + tree, encoding="unicode" ) + return inputStr + + +def _prettifyJSON(inputStr): + """ + Function to prettify the SBOM JSON output generated by CycloneDX. + + @param inputStr output generated by CycloneDX + @type str + @return prettified SBOM string + @rtype str + """ + sbom = json.loads(inputStr) + return json.dumps(sbom, indent=" ") + def addCycloneDXVulnerabilities(parser): """