From c88a82905921565053a43beec0ca50c4e0d7f583 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 22 Nov 2022 12:29:02 +0100 Subject: [PATCH] RsyncDeployService: Reuse TaskTree Change-Id: I411726e47550da5fd3269fcbb3e4f3e19096adeb Reviewed-by: Christian Kandeler Reviewed-by: --- .../devicesupport/filetransfer.h | 7 + src/plugins/remotelinux/linuxdevicetester.cpp | 2 +- src/plugins/remotelinux/rsyncdeploystep.cpp | 128 +++++++++--------- 3 files changed, 74 insertions(+), 63 deletions(-) diff --git a/src/plugins/projectexplorer/devicesupport/filetransfer.h b/src/plugins/projectexplorer/devicesupport/filetransfer.h index 75354a0df7e..761d083ad2e 100644 --- a/src/plugins/projectexplorer/devicesupport/filetransfer.h +++ b/src/plugins/projectexplorer/devicesupport/filetransfer.h @@ -50,9 +50,16 @@ class PROJECTEXPLORER_EXPORT FileTransferAdapter : public Utils::Tasking::TaskAd { public: FileTransferAdapter(); + void start() override { task()->start(); } +}; + +class PROJECTEXPLORER_EXPORT FileTransferTestAdapter : public FileTransferAdapter +{ +public: void start() final { task()->test(); } }; } // namespace ProjectExplorer QTC_DECLARE_CUSTOM_TASK(Transfer, ProjectExplorer::FileTransferAdapter); +QTC_DECLARE_CUSTOM_TASK(TransferTest, ProjectExplorer::FileTransferTestAdapter); diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp index 83ca7470191..42ff6a0535b 100644 --- a/src/plugins/remotelinux/linuxdevicetester.cpp +++ b/src/plugins/remotelinux/linuxdevicetester.cpp @@ -181,7 +181,7 @@ TaskItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod method "is not available.\n").arg(sftp, rsync)); } }; - return Transfer(setup, done, error); + return TransferTest(setup, done, error); } TaskItem GenericLinuxDeviceTesterPrivate::transferTasks() diff --git a/src/plugins/remotelinux/rsyncdeploystep.cpp b/src/plugins/remotelinux/rsyncdeploystep.cpp index 770d3a6d7b4..3a406cff95b 100644 --- a/src/plugins/remotelinux/rsyncdeploystep.cpp +++ b/src/plugins/remotelinux/rsyncdeploystep.cpp @@ -23,65 +23,28 @@ using namespace ProjectExplorer; using namespace Utils; +using namespace Utils::Tasking; namespace RemoteLinux { class RsyncDeployService : public AbstractRemoteLinuxDeployService { public: - RsyncDeployService() - { - connect(&m_mkdir, &QtcProcess::done, this, [this] { - if (m_mkdir.result() != ProcessResult::FinishedWithSuccess) { - QString finalMessage = m_mkdir.errorString(); - const QString stdErr = m_mkdir.cleanedStdErr(); - if (!stdErr.isEmpty()) { - if (!finalMessage.isEmpty()) - finalMessage += '\n'; - finalMessage += stdErr; - } - emit errorMessage(Tr::tr("Deploy via rsync: failed to create remote directories:") - + '\n' + finalMessage); - stopDeployment(); - return; - } - deployFiles(); - }); - connect(&m_mkdir, &QtcProcess::readyReadStandardError, this, [this] { - emit stdErrData(QString::fromLocal8Bit(m_mkdir.readAllStandardError())); - }); - connect(&m_fileTransfer, &FileTransfer::progress, - this, &AbstractRemoteLinuxDeployService::stdOutData); - connect(&m_fileTransfer, &FileTransfer::done, this, [this](const ProcessResultData &result) { - if (result.m_error == QProcess::FailedToStart) - emit errorMessage(Tr::tr("rsync failed to start: %1").arg(result.m_errorString)); - else if (result.m_exitStatus == QProcess::CrashExit) - emit errorMessage(Tr::tr("rsync crashed.")); - else if (result.m_exitCode != 0) - emit errorMessage(Tr::tr("rsync failed with exit code %1.").arg(result.m_exitCode)); - - stopDeployment(); - }); - } - void setDeployableFiles(const QList &files); void setIgnoreMissingFiles(bool ignore) { m_ignoreMissingFiles = ignore; } void setFlags(const QString &flags) { m_flags = flags; } private: bool isDeploymentNecessary() const override; - void doDeploy() override; void stopDeployment() override; - - void createRemoteDirectories(); - void deployFiles(); + TaskItem mkdirTask(); + TaskItem transferTask(); mutable FilesToTransfer m_files; bool m_ignoreMissingFiles = false; QString m_flags; - QtcProcess m_mkdir; - FileTransfer m_fileTransfer; + std::unique_ptr m_taskTree; }; void RsyncDeployService::setDeployableFiles(const QList &files) @@ -98,35 +61,76 @@ bool RsyncDeployService::isDeploymentNecessary() const return !m_files.empty(); } +TaskItem RsyncDeployService::mkdirTask() +{ + auto setupHandler = [this](QtcProcess &process) { + QStringList remoteDirs; + for (const FileToTransfer &file : std::as_const(m_files)) + remoteDirs << file.m_target.parentDir().path(); + remoteDirs.sort(); + remoteDirs.removeDuplicates(); + process.setCommand({deviceConfiguration()->filePath("mkdir"), + QStringList("-p") + remoteDirs}); + connect(&process, &QtcProcess::readyReadStandardError, this, [this, proc = &process] { + emit stdErrData(QString::fromLocal8Bit(proc->readAllStandardError())); + }); + }; + auto errorHandler = [this](const QtcProcess &process) { + QString finalMessage = process.errorString(); + const QString stdErr = process.cleanedStdErr(); + if (!stdErr.isEmpty()) { + if (!finalMessage.isEmpty()) + finalMessage += '\n'; + finalMessage += stdErr; + } + emit errorMessage(Tr::tr("Deploy via rsync: failed to create remote directories:") + + '\n' + finalMessage); + }; + return Process(setupHandler, {}, errorHandler); +} + +TaskItem RsyncDeployService::transferTask() +{ + auto setupHandler = [this](FileTransfer &transfer) { + transfer.setTransferMethod(FileTransferMethod::Rsync); + transfer.setRsyncFlags(m_flags); + transfer.setFilesToTransfer(m_files); + connect(&transfer, &FileTransfer::progress, + this, &AbstractRemoteLinuxDeployService::stdOutData); + }; + auto errorHandler = [this](const FileTransfer &transfer) { + const ProcessResultData result = transfer.resultData(); + if (result.m_error == QProcess::FailedToStart) + emit errorMessage(Tr::tr("rsync failed to start: %1").arg(result.m_errorString)); + else if (result.m_exitStatus == QProcess::CrashExit) + emit errorMessage(Tr::tr("rsync crashed.")); + else if (result.m_exitCode != 0) + emit errorMessage(Tr::tr("rsync failed with exit code %1.").arg(result.m_exitCode)); + }; + return Transfer(setupHandler, {}, errorHandler); +} + void RsyncDeployService::doDeploy() { - createRemoteDirectories(); -} + auto finishHandler = [this] { + m_taskTree.release()->deleteLater(); + stopDeployment(); + }; -void RsyncDeployService::createRemoteDirectories() -{ - QStringList remoteDirs; - for (const FileToTransfer &file : std::as_const(m_files)) - remoteDirs << file.m_target.parentDir().path(); - remoteDirs.sort(); - remoteDirs.removeDuplicates(); + Group root { + mkdirTask(), + transferTask(), + OnGroupDone(finishHandler), + OnGroupError(finishHandler), + }; - m_mkdir.setCommand({deviceConfiguration()->filePath("mkdir"), QStringList("-p") + remoteDirs}); - m_mkdir.start(); -} - -void RsyncDeployService::deployFiles() -{ - m_fileTransfer.setTransferMethod(FileTransferMethod::Rsync); - m_fileTransfer.setRsyncFlags(m_flags); - m_fileTransfer.setFilesToTransfer(m_files); - m_fileTransfer.start(); + m_taskTree.reset(new TaskTree(root)); + m_taskTree->start(); } void RsyncDeployService::stopDeployment() { - m_mkdir.close(); - m_fileTransfer.stop(); + m_taskTree.reset(); handleDeploymentDone(); }