From 4997a23f15f5bb2cdb8deb979aeedf1f8c771929 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 14 Jul 2023 20:50:05 +0200 Subject: [PATCH] QbsProjectManager: Introduce QbsRequest It's going to be used in task tree for QbsBuildStep, QbsCleanStep and QbsInstallStep. Change-Id: I347562b72a628b66d648f943c2fbf67df69c0bc5 Reviewed-by: Christian Kandeler --- src/plugins/qbsprojectmanager/CMakeLists.txt | 1 + .../qbsprojectmanager/qbsprojectmanager.qbs | 2 + src/plugins/qbsprojectmanager/qbsrequest.cpp | 88 +++++++++++++++++++ src/plugins/qbsprojectmanager/qbsrequest.h | 52 +++++++++++ 4 files changed, 143 insertions(+) create mode 100644 src/plugins/qbsprojectmanager/qbsrequest.cpp create mode 100644 src/plugins/qbsprojectmanager/qbsrequest.h diff --git a/src/plugins/qbsprojectmanager/CMakeLists.txt b/src/plugins/qbsprojectmanager/CMakeLists.txt index 885edbf0bf7..3408e3f3ad0 100644 --- a/src/plugins/qbsprojectmanager/CMakeLists.txt +++ b/src/plugins/qbsprojectmanager/CMakeLists.txt @@ -25,6 +25,7 @@ add_qtc_plugin(QbsProjectManager qbsprojectmanagerconstants.h qbsprojectmanagerplugin.cpp qbsprojectmanagerplugin.h qbsprojectparser.cpp qbsprojectparser.h + qbsrequest.cpp qbsrequest.h qbssession.cpp qbssession.h qbssettings.cpp qbssettings.h ) diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs index 727507dda13..b5d671e8df9 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs +++ b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs @@ -54,6 +54,8 @@ QtcPlugin { "qbsprojectmanagerplugin.h", "qbsprojectparser.cpp", "qbsprojectparser.h", + "qbsrequest.cpp", + "qbsrequest.h", "qbssession.cpp", "qbssession.h", "qbssettings.cpp", diff --git a/src/plugins/qbsprojectmanager/qbsrequest.cpp b/src/plugins/qbsprojectmanager/qbsrequest.cpp new file mode 100644 index 00000000000..78624cfcead --- /dev/null +++ b/src/plugins/qbsprojectmanager/qbsrequest.cpp @@ -0,0 +1,88 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "qbsrequest.h" + +#include "qbsprojectmanagertr.h" +#include "qbssession.h" + +#include + +#include +#include + +using namespace ProjectExplorer; +using namespace Tasking; +using namespace Utils; + +namespace QbsProjectManager::Internal { + +QbsRequest::~QbsRequest() +{ + if (m_isRunning) + m_session->cancelCurrentJob(); +} + +void QbsRequest::setSession(QbsSession *session) +{ + QTC_ASSERT(!m_isRunning, return); + m_session = session; +} + +void QbsRequest::start() +{ + QTC_ASSERT(!m_isRunning, return); + QTC_ASSERT(m_session, emit done(false); return); + QTC_ASSERT(m_requestData, emit done(false); return); + + const auto handleDone = [this](const ErrorInfo &error) { + m_isRunning = false; + m_session->disconnect(this); + for (const ErrorInfoItem &item : error.items) { + emit outputAdded(item.description, BuildStep::OutputFormat::Stdout); + emit taskAdded(CompileTask(Task::Error, item.description, item.filePath, item.line)); + } + emit done(error.items.isEmpty()); + }; + connect(m_session, &QbsSession::projectBuilt, this, handleDone); + connect(m_session, &QbsSession::projectCleaned, this, handleDone); + connect(m_session, &QbsSession::projectInstalled, this, handleDone); + connect(m_session, &QbsSession::errorOccurred, this, [handleDone](QbsSession::Error error) { + handleDone(ErrorInfo(QbsSession::errorString(error))); + }); + connect(m_session, &QbsSession::taskStarted, this, [this](const QString &desciption, int max) { + m_description = desciption; + m_maxProgress = max; + }); + connect(m_session, &QbsSession::maxProgressChanged, this, [this](int max) { + m_maxProgress = max; + }); + connect(m_session, &QbsSession::taskProgress, this, [this](int progress) { + if (m_maxProgress > 0) + emit progressChanged(progress * 100 / m_maxProgress, m_description); + }); + connect(m_session, &QbsSession::commandDescription, this, [this](const QString &message) { + emit outputAdded(message, BuildStep::OutputFormat::Stdout); + }); + connect(m_session, &QbsSession::processResult, this, [this](const FilePath &executable, + const QStringList &arguments, + const FilePath &workingDir, + const QStringList &stdOut, + const QStringList &stdErr, + bool success) { + Q_UNUSED(workingDir); + const bool hasOutput = !stdOut.isEmpty() || !stdErr.isEmpty(); + if (success && !hasOutput) + return; + emit outputAdded(executable.toUserOutput() + ' ' + ProcessArgs::joinArgs(arguments), + BuildStep::OutputFormat::Stdout); + for (const QString &line : stdErr) + emit outputAdded(line, BuildStep::OutputFormat::Stderr); + for (const QString &line : stdOut) + emit outputAdded(line, BuildStep::OutputFormat::Stdout); + }); + m_isRunning = true; + m_session->sendRequest(*m_requestData); +} + +} // namespace QbsProjectManager::Internal diff --git a/src/plugins/qbsprojectmanager/qbsrequest.h b/src/plugins/qbsprojectmanager/qbsrequest.h new file mode 100644 index 00000000000..12b00a83fb6 --- /dev/null +++ b/src/plugins/qbsprojectmanager/qbsrequest.h @@ -0,0 +1,52 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +#include + +#include + +namespace QbsProjectManager::Internal { + +class QbsSession; + +class QbsRequest final : public QObject +{ + Q_OBJECT + +public: + ~QbsRequest() override; + + void setSession(QbsSession *session); + void setRequestData(const QJsonObject &requestData) { m_requestData = requestData; } + void start(); + +signals: + void done(bool success); + void progressChanged(int progress, const QString &info); // progress in % + void outputAdded(const QString &output, ProjectExplorer::BuildStep::OutputFormat format); + void taskAdded(const ProjectExplorer::Task &task); + +private: + QbsSession *m_session = nullptr; + std::optional m_requestData; + bool m_isRunning = false; + QString m_description; + int m_maxProgress = 100; +}; + +class QbsRequestTaskAdapter : public Tasking::TaskAdapter +{ +public: + QbsRequestTaskAdapter() { connect(task(), &QbsRequest::done, this, &TaskInterface::done); } + +private: + void start() final { task()->start(); } +}; + +} // namespace QbsProjectManager::Internal + +TASKING_DECLARE_TASK(QbsRequestTask, QbsProjectManager::Internal::QbsRequestTaskAdapter);