TaskTree: Use common done handler

Instead of specifying two separate done and error handlers,
specify just one that takes additional "bool success" argument.

Task-number: QTCREATORBUG-29834
Change-Id: Ie4f92236a38b03dac3dd33b2c80a317b62772a12
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Jarek Kobus
2023-11-02 16:14:50 +01:00
parent 0e7ecee489
commit 0fa16f8489
21 changed files with 209 additions and 217 deletions

View File

@@ -252,7 +252,7 @@ signals:
private:
GroupItem remoteTask() final {
const auto setup = [this](Process &process) {
const auto onSetup = [this](Process &process) {
m_writeBuffer = new WriteBuffer(false, &process);
connect(m_writeBuffer, &WriteBuffer::writeRequested, &process, &Process::writeRaw);
connect(m_writeBuffer, &WriteBuffer::closeWriteChannelRequested,
@@ -266,23 +266,23 @@ private:
process.setWriteData(m_writeData);
connect(&process, &Process::started, this, [this] { emit started(); });
};
const auto finalize = [this](const Process &) {
const auto onDone = [this](const Process &, bool) {
delete m_writeBuffer;
m_writeBuffer = nullptr;
};
return ProcessTask(setup, finalize, finalize);
return ProcessTask(onSetup, onDone);
}
GroupItem localTask() final {
const auto setup = [this](Async<void> &async) {
const auto onSetup = [this](Async<void> &async) {
m_writeBuffer = new WriteBuffer(isBuffered(), &async);
async.setConcurrentCallData(localWrite, m_filePath, m_writeData, m_writeBuffer);
emit started();
};
const auto finalize = [this](const Async<void> &) {
const auto onDone = [this](const Async<void> &, bool) {
delete m_writeBuffer;
m_writeBuffer = nullptr;
};
return AsyncTask<void>(setup, finalize, finalize);
return AsyncTask<void>(onSetup, onDone);
}
bool isBuffered() const { return m_writeData.isEmpty(); }
@@ -327,17 +327,17 @@ static Group interDeviceTransferTask(const FilePath &source, const FilePath &des
SingleBarrier writerReadyBarrier;
TreeStorage<TransferStorage> storage;
const auto setupReader = [=](FileStreamReader &reader) {
const auto onReaderSetup = [=](FileStreamReader &reader) {
reader.setFilePath(source);
QTC_CHECK(storage->writer != nullptr);
QObject::connect(&reader, &FileStreamReader::readyRead,
storage->writer, &FileStreamWriter::write);
};
const auto finalizeReader = [=](const FileStreamReader &) {
const auto onReaderDone = [=](const FileStreamReader &, bool) {
if (storage->writer) // writer may be deleted before the reader on TaskTree::stop().
storage->writer->closeWriteChannel();
};
const auto setupWriter = [=](FileStreamWriter &writer) {
const auto onWriterSetup = [=](FileStreamWriter &writer) {
writer.setFilePath(destination);
QObject::connect(&writer, &FileStreamWriter::started,
writerReadyBarrier->barrier(), &Barrier::advance);
@@ -349,10 +349,10 @@ static Group interDeviceTransferTask(const FilePath &source, const FilePath &des
Storage(writerReadyBarrier),
parallel,
Storage(storage),
FileStreamWriterTask(setupWriter),
FileStreamWriterTask(onWriterSetup),
Group {
waitForBarrierTask(writerReadyBarrier),
FileStreamReaderTask(setupReader, finalizeReader, finalizeReader)
FileStreamReaderTask(onReaderSetup, onReaderDone)
}
};

View File

@@ -130,10 +130,15 @@ void AndroidSdkDownloader::downloadAndExtractSdk()
#endif
});
};
const auto onQueryDone = [this, storage](const NetworkQuery &query) {
const auto onQueryDone = [this, storage](const NetworkQuery &query, bool success) {
QNetworkReply *reply = query.reply();
QTC_ASSERT(reply, return);
const QUrl url = reply->url();
if (!success) {
logError(Tr::tr("Downloading Android SDK Tools from URL %1 has failed: %2.")
.arg(url.toString(), reply->errorString()));
return;
}
if (isHttpRedirect(reply)) {
logError(Tr::tr("Download from %1 was redirected.").arg(url.toString()));
return;
@@ -146,13 +151,6 @@ void AndroidSdkDownloader::downloadAndExtractSdk()
}
*storage = sdkFileName;
};
const auto onQueryError = [this](const NetworkQuery &query) {
QNetworkReply *reply = query.reply();
QTC_ASSERT(reply, return);
const QUrl url = reply->url();
logError(Tr::tr("Downloading Android SDK Tools from URL %1 has failed: %2.")
.arg(url.toString(), reply->errorString()));
};
const auto onUnarchiveSetup = [this, storage](Unarchiver &unarchiver) {
m_progressDialog->setRange(0, 0);
@@ -173,19 +171,20 @@ void AndroidSdkDownloader::downloadAndExtractSdk()
unarchiver.setDestDir(sdkFileName.parentDir());
return SetupResult::Continue;
};
const auto onUnarchiverDone = [this, storage](const Unarchiver &) {
const auto onUnarchiverDone = [this, storage](const Unarchiver &, bool success) {
if (!success) {
logError(Tr::tr("Unarchiving error."));
return;
}
m_androidConfig.setTemporarySdkToolsPath(
(*storage)->parentDir().pathAppended(Constants::cmdlineToolsName));
QMetaObject::invokeMethod(this, [this] { emit sdkExtracted(); }, Qt::QueuedConnection);
};
const auto onUnarchiverError = [this](const Unarchiver &) {
logError(Tr::tr("Unarchiving error."));
};
const Group root {
Tasking::Storage(storage),
NetworkQueryTask(onQuerySetup, onQueryDone, onQueryError),
UnarchiverTask(onUnarchiveSetup, onUnarchiverDone, onUnarchiverError)
NetworkQueryTask(onQuerySetup, onQueryDone),
UnarchiverTask(onUnarchiveSetup, onUnarchiverDone)
};
m_taskTree.reset(new TaskTree(root));

View File

@@ -410,7 +410,7 @@ void TestRunner::runTestsHelper()
qCInfo(runnerLog) << "Working directory:" << process.workingDirectory();
qCDebug(runnerLog) << "Environment:" << process.environment().toStringList();
};
const auto onProcessDone = [this, config, storage](const Process &process) {
const auto onProcessDone = [this, config, storage](const Process &process, bool) {
TestStorage *testStorage = storage.activeStorage();
QTC_ASSERT(testStorage, return);
if (process.result() == ProcessResult::StartFailed) {
@@ -448,7 +448,7 @@ void TestRunner::runTestsHelper()
finishAllAndDone,
Tasking::Storage(storage),
onGroupSetup(onSetup),
ProcessTask(onProcessSetup, onProcessDone, onProcessDone)
ProcessTask(onProcessSetup, onProcessDone)
};
tasks.append(group);
}

View File

@@ -38,7 +38,7 @@ public:
private:
GroupItem deployRecipe() final
{
const auto setupHandler = [this](Process &process) {
const auto onSetup = [this](Process &process) {
QString remoteExe;
if (RunConfiguration *rc = target()->activeRunConfiguration()) {
if (auto exeAspect = rc->aspect<ExecutableAspect>())
@@ -55,16 +55,15 @@ private:
handleStdErrData(proc->readAllStandardError());
});
};
const auto doneHandler = [this](const Process &) {
if (selection() == 0)
const auto onDone = [this](const Process &process, bool success) {
if (!success)
addErrorMessage(Tr::tr("Remote process failed: %1").arg(process.errorString()));
else if (selection() == 0)
addProgressMessage(Tr::tr("Application set as the default one."));
else
addProgressMessage(Tr::tr("Reset the default application."));
};
const auto errorHandler = [this](const Process &process) {
addErrorMessage(Tr::tr("Remote process failed: %1").arg(process.errorString()));
};
return ProcessTask(setupHandler, doneHandler, errorHandler);
return ProcessTask(onSetup, onDone);
}
SelectionAspect selection{this};

View File

@@ -39,7 +39,7 @@ public:
GroupItem QdbStopApplicationStep::deployRecipe()
{
const auto setupHandler = [this](Process &process) {
const auto onSetup = [this](Process &process) {
const auto device = DeviceKitAspect::device(target()->kit());
if (!device) {
addErrorMessage(Tr::tr("No device to stop the application on."));
@@ -54,10 +54,11 @@ GroupItem QdbStopApplicationStep::deployRecipe()
});
return SetupResult::Continue;
};
const auto doneHandler = [this](const Process &) {
addProgressMessage(Tr::tr("Stopped the running application."));
};
const auto errorHandler = [this](const Process &process) {
const auto onDone = [this](const Process &process, bool success) {
if (success) {
addProgressMessage(Tr::tr("Stopped the running application."));
return;
}
const QString errorOutput = process.cleanedStdErr();
const QString failureMessage = Tr::tr("Could not check and possibly stop running application.");
if (process.exitStatus() == QProcess::CrashExit) {
@@ -71,7 +72,7 @@ GroupItem QdbStopApplicationStep::deployRecipe()
addErrorMessage(failureMessage);
}
};
return ProcessTask(setupHandler, doneHandler, errorHandler);
return ProcessTask(onSetup, onDone);
}
// QdbStopApplicationStepFactory

View File

@@ -163,24 +163,19 @@ GroupItem clangToolTask(const AnalyzeInputData &input,
qCDebug(LOG).noquote() << "Starting" << commandLine.toUserOutput();
process.setCommand(commandLine);
};
const auto onProcessDone = [=](const Process &process) {
const auto onProcessDone = [=](const Process &process, bool success) {
qCDebug(LOG).noquote() << "Output:\n" << process.cleanedStdOut();
// Here we handle only the case of process success with stderr output.
if (!outputHandler)
return;
if (process.result() != ProcessResult::FinishedWithSuccess)
return;
const QString stdErr = process.cleanedStdErr();
if (stdErr.isEmpty())
return;
outputHandler(
{true, input.unit.file, {}, {}, input.tool, Tr::tr("%1 produced stderr output:")
.arg(storage->name), stdErr});
};
const auto onProcessError = [=](const Process &process) {
if (!outputHandler)
if (success) {
const QString stdErr = process.cleanedStdErr();
if (stdErr.isEmpty())
return;
outputHandler({true, input.unit.file, {}, {}, input.tool,
Tr::tr("%1 produced stderr output:").arg(storage->name), stdErr});
return;
}
const QString details = Tr::tr("Command line: %1\nProcess Error: %2\nOutput:\n%3")
.arg(process.commandLine().toUserOutput())
.arg(process.error())
@@ -203,31 +198,24 @@ GroupItem clangToolTask(const AnalyzeInputData &input,
input.diagnosticsFilter);
data.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer());
};
const auto onReadDone = [=](const Async<expected_str<Diagnostics>> &data) {
const auto onReadDone = [=](const Async<expected_str<Diagnostics>> &data, bool success) {
if (!outputHandler)
return;
const expected_str<Diagnostics> result = data.result();
const bool success = result.has_value();
const bool ok = success && result.has_value();
Diagnostics diagnostics;
QString error;
if (success)
if (ok)
diagnostics = *result;
else
error = result.error();
outputHandler({success,
outputHandler({ok,
input.unit.file,
storage->outputFilePath,
diagnostics,
input.tool,
error});
};
const auto onReadError = [=](const Async<expected_str<Diagnostics>> &data) {
if (!outputHandler)
return;
const expected_str<Diagnostics> result = data.result();
outputHandler(
{false, input.unit.file, storage->outputFilePath, {}, input.tool, result.error()});
};
const Group group {
finishAllAndDone,
@@ -235,8 +223,8 @@ GroupItem clangToolTask(const AnalyzeInputData &input,
onGroupSetup(onSetup),
Group {
sequential,
ProcessTask(onProcessSetup, onProcessDone, onProcessError),
AsyncTask<expected_str<Diagnostics>>(onReadSetup, onReadDone, onReadError)
ProcessTask(onProcessSetup, onProcessDone),
AsyncTask<expected_str<Diagnostics>>(onReadSetup, onReadDone)
}
};
return group;

View File

@@ -441,8 +441,7 @@ void LocatorMatcher::start()
emit serialOutputDataReady(serialOutputData);
});
};
const auto onCollectorDone = [collectorStorage](const ResultsCollector &collector) {
Q_UNUSED(collector)
const auto onCollectorDone = [collectorStorage](const ResultsCollector &, bool) {
collectorStorage->m_collector = nullptr;
};
@@ -480,7 +479,7 @@ void LocatorMatcher::start()
const Group root {
parallel,
Storage(collectorStorage),
ResultsCollectorTask(onCollectorSetup, onCollectorDone, onCollectorDone),
ResultsCollectorTask(onCollectorSetup, onCollectorDone),
Group {
parallelTasks
}

View File

@@ -394,7 +394,13 @@ LocatorMatcherTasks JavaScriptFilter::matchers()
request.setEngine(engine);
request.setEvaluateData(storage->input());
};
const auto onJavaScriptDone = [storage](const JavaScriptRequest &request) {
const auto onJavaScriptDone = [storage](const JavaScriptRequest &request, bool success) {
if (!success) {
LocatorFilterEntry entry;
entry.displayName = request.output().m_output;
storage->reportOutput({entry});
return;
}
const auto acceptor = [](const QString &clipboardContents) {
return [clipboardContents] {
QGuiApplication::clipboard()->setText(clipboardContents);
@@ -418,15 +424,10 @@ LocatorMatcherTasks JavaScriptFilter::matchers()
storage->reportOutput({entry, copyResultEntry, copyExpressionEntry});
};
const auto onJavaScriptError = [storage](const JavaScriptRequest &request) {
LocatorFilterEntry entry;
entry.displayName = request.output().m_output;
storage->reportOutput({entry});
};
const Group root {
onGroupSetup(onSetup),
JavaScriptRequestTask(onJavaScriptSetup, onJavaScriptDone, onJavaScriptError)
JavaScriptRequestTask(onJavaScriptSetup, onJavaScriptDone)
};
return {{root, storage}};

View File

@@ -164,8 +164,8 @@ GroupItem AbstractProcessStep::defaultProcessTask()
const auto onSetup = [this](Process &process) {
return setupProcess(process) ? SetupResult::Continue : SetupResult::StopWithError;
};
const auto onEnd = [this](const Process &process) { handleProcessDone(process); };
return ProcessTask(onSetup, onEnd, onEnd);
const auto onDone = [this](const Process &process, bool) { handleProcessDone(process); };
return ProcessTask(onSetup, onDone);
}
bool AbstractProcessStep::setupProcess(Process &process)

View File

@@ -52,13 +52,13 @@ private:
streamer.setDestination(m_target);
return SetupResult::Continue;
};
const auto onDone = [this](const FileStreamer &) {
addOutput(Tr::tr("Copying finished."), OutputFormat::NormalMessage);
const auto onDone = [this](const FileStreamer &, bool success) {
if (success)
addOutput(Tr::tr("Copying finished."), OutputFormat::NormalMessage);
else
addOutput(Tr::tr("Copying failed."), OutputFormat::ErrorMessage);
};
const auto onError = [this](const FileStreamer &) {
addOutput(Tr::tr("Copying failed."), OutputFormat::ErrorMessage);
};
return FileStreamerTask(onSetup, onDone, onError);
return FileStreamerTask(onSetup, onDone);
}
FilePath m_source;

View File

@@ -275,14 +275,14 @@ Tasking::GroupItem QMakeStep::runRecipe()
return SetupResult::StopWithDone;
};
const auto setupQMake = [this](Process &process) {
const auto onQMakeSetup = [this](Process &process) {
m_outputFormatter->setLineParsers({new QMakeParser});
ProcessParameters *pp = processParameters();
pp->setCommandLine(m_qmakeCommand);
return setupProcess(process) ? SetupResult::Continue : SetupResult::StopWithError;
};
const auto setupMakeQMake = [this](Process &process) {
const auto onMakeQMakeSetup = [this](Process &process) {
auto *parser = new GnuMakeParser;
parser->addSearchDir(processParameters()->workingDirectory());
m_outputFormatter->setLineParsers({parser});
@@ -291,7 +291,7 @@ Tasking::GroupItem QMakeStep::runRecipe()
return setupProcess(process) ? SetupResult::Continue : SetupResult::StopWithError;
};
const auto onProcessDone = [this](const Process &process) { handleProcessDone(process); };
const auto onProcessDone = [this](const Process &process, bool) { handleProcessDone(process); };
const auto onDone = [this] {
emit buildConfiguration()->buildDirectoryInitialized();
@@ -300,9 +300,9 @@ Tasking::GroupItem QMakeStep::runRecipe()
QList<GroupItem> processList = {onGroupSetup(onSetup),
onGroupDone(onDone),
ProcessTask(setupQMake, onProcessDone, onProcessDone)};
ProcessTask(onQMakeSetup, onProcessDone)};
if (m_runMakeQmake)
processList << ProcessTask(setupMakeQMake, onProcessDone, onProcessDone);
processList << ProcessTask(onMakeQMakeSetup, onProcessDone);
return Group(processList);
}

View File

@@ -119,13 +119,22 @@ QList<DeployableFile> collectFilesToUpload(const DeployableFile &deployable)
GroupItem QnxDeployQtLibrariesDialogPrivate::checkDirTask()
{
const auto setupHandler = [this](Process &process) {
const auto onSetup = [this](Process &process) {
m_deployLogWindow->appendPlainText(Tr::tr("Checking existence of \"%1\"")
.arg(fullRemoteDirectory()));
process.setCommand({m_device->filePath("test"), {"-d", fullRemoteDirectory()}});
};
const auto doneHandler = [this](const Process &process) {
Q_UNUSED(process)
const auto onDone = [this](const Process &process, bool success) {
if (!success) {
if (process.result() != ProcessResult::FinishedWithError) {
m_deployLogWindow->appendPlainText(Tr::tr("Connection failed: %1")
.arg(process.errorString()));
m_checkResult = CheckResult::Abort;
return;
}
m_checkResult = CheckResult::SkipRemoveDir;
return;
}
const int answer = QMessageBox::question(q, q->windowTitle(),
Tr::tr("The remote directory \"%1\" already exists.\n"
"Deploying to that directory will remove any files already present.\n\n"
@@ -133,16 +142,7 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::checkDirTask()
QMessageBox::Yes | QMessageBox::No);
m_checkResult = answer == QMessageBox::Yes ? CheckResult::RemoveDir : CheckResult::Abort;
};
const auto errorHandler = [this](const Process &process) {
if (process.result() != ProcessResult::FinishedWithError) {
m_deployLogWindow->appendPlainText(Tr::tr("Connection failed: %1")
.arg(process.errorString()));
m_checkResult = CheckResult::Abort;
return;
}
m_checkResult = CheckResult::SkipRemoveDir;
};
return ProcessTask(setupHandler, doneHandler, errorHandler);
return ProcessTask(onSetup, onDone);
}
GroupItem QnxDeployQtLibrariesDialogPrivate::removeDirTask()

View File

@@ -43,7 +43,7 @@ void QnxDeviceTester::testDevice(const ProjectExplorer::IDevice::Ptr &device)
using namespace Tasking;
auto setupHandler = [device, this](Process &process) {
auto onSetup = [device, this](Process &process) {
emit progressMessage(Tr::tr("Checking that files can be created in %1...")
.arg(Constants::QNX_TMP_DIR));
const QString pidFile = QString("%1/qtc_xxxx.pid").arg(Constants::QNX_TMP_DIR);
@@ -51,17 +51,18 @@ void QnxDeviceTester::testDevice(const ProjectExplorer::IDevice::Ptr &device)
{"-c", QLatin1String("rm %1 > /dev/null 2>&1; echo ABC > %1 && rm %1").arg(pidFile)});
process.setCommand(cmd);
};
auto doneHandler = [this](const Process &) {
emit progressMessage(Tr::tr("Files can be created in /var/run.") + '\n');
};
auto errorHandler = [this](const Process &process) {
auto onDone = [this](const Process &process, bool success) {
if (success) {
emit progressMessage(Tr::tr("Files can be created in /var/run.") + '\n');
return;
}
const QString message = process.result() == ProcessResult::StartFailed
? Tr::tr("An error occurred while checking that files can be created in %1.")
.arg(Constants::QNX_TMP_DIR) + '\n' + process.errorString()
: Tr::tr("Files cannot be created in %1.").arg(Constants::QNX_TMP_DIR);
emit errorMessage(message + '\n');
};
setExtraTests({ProcessTask(setupHandler, doneHandler, errorHandler)});
setExtraTests({ProcessTask(onSetup, onDone)});
RemoteLinux::GenericLinuxDeviceTester::testDevice(device);
}

View File

@@ -34,27 +34,28 @@ void Slog2InfoRunner::start()
using namespace Tasking;
QTC_CHECK(!m_taskTree);
const auto testStartHandler = [this](Process &process) {
const auto onTestSetup = [this](Process &process) {
process.setCommand({device()->filePath("slog2info"), {}});
};
const auto testDoneHandler = [this](const Process &) {
m_found = true;
};
const auto testErrorHandler = [this](const Process &) {
const auto onTestDone = [this](const Process &, bool success) {
if (success) {
m_found = true;
return;
}
appendMessage(Tr::tr("Warning: \"slog2info\" is not found on the device, "
"debug output not available."), ErrorMessageFormat);
};
const auto launchTimeStartHandler = [this](Process &process) {
const auto onLaunchTimeSetup = [this](Process &process) {
process.setCommand({device()->filePath("date"), "+\"%d %H:%M:%S\"", CommandLine::Raw});
};
const auto launchTimeDoneHandler = [this](const Process &process) {
const auto onLaunchTimeDone = [this](const Process &process) {
QTC_CHECK(!m_applicationId.isEmpty());
QTC_CHECK(m_found);
m_launchDateTime = QDateTime::fromString(process.cleanedStdOut().trimmed(), "dd HH:mm:ss");
};
const auto logStartHandler = [this](Process &process) {
const auto onLogSetup = [this](Process &process) {
process.setCommand({device()->filePath("slog2info"), {"-w"}});
connect(&process, &Process::readyReadStandardOutput, this, [&] {
processLogInput(QString::fromLatin1(process.readAllRawStandardOutput()));
@@ -63,15 +64,15 @@ void Slog2InfoRunner::start()
appendMessage(QString::fromLatin1(process.readAllRawStandardError()), StdErrFormat);
});
};
const auto logErrorHandler = [this](const Process &process) {
const auto onLogError = [this](const Process &process) {
appendMessage(Tr::tr("Cannot show slog2info output. Error: %1").arg(process.errorString()),
StdErrFormat);
};
const Group root {
ProcessTask(testStartHandler, testDoneHandler, testErrorHandler),
ProcessTask(launchTimeStartHandler, launchTimeDoneHandler),
ProcessTask(logStartHandler, {}, logErrorHandler)
ProcessTask(onTestSetup, onTestDone),
ProcessTask(onLaunchTimeSetup, onLaunchTimeDone),
ProcessTask(onLogSetup, {}, onLogError)
};
m_taskTree.reset(new TaskTree(root));

View File

@@ -53,7 +53,7 @@ expected_str<void> CustomCommandDeployStep::isDeploymentPossible() const
GroupItem CustomCommandDeployStep::deployRecipe()
{
const auto setupHandler = [this](Process &process) {
const auto onSetup = [this](Process &process) {
addProgressMessage(Tr::tr("Starting remote command \"%1\"...").arg(commandLine()));
process.setCommand({deviceConfiguration()->filePath("/bin/sh"),
{"-c", commandLine()}});
@@ -65,11 +65,10 @@ GroupItem CustomCommandDeployStep::deployRecipe()
handleStdErrData(proc->readAllStandardError());
});
};
const auto doneHandler = [this](const Process &) {
addProgressMessage(Tr::tr("Remote command finished successfully."));
};
const auto errorHandler = [this](const Process &process) {
if (process.error() != QProcess::UnknownError
const auto onDone = [this](const Process &process, bool success) {
if (success) {
addProgressMessage(Tr::tr("Remote command finished successfully."));
} else if (process.error() != QProcess::UnknownError
|| process.exitStatus() != QProcess::NormalExit) {
addErrorMessage(Tr::tr("Remote process failed: %1").arg(process.errorString()));
} else if (process.exitCode() != 0) {
@@ -77,7 +76,7 @@ GroupItem CustomCommandDeployStep::deployRecipe()
.arg(process.exitCode()));
}
};
return ProcessTask(setupHandler, doneHandler, errorHandler);
return ProcessTask(onSetup, onDone);
}

View File

@@ -135,17 +135,17 @@ GroupItem GenericDirectUploadStep::statTask(UploadStorage *storage,
const DeployableFile &file,
StatEndHandler statEndHandler)
{
const auto setupHandler = [=](Process &process) {
const auto onSetup = [this, file](Process &process) {
// We'd like to use --format=%Y, but it's not supported by busybox.
process.setCommand({deviceConfiguration()->filePath("stat"),
{"-t", Utils::ProcessArgs::quoteArgUnix(file.remoteFilePath())}});
};
const auto endHandler = [=](const Process &process) {
const auto onDone = [this, storage, file, statEndHandler](const Process &process, bool) {
Process *proc = const_cast<Process *>(&process);
const QDateTime timestamp = timestampFromStat(file, proc);
statEndHandler(storage, file, timestamp);
};
return ProcessTask(setupHandler, endHandler, endHandler);
return ProcessTask(onSetup, onDone);
}
GroupItem GenericDirectUploadStep::statTree(const TreeStorage<UploadStorage> &storage,

View File

@@ -45,7 +45,7 @@ private:
GroupItem KillAppStep::deployRecipe()
{
const auto setupHandler = [this](DeviceProcessKiller &killer) {
const auto onSetup = [this](DeviceProcessKiller &killer) {
if (m_remoteExecutable.isEmpty()) {
addSkipDeploymentMessage();
return SetupResult::StopWithDone;
@@ -55,14 +55,13 @@ GroupItem KillAppStep::deployRecipe()
.arg(m_remoteExecutable.path()));
return SetupResult::Continue;
};
const auto doneHandler = [this](const DeviceProcessKiller &) {
addProgressMessage(Tr::tr("Remote application killed."));
const auto onDone = [this](const DeviceProcessKiller &, bool success) {
const QString message = success ? Tr::tr("Remote application killed.")
: Tr::tr("Failed to kill remote application. "
"Assuming it was not running.");
addProgressMessage(message);
};
const auto errorHandler = [this](const DeviceProcessKiller &) {
addProgressMessage(Tr::tr("Failed to kill remote application. "
"Assuming it was not running."));
};
return DeviceProcessKillerTask(setupHandler, doneHandler, errorHandler);
return DeviceProcessKillerTask(onSetup, onDone);
}
KillAppStepFactory::KillAppStepFactory()

View File

@@ -92,38 +92,42 @@ QStringList GenericLinuxDeviceTesterPrivate::commandsToTest() const
GroupItem GenericLinuxDeviceTesterPrivate::echoTask(const QString &contents) const
{
const auto setup = [this, contents](Process &process) {
const auto onSetup = [this, contents](Process &process) {
emit q->progressMessage(Tr::tr("Sending echo to device..."));
process.setCommand({m_device->filePath("echo"), {contents}});
};
const auto done = [this, contents](const Process &process) {
const auto onDone = [this, contents](const Process &process, bool success) {
if (!success) {
const QString stdErrOutput = process.cleanedStdErr();
if (!stdErrOutput.isEmpty())
emit q->errorMessage(Tr::tr("echo failed: %1").arg(stdErrOutput) + '\n');
else
emit q->errorMessage(Tr::tr("echo failed.") + '\n');
return;
}
const QString reply = Utils::chopIfEndsWith(process.cleanedStdOut(), '\n');
if (reply != contents)
if (reply != contents) {
emit q->errorMessage(Tr::tr("Device replied to echo with unexpected contents: \"%1\"")
.arg(reply) + '\n');
else
emit q->progressMessage(Tr::tr("Device replied to echo with expected contents.") + '\n');
.arg(reply) + '\n');
} else {
emit q->progressMessage(Tr::tr("Device replied to echo with expected contents.")
+ '\n');
}
};
const auto error = [this](const Process &process) {
const QString stdErrOutput = process.cleanedStdErr();
if (!stdErrOutput.isEmpty())
emit q->errorMessage(Tr::tr("echo failed: %1").arg(stdErrOutput) + '\n');
else
emit q->errorMessage(Tr::tr("echo failed.") + '\n');
};
return ProcessTask(setup, done, error);
return ProcessTask(onSetup, onDone);
}
GroupItem GenericLinuxDeviceTesterPrivate::unameTask() const
{
const auto setup = [this](Process &process) {
const auto onSetup = [this](Process &process) {
emit q->progressMessage(Tr::tr("Checking kernel version..."));
process.setCommand({m_device->filePath("uname"), {"-rsm"}});
};
const auto done = [this](const Process &process) {
emit q->progressMessage(process.cleanedStdOut());
};
const auto error = [this](const Process &process) {
const auto onDone = [this](const Process &process, bool success) {
if (success) {
emit q->progressMessage(process.cleanedStdOut());
return;
}
const QString stdErrOutput = process.cleanedStdErr();
if (!stdErrOutput.isEmpty())
emit q->errorMessage(Tr::tr("uname failed: %1").arg(stdErrOutput) + '\n');
@@ -132,18 +136,21 @@ GroupItem GenericLinuxDeviceTesterPrivate::unameTask() const
};
return Group {
finishAllAndDone,
ProcessTask(setup, done, error)
ProcessTask(onSetup, onDone)
};
}
GroupItem GenericLinuxDeviceTesterPrivate::gathererTask() const
{
const auto setup = [this](DeviceUsedPortsGatherer &gatherer) {
const auto onSetup = [this](DeviceUsedPortsGatherer &gatherer) {
emit q->progressMessage(Tr::tr("Checking if specified ports are available..."));
gatherer.setDevice(m_device);
};
const auto done = [this](const DeviceUsedPortsGatherer &gatherer) {
if (gatherer.usedPorts().isEmpty()) {
const auto onDone = [this](const DeviceUsedPortsGatherer &gatherer, bool success) {
if (!success) {
emit q->errorMessage(Tr::tr("Error gathering ports: %1").arg(gatherer.errorString()) + '\n'
+ Tr::tr("Some tools will not work out of the box.\n"));
} else if (gatherer.usedPorts().isEmpty()) {
emit q->progressMessage(Tr::tr("All specified ports are available.") + '\n');
} else {
const QString portList = transform(gatherer.usedPorts(), [](const Port &port) {
@@ -153,38 +160,34 @@ GroupItem GenericLinuxDeviceTesterPrivate::gathererTask() const
.arg(portList) + '\n');
}
};
const auto error = [this](const DeviceUsedPortsGatherer &gatherer) {
emit q->errorMessage(Tr::tr("Error gathering ports: %1").arg(gatherer.errorString()) + '\n'
+ Tr::tr("Some tools will not work out of the box.\n"));
};
return Group {
finishAllAndDone,
DeviceUsedPortsGathererTask(setup, done, error)
DeviceUsedPortsGathererTask(onSetup, onDone)
};
}
GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod method,
const TreeStorage<TransferStorage> &storage) const
{
const auto setup = [this, method](FileTransfer &transfer) {
const auto onSetup = [this, method](FileTransfer &transfer) {
emit q->progressMessage(Tr::tr("Checking whether \"%1\" works...")
.arg(FileTransfer::transferMethodName(method)));
transfer.setTransferMethod(method);
transfer.setTestDevice(m_device);
};
const auto done = [this, method, storage](const FileTransfer &) {
const QString methodName = FileTransfer::transferMethodName(method);
emit q->progressMessage(Tr::tr("\"%1\" is functional.\n").arg(methodName));
if (method == FileTransferMethod::Rsync)
m_device->setExtraData(Constants::SUPPORTS_RSYNC, true);
else if (method == FileTransferMethod::Sftp)
m_device->setExtraData(Constants::SUPPORTS_SFTP, true);
else
storage->useGenericCopy = true;
};
const auto error = [this, method, storage](const FileTransfer &transfer) {
const auto onDone = [this, method, storage](const FileTransfer &transfer, bool success) {
const QString methodName = FileTransfer::transferMethodName(method);
if (success) {
emit q->progressMessage(Tr::tr("\"%1\" is functional.\n").arg(methodName));
if (method == FileTransferMethod::Rsync)
m_device->setExtraData(Constants::SUPPORTS_RSYNC, true);
else if (method == FileTransferMethod::Sftp)
m_device->setExtraData(Constants::SUPPORTS_SFTP, true);
else
storage->useGenericCopy = true;
return;
}
const ProcessResultData resultData = transfer.resultData();
QString error;
if (resultData.m_error == QProcess::FailedToStart) {
@@ -218,7 +221,7 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod metho
+ "\n");
}
};
return FileTransferTestTask(setup, done, error);
return FileTransferTestTask(onSetup, onDone);
}
GroupItem GenericLinuxDeviceTesterPrivate::transferTasks() const
@@ -238,23 +241,24 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTasks() const
GroupItem GenericLinuxDeviceTesterPrivate::commandTask(const QString &commandName) const
{
const auto setup = [this, commandName](Process &process) {
const auto onSetup = [this, commandName](Process &process) {
emit q->progressMessage(Tr::tr("%1...").arg(commandName));
CommandLine command{m_device->filePath("/bin/sh"), {"-c"}};
command.addArgs(QLatin1String("\"command -v %1\"").arg(commandName), CommandLine::Raw);
process.setCommand(command);
};
const auto done = [this, commandName](const Process &) {
emit q->progressMessage(Tr::tr("%1 found.").arg(commandName));
};
const auto error = [this, commandName](const Process &process) {
const auto onDone = [this, commandName](const Process &process, bool success) {
if (success) {
emit q->progressMessage(Tr::tr("%1 found.").arg(commandName));
return;
}
const QString message = process.result() == ProcessResult::StartFailed
? Tr::tr("An error occurred while checking for %1.").arg(commandName)
+ '\n' + process.errorString()
: Tr::tr("%1 not found.").arg(commandName);
emit q->errorMessage(message);
};
return ProcessTask(setup, done, error);
return ProcessTask(onSetup, onDone);
}
GroupItem GenericLinuxDeviceTesterPrivate::commandTasks() const

View File

@@ -153,17 +153,18 @@ Tasking::GroupItem TarPackageCreationStep::runRecipe()
async.setFutureSynchronizer(&m_synchronizer);
return SetupResult::Continue;
};
const auto onDone = [this](const Async<void> &) {
const auto onDone = [this](const Async<void> &, bool success) {
if (!success) {
emit addOutput(Tr::tr("Packaging failed."), OutputFormat::ErrorMessage);
return;
}
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,
this, &TarPackageCreationStep::deployFinished);
};
const auto onError = [this](const Async<void> &) {
emit addOutput(Tr::tr("Packaging failed."), OutputFormat::ErrorMessage);
};
return AsyncTask<void>(onSetup, onDone, onError);
return AsyncTask<void>(onSetup, onDone);
}
void TarPackageCreationStep::fromMap(const Store &map)

View File

@@ -67,26 +67,25 @@ QString TarPackageDeployStep::remoteFilePath() const
GroupItem TarPackageDeployStep::uploadTask()
{
const auto setupHandler = [this](FileTransfer &transfer) {
const auto onSetup = [this](FileTransfer &transfer) {
const FilesToTransfer files {{m_packageFilePath,
deviceConfiguration()->filePath(remoteFilePath())}};
transfer.setFilesToTransfer(files);
connect(&transfer, &FileTransfer::progress, this, &TarPackageDeployStep::addProgressMessage);
addProgressMessage(Tr::tr("Uploading package to device..."));
};
const auto doneHandler = [this](const FileTransfer &) {
addProgressMessage(Tr::tr("Successfully uploaded package file."));
const auto onDone = [this](const FileTransfer &transfer, bool success) {
if (success)
addProgressMessage(Tr::tr("Successfully uploaded package file."));
else
addErrorMessage(transfer.resultData().m_errorString);
};
const auto errorHandler = [this](const FileTransfer &transfer) {
const ProcessResultData result = transfer.resultData();
addErrorMessage(result.m_errorString);
};
return FileTransferTask(setupHandler, doneHandler, errorHandler);
return FileTransferTask(onSetup, onDone);
}
GroupItem TarPackageDeployStep::installTask()
{
const auto setupHandler = [this](Process &process) {
const auto onSetup = [this](Process &process) {
const QString cmdLine = QLatin1String("cd / && tar xvf ") + remoteFilePath()
+ " && (rm " + remoteFilePath() + " || :)";
process.setCommand({deviceConfiguration()->filePath("/bin/sh"), {"-c", cmdLine}});
@@ -99,14 +98,15 @@ GroupItem TarPackageDeployStep::installTask()
});
addProgressMessage(Tr::tr("Installing package to device..."));
};
const auto doneHandler = [this](const Process &) {
saveDeploymentTimeStamp(DeployableFile(m_packageFilePath, {}), {});
addProgressMessage(Tr::tr("Successfully installed package file."));
};
const auto errorHandler = [this](const Process &process) {
const auto onDone = [this](const Process &process, bool success) {
if (success) {
saveDeploymentTimeStamp(DeployableFile(m_packageFilePath, {}), {});
addProgressMessage(Tr::tr("Successfully installed package file."));
return;
}
addErrorMessage(Tr::tr("Installing package failed.") + process.errorString());
};
return ProcessTask(setupHandler, doneHandler, errorHandler);
return ProcessTask(onSetup, onDone);
}
GroupItem TarPackageDeployStep::deployRecipe()

View File

@@ -79,27 +79,27 @@ void Images::process()
query.setNetworkAccessManager(&qnam);
query.setRequest(QNetworkRequest(url));
};
const auto onDownloadDone = [storage](const NetworkQuery &query) {
*storage = query.reply()->readAll();
};
const auto onDownloadError = [this, i](const NetworkQuery &query) {
labels[i]->setText(tr("Download\nError.\nCode: %1.").arg(query.reply()->error()));
const auto onDownloadDone = [this, storage, i](const NetworkQuery &query, bool success) {
if (success)
*storage = query.reply()->readAll();
else
labels[i]->setText(tr("Download\nError.\nCode: %1.").arg(query.reply()->error()));
};
const auto onScalingSetup = [storage](ConcurrentCall<QImage> &data) {
data.setConcurrentCallData(&scale, *storage);
};
const auto onScalingDone = [this, i](const ConcurrentCall<QImage> &data) {
labels[i]->setPixmap(QPixmap::fromImage(data.result()));
};
const auto onScalingError = [this, i](const ConcurrentCall<QImage> &) {
labels[i]->setText(tr("Image\nData\nError."));
const auto onScalingDone = [this, i](const ConcurrentCall<QImage> &data, bool success) {
if (success)
labels[i]->setPixmap(QPixmap::fromImage(data.result()));
else
labels[i]->setText(tr("Image\nData\nError."));
};
const Group group {
Storage(storage),
NetworkQueryTask(onDownloadSetup, onDownloadDone, onDownloadError),
ConcurrentCallTask<QImage>(onScalingSetup, onScalingDone, onScalingError)
NetworkQueryTask(onDownloadSetup, onDownloadDone),
ConcurrentCallTask<QImage>(onScalingSetup, onScalingDone)
};
tasks.append(group);
++i;