TarPackageCreationStep: Employ task tree for running

Task-number: QTCREATORBUG-29168
Change-Id: Ic37e7047e063ff9e024e2d53a81f6bd310d545c1
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Jarek Kobus
2023-07-13 01:09:48 +02:00
parent 46b0cdf90e
commit 87dcd7ce34

View File

@@ -25,6 +25,7 @@
#include <cstring> #include <cstring>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Tasking;
using namespace Utils; using namespace Utils;
namespace RemoteLinux::Internal { namespace RemoteLinux::Internal {
@@ -60,8 +61,7 @@ public:
private: private:
bool init() final; bool init() final;
void doRun() final; GroupItem runRecipe() final;
void doCancel() final;
bool fromMap(const QVariantMap &map) final; bool fromMap(const QVariantMap &map) final;
QVariantMap toMap() const final; QVariantMap toMap() const final;
QVariant data(Id id) const final; QVariant data(Id id) const final;
@@ -71,9 +71,9 @@ private:
bool isPackagingNeeded() const; bool isPackagingNeeded() const;
void deployFinished(bool success); void deployFinished(bool success);
void addNeededDeploymentFiles(const DeployableFile &deployable, const Kit *kit); void addNeededDeploymentFiles(const DeployableFile &deployable, const Kit *kit);
void doPackage(QPromise<bool> &promise, const Utils::FilePath &tarFilePath, void doPackage(QPromise<void> &promise, const Utils::FilePath &tarFilePath,
bool ignoreMissingFiles); bool ignoreMissingFiles);
bool appendFile(QPromise<bool> &promise, QFile &tarFile, const QFileInfo &fileInfo, bool appendFile(QPromise<void> &promise, QFile &tarFile, const QFileInfo &fileInfo,
const QString &remoteFilePath, const Utils::FilePath &tarFilePath, const QString &remoteFilePath, const Utils::FilePath &tarFilePath,
bool ignoreMissingFiles); bool ignoreMissingFiles);
@@ -129,48 +129,41 @@ bool TarPackageCreationStep::init()
return true; return true;
} }
void TarPackageCreationStep::doRun() GroupItem TarPackageCreationStep::runRecipe()
{ {
const QList<DeployableFile> &files = target()->deploymentData().allFiles(); const auto onSetup = [this](Async<void> &async) {
const QList<DeployableFile> &files = target()->deploymentData().allFiles();
if (m_incrementalDeployment()) { if (m_incrementalDeployment()) {
m_files.clear(); m_files.clear();
for (const DeployableFile &file : files) for (const DeployableFile &file : files)
addNeededDeploymentFiles(file, kit()); addNeededDeploymentFiles(file, kit());
} else {
m_files = files;
}
emit addOutput(Tr::tr("Creating tarball..."), OutputFormat::NormalMessage);
if (!m_packagingNeeded) {
emit addOutput(Tr::tr("Tarball up to date, skipping packaging."), OutputFormat::NormalMessage);
emit finished(true);
return;
}
auto * const watcher = new QFutureWatcher<bool>(this);
connect(watcher, &QFutureWatcher<bool>::finished, this, [this, watcher] {
const bool success = !watcher->isCanceled() && watcher->result();
if (success) {
m_deploymentDataModified = false;
emit addOutput(Tr::tr("Packaging finished successfully."), OutputFormat::NormalMessage);
} else { } else {
emit addOutput(Tr::tr("Packaging failed."), OutputFormat::ErrorMessage); m_files = files;
} }
emit finished(success);
watcher->deleteLater(); emit addOutput(Tr::tr("Creating tarball..."), OutputFormat::NormalMessage);
if (!m_packagingNeeded) {
emit addOutput(Tr::tr("Tarball up to date, skipping packaging."),
OutputFormat::NormalMessage);
return SetupResult::StopWithDone;
}
async.setConcurrentCallData(&TarPackageCreationStep::doPackage, this,
m_tarFilePath, m_ignoreMissingFiles());
async.setFutureSynchronizer(&m_synchronizer);
return SetupResult::Continue;
};
const auto onDone = [this](const Async<void> &) {
m_deploymentDataModified = false;
emit addOutput(Tr::tr("Packaging finished successfully."), OutputFormat::NormalMessage);
// TODO: Should it be the next task in sequence?
connect(BuildManager::instance(), &BuildManager::buildQueueFinished, connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
this, &TarPackageCreationStep::deployFinished); this, &TarPackageCreationStep::deployFinished);
}); };
auto future = Utils::asyncRun(&TarPackageCreationStep::doPackage, this, const auto onError = [this](const Async<void> &) {
m_tarFilePath, m_ignoreMissingFiles()); emit addOutput(Tr::tr("Packaging failed."), OutputFormat::ErrorMessage);
watcher->setFuture(future); };
m_synchronizer.addFuture(future); return AsyncTask<void>(onSetup, onDone, onError);
}
void TarPackageCreationStep::doCancel()
{
m_synchronizer.cancelAllFutures();
} }
bool TarPackageCreationStep::fromMap(const QVariantMap &map) bool TarPackageCreationStep::fromMap(const QVariantMap &map)
@@ -266,7 +259,9 @@ void TarPackageCreationStep::addNeededDeploymentFiles(
} }
} }
void TarPackageCreationStep::doPackage(QPromise<bool> &promise, const FilePath &tarFilePath, // TODO: Fix error / message reporting. Currently, the messages may still be posted
// (and delivered) after the async task was already canceled.
void TarPackageCreationStep::doPackage(QPromise<void> &promise, const FilePath &tarFilePath,
bool ignoreMissingFiles) bool ignoreMissingFiles)
{ {
// TODO: Optimization: Only package changed files // TODO: Optimization: Only package changed files
@@ -275,7 +270,7 @@ void TarPackageCreationStep::doPackage(QPromise<bool> &promise, const FilePath &
if (!tarFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { if (!tarFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
raiseError(Tr::tr("Error: tar file %1 cannot be opened (%2).") raiseError(Tr::tr("Error: tar file %1 cannot be opened (%2).")
.arg(tarFilePath.toUserOutput(), tarFile.errorString())); .arg(tarFilePath.toUserOutput(), tarFile.errorString()));
promise.addResult(false); promise.future().cancel();
return; return;
} }
@@ -289,19 +284,18 @@ void TarPackageCreationStep::doPackage(QPromise<bool> &promise, const FilePath &
if (!appendFile(promise, tarFile, fileInfo, if (!appendFile(promise, tarFile, fileInfo,
d.remoteDirectory() + QLatin1Char('/') + fileInfo.fileName(), d.remoteDirectory() + QLatin1Char('/') + fileInfo.fileName(),
tarFilePath, ignoreMissingFiles)) { tarFilePath, ignoreMissingFiles)) {
promise.addResult(false); promise.future().cancel();
return; return;
} }
} }
const QByteArray eofIndicator(2*sizeof(TarFileHeader), 0); const QByteArray eofIndicator(2 * sizeof(TarFileHeader), 0);
if (tarFile.write(eofIndicator) != eofIndicator.length()) { if (tarFile.write(eofIndicator) != eofIndicator.length()) {
raiseError(Tr::tr("Error writing tar file \"%1\": %2.") raiseError(Tr::tr("Error writing tar file \"%1\": %2.")
.arg(QDir::toNativeSeparators(tarFile.fileName()), tarFile.errorString())); .arg(QDir::toNativeSeparators(tarFile.fileName()), tarFile.errorString()));
promise.addResult(false); promise.future().cancel();
return; return;
} }
promise.addResult(true);
} }
static bool setFilePath(TarFileHeader &header, const QByteArray &filePath) static bool setFilePath(TarFileHeader &header, const QByteArray &filePath)
@@ -383,7 +377,7 @@ static bool writeHeader(QFile &tarFile, const QFileInfo &fileInfo, const QString
return true; return true;
} }
bool TarPackageCreationStep::appendFile(QPromise<bool> &promise, bool TarPackageCreationStep::appendFile(QPromise<void> &promise,
QFile &tarFile, QFile &tarFile,
const QFileInfo &fileInfo, const QFileInfo &fileInfo,
const QString &remoteFilePath, const QString &remoteFilePath,