diff options
| author | Jaime Resano <Jaime.Resano-Aisa@qt.io> | 2025-02-13 17:30:45 +0100 |
|---|---|---|
| committer | Jaime Resano <Jaime.RESANO-AISA@qt.io> | 2025-03-11 13:41:54 +0000 |
| commit | 2384da479caa9fe36e64d0f0f3f8f69fff06d6be (patch) | |
| tree | fbf5a92e524045c732486870bd768ef29ce00949 /src/plugins/python/pythonbuildsystem.cpp | |
| parent | 69b9d6cb82d6231151258f880e3c579b4c2d4522 (diff) | |
Add pyproject.toml support for Python projects
This patch adds support for the standard Python project configuration
file: pyproject.toml. It is intended to replace *.pyproject files.
Task-number: QTCREATORBUG-22492
Task-number: PYSIDE-2714
Change-Id: I783ee7b49be23c61b0a501ef9bbd722cc652ad14
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Jaime Resano <Jaime.RESANO-AISA@qt.io>
Diffstat (limited to 'src/plugins/python/pythonbuildsystem.cpp')
| -rw-r--r-- | src/plugins/python/pythonbuildsystem.cpp | 73 |
1 files changed, 56 insertions, 17 deletions
diff --git a/src/plugins/python/pythonbuildsystem.cpp b/src/plugins/python/pythonbuildsystem.cpp index b8dc13c76bd..c16b6de77b2 100644 --- a/src/plugins/python/pythonbuildsystem.cpp +++ b/src/plugins/python/pythonbuildsystem.cpp @@ -3,6 +3,7 @@ #include "pythonbuildsystem.h" +#include "pyprojecttoml.h" #include "pythonbuildconfiguration.h" #include "pythonconstants.h" #include "pythonproject.h" @@ -10,9 +11,11 @@ #include <coreplugin/documentmanager.h> #include <coreplugin/messagemanager.h> +#include <coreplugin/textdocument.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/target.h> +#include <projectexplorer/taskhub.h> #include <qmljs/qmljsmodelmanagerinterface.h> @@ -216,28 +219,50 @@ void PythonBuildSystem::triggerParsing() emitBuildSystemUpdated(); } +/*! + \brief Saves the build system configuration in the corresponding project file. + Currently, three project file formats are supported: pyproject.toml, *.pyproject and the legacy + *.pyqtc file. + \returns true if the save was successful, false otherwise. +*/ bool PythonBuildSystem::save() { const FilePath filePath = projectFilePath(); - const QStringList rawList = Utils::transform(m_files, &FileEntry::rawEntry); + const QStringList projectFiles = Utils::transform(m_files, &FileEntry::rawEntry); const FileChangeBlocker changeGuard(filePath); QByteArray newContents; - // New project file - if (filePath.endsWith(".pyproject")) { + if (filePath.fileName() == "pyproject.toml") { + Core::BaseTextDocument projectFile; + QString pyProjectTomlContent; + QString readingError; + auto result = projectFile.read(filePath, &pyProjectTomlContent, &readingError); + if (result != TextFileFormat::ReadSuccess) { + MessageManager::writeDisrupting(readingError); + return false; + } + auto newPyProjectToml = updatePyProjectTomlContent(pyProjectTomlContent, projectFiles); + if (!newPyProjectToml) { + MessageManager::writeDisrupting(newPyProjectToml.error()); + return false; + } + newContents = newPyProjectToml.value().toUtf8(); + } else if (filePath.endsWith(".pyproject")) { + // *.pyproject project file expected_str<QByteArray> contents = filePath.fileContents(); - if (contents) { - QJsonDocument doc = QJsonDocument::fromJson(*contents); - QJsonObject project = doc.object(); - project["files"] = QJsonArray::fromStringList(rawList); - doc.setObject(project); - newContents = doc.toJson(); - } else { + if (!contents) { MessageManager::writeDisrupting(contents.error()); + return false; } - } else { // Old project file - newContents = rawList.join('\n').toUtf8(); + QJsonDocument doc = QJsonDocument::fromJson(*contents); + QJsonObject project = doc.object(); + project["files"] = QJsonArray::fromStringList(projectFiles); + doc.setObject(project); + newContents = doc.toJson(); + } else { + // Old project file + newContents = projectFiles.join('\n').toUtf8(); } const expected_str<qint64> writeResult = filePath.writeFileContents(newContents); @@ -326,14 +351,14 @@ void PythonBuildSystem::parse() QStringList qmlImportPaths; const FilePath filePath = projectFilePath(); - // The PySide project file is JSON based + QString errorMessage; if (filePath.endsWith(".pyproject")) { - QString errorMessage; + // The PySide .pyproject file is JSON based files = readLinesJson(filePath, &errorMessage); - if (!errorMessage.isEmpty()) + if (!errorMessage.isEmpty()) { MessageManager::writeFlashing(errorMessage); - - errorMessage.clear(); + errorMessage.clear(); + } qmlImportPaths = readImportPathsJson(filePath, &errorMessage); if (!errorMessage.isEmpty()) MessageManager::writeFlashing(errorMessage); @@ -341,6 +366,20 @@ void PythonBuildSystem::parse() // To keep compatibility with PyQt we keep the compatibility with plain // text files as project files. files = readLines(filePath); + } else if (filePath.fileName() == "pyproject.toml") { + auto pyProjectTomlParseResult = parsePyProjectToml(filePath); + + TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); + for (const PyProjectTomlError &error : pyProjectTomlParseResult.errors) { + TaskHub::addTask( + BuildSystemTask(Task::TaskType::Error, error.description, filePath, error.line)); + } + + if (!pyProjectTomlParseResult.projectName.isEmpty()) { + project()->setDisplayName(pyProjectTomlParseResult.projectName); + } + + files = pyProjectTomlParseResult.projectFiles; } m_files = processEntries(files); |
