diff -r 698660ef7350 -r c6afba2049cf eric7/CycloneDXInterface/CycloneDXConfigDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric7/CycloneDXInterface/CycloneDXConfigDialog.py Fri Jun 03 19:54:57 2022 +0200 @@ -0,0 +1,157 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to configure the CycloneDX SBOM generation. +""" + +import os + +from PyQt6.QtCore import pyqtSlot +from PyQt6.QtWidgets import QDialog + +from EricWidgets.EricApplication import ericApp +from EricWidgets.EricPathPicker import EricPathPickerModes + +from .Ui_CycloneDXConfigDialog import Ui_CycloneDXConfigDialog + + +class CycloneDXConfigDialog(QDialog, Ui_CycloneDXConfigDialog): + """ + Class implementing a dialog to configure the CycloneDX SBOM generation. + """ + SupportedSchemas = { + "JSON": ["1.4", "1.3", "1.2"], + "XML": ["1.4", "1.3", "1.2", "1.1", "1.0"], + } + Sources = { + "pipenv": "Pipfile.lock", + "poetry": "poetry.lock", + "requirements": "requirements.txt", + } + DefaultFileFormat = "JSON" + DefaultFileNames = { + "JSON": "cyclonedx.json", + "XML": "cyclonedx.xml", + } + + def __init__(self, environment, parent=None): + """ + Constructor + + @param environment name of the virtual environment + @type str + @param parent reference to the parent widget (defaults to None) + @type QWidget (optional) + """ + super().__init__(parent) + self.setupUi(self) + + if environment == "<project>": + project = ericApp().getObject("Project") + self.__defaultDirectory = project.getProjectPath() + else: + venvManager = ericApp().getObject("VirtualEnvManager") + self.__defaultDirectory = venvManager.getVirtualenvDirectory( + environment) + + self.environmentLabel.setText(environment) + + self.pipenvButton.setEnabled(os.path.isfile(os.path.join( + self.__defaultDirectory, + CycloneDXConfigDialog.Sources["pipenv"] + ))) + self.poetryButton.setEnabled(os.path.isfile(os.path.join( + self.__defaultDirectory, + CycloneDXConfigDialog.Sources["poetry"] + ))) + self.requirementsButton.setEnabled(os.path.isfile(os.path.join( + self.__defaultDirectory, + CycloneDXConfigDialog.Sources["requirements"] + ))) + + self.filePicker.setMode(EricPathPickerModes.SAVE_FILE_OVERWRITE_MODE) + self.filePicker.setDefaultDirectory(self.__defaultDirectory) + + self.fileFormatComboBox.setCurrentText( + CycloneDXConfigDialog.DefaultFileFormat) + self.on_fileFormatComboBox_currentTextChanged( + CycloneDXConfigDialog.DefaultFileFormat) + + msh = self.minimumSizeHint() + self.resize(max(self.width(), msh.width()), msh.height()) + + @pyqtSlot(str) + def on_fileFormatComboBox_currentTextChanged(self, fileFormat): + """ + Private slot to handle the selection of a SBOM file format. + + @param fileFormat selected format + @type str + """ + # re-populate the file schema combo box + self.schemaVersionComboBox.clear() + self.schemaVersionComboBox.addItems( + CycloneDXConfigDialog.SupportedSchemas[fileFormat]) + + # set the file filter + if fileFormat == "JSON": + self.filePicker.setFilters( + self.tr("JSON Files (*.json);;All Files (*)")) + elif fileFormat == "XML": + self.filePicker.setFilters( + self.tr("XML Files (*.xml);;All Files (*)")) + else: + self.filePicker.setFilters(self.tr("All Files (*)")) + + def getData(self): + """ + Public method to get the SBOM configuration data. + + @return tuple containing the input source, the input file name, the + file format, the schema version and the path of the SBOM file to + be written + @rtype tuple of (str, str, str, str, str) + """ + if self.environmentButton.isChecked(): + inputSource = "environment" + inputFile = None + elif self.pipenvButton.isChecked(): + inputSource = "pipenv" + inputFile = os.path.join( + self.__defaultDirectory, + CycloneDXConfigDialog.Sources["pipenv"] + ) + elif self.poetryButton.isChecked(): + inputSource = "poetry" + inputFile = os.path.join( + self.__defaultDirectory, + CycloneDXConfigDialog.Sources["poetry"] + ) + elif self.requirementsButton.isChecked(): + inputSource = "requirements" + inputFile = os.path.join( + self.__defaultDirectory, + CycloneDXConfigDialog.Sources["requirements"] + ) + else: + # should not happen + inputSource = None + inputFile = None + + fileFormat = self.fileFormatComboBox.currentText() + schemaVersion = self.schemaVersionComboBox.currentText() + sbomFile = self.filePicker.text() + if not sbomFile: + try: + sbomFile = os.path.join( + self.__defaultDirectory, + CycloneDXConfigDialog.DefaultFileNames[fileFormat] + ) + except KeyError: + # should not happen + sbomFile = None + + return inputSource, inputFile, fileFormat, schemaVersion, sbomFile