From 0fa16f8489fd627a388011bbdc36d2278455a25c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 2 Nov 2023 16:14:50 +0100 Subject: [PATCH] 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 Reviewed-by: Qt CI Bot Reviewed-by: --- src/libs/utils/filestreamer.cpp | 22 ++--- src/plugins/android/androidsdkdownloader.cpp | 27 +++-- src/plugins/autotest/testrunner.cpp | 4 +- src/plugins/boot2qt/qdbmakedefaultappstep.cpp | 13 ++- .../boot2qt/qdbstopapplicationstep.cpp | 13 +-- src/plugins/clangtools/clangtoolrunner.cpp | 40 +++----- .../coreplugin/locator/ilocatorfilter.cpp | 5 +- .../coreplugin/locator/javascriptfilter.cpp | 15 +-- .../projectexplorer/abstractprocessstep.cpp | 4 +- src/plugins/projectexplorer/copystep.cpp | 12 +-- src/plugins/qmakeprojectmanager/qmakestep.cpp | 10 +- .../qnx/qnxdeployqtlibrariesdialog.cpp | 26 ++--- src/plugins/qnx/qnxdevicetester.cpp | 13 +-- src/plugins/qnx/slog2inforunner.cpp | 25 ++--- .../remotelinux/customcommanddeploystep.cpp | 13 ++- .../remotelinux/genericdirectuploadstep.cpp | 6 +- src/plugins/remotelinux/killappstep.cpp | 15 ++- src/plugins/remotelinux/linuxdevicetester.cpp | 98 ++++++++++--------- .../remotelinux/tarpackagecreationstep.cpp | 11 ++- .../remotelinux/tarpackagedeploystep.cpp | 30 +++--- .../tasking/imagescaling/imagescaling.cpp | 24 ++--- 21 files changed, 209 insertions(+), 217 deletions(-) diff --git a/src/libs/utils/filestreamer.cpp b/src/libs/utils/filestreamer.cpp index 24587563019..c85fe9e4801 100644 --- a/src/libs/utils/filestreamer.cpp +++ b/src/libs/utils/filestreamer.cpp @@ -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 &async) { + const auto onSetup = [this](Async &async) { m_writeBuffer = new WriteBuffer(isBuffered(), &async); async.setConcurrentCallData(localWrite, m_filePath, m_writeData, m_writeBuffer); emit started(); }; - const auto finalize = [this](const Async &) { + const auto onDone = [this](const Async &, bool) { delete m_writeBuffer; m_writeBuffer = nullptr; }; - return AsyncTask(setup, finalize, finalize); + return AsyncTask(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 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) } }; diff --git a/src/plugins/android/androidsdkdownloader.cpp b/src/plugins/android/androidsdkdownloader.cpp index 20d89436a7c..89e6d6f267b 100644 --- a/src/plugins/android/androidsdkdownloader.cpp +++ b/src/plugins/android/androidsdkdownloader.cpp @@ -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)); diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index ecfd2dc54dd..16ddf2717f4 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -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); } diff --git a/src/plugins/boot2qt/qdbmakedefaultappstep.cpp b/src/plugins/boot2qt/qdbmakedefaultappstep.cpp index fbff89bd398..39d66f140d2 100644 --- a/src/plugins/boot2qt/qdbmakedefaultappstep.cpp +++ b/src/plugins/boot2qt/qdbmakedefaultappstep.cpp @@ -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()) @@ -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}; diff --git a/src/plugins/boot2qt/qdbstopapplicationstep.cpp b/src/plugins/boot2qt/qdbstopapplicationstep.cpp index 4a51f843904..8a5002624ee 100644 --- a/src/plugins/boot2qt/qdbstopapplicationstep.cpp +++ b/src/plugins/boot2qt/qdbstopapplicationstep.cpp @@ -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 diff --git a/src/plugins/clangtools/clangtoolrunner.cpp b/src/plugins/clangtools/clangtoolrunner.cpp index e83037aa536..0bded02193d 100644 --- a/src/plugins/clangtools/clangtoolrunner.cpp +++ b/src/plugins/clangtools/clangtoolrunner.cpp @@ -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> &data) { + const auto onReadDone = [=](const Async> &data, bool success) { if (!outputHandler) return; const expected_str 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> &data) { - if (!outputHandler) - return; - const expected_str 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>(onReadSetup, onReadDone, onReadError) + ProcessTask(onProcessSetup, onProcessDone), + AsyncTask>(onReadSetup, onReadDone) } }; return group; diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp index feff0d9d1ca..fbfd557e467 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp @@ -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 } diff --git a/src/plugins/coreplugin/locator/javascriptfilter.cpp b/src/plugins/coreplugin/locator/javascriptfilter.cpp index 21459d41dc6..777b352e846 100644 --- a/src/plugins/coreplugin/locator/javascriptfilter.cpp +++ b/src/plugins/coreplugin/locator/javascriptfilter.cpp @@ -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}}; diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp index c5516d5dc5b..c64044259c8 100644 --- a/src/plugins/projectexplorer/abstractprocessstep.cpp +++ b/src/plugins/projectexplorer/abstractprocessstep.cpp @@ -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) diff --git a/src/plugins/projectexplorer/copystep.cpp b/src/plugins/projectexplorer/copystep.cpp index 98cd5df3f17..b6262a0fe12 100644 --- a/src/plugins/projectexplorer/copystep.cpp +++ b/src/plugins/projectexplorer/copystep.cpp @@ -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; diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 95a2d487e4b..53b7ab9048c 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -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 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); } diff --git a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp index 5855352975c..6c19ea10f67 100644 --- a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp +++ b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp @@ -119,13 +119,22 @@ QList 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() diff --git a/src/plugins/qnx/qnxdevicetester.cpp b/src/plugins/qnx/qnxdevicetester.cpp index cbead1aa3d6..b162abb7f69 100644 --- a/src/plugins/qnx/qnxdevicetester.cpp +++ b/src/plugins/qnx/qnxdevicetester.cpp @@ -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); } diff --git a/src/plugins/qnx/slog2inforunner.cpp b/src/plugins/qnx/slog2inforunner.cpp index 77700804b21..8be079c4300 100644 --- a/src/plugins/qnx/slog2inforunner.cpp +++ b/src/plugins/qnx/slog2inforunner.cpp @@ -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)); diff --git a/src/plugins/remotelinux/customcommanddeploystep.cpp b/src/plugins/remotelinux/customcommanddeploystep.cpp index 2b5753243fb..1de16a6fedd 100644 --- a/src/plugins/remotelinux/customcommanddeploystep.cpp +++ b/src/plugins/remotelinux/customcommanddeploystep.cpp @@ -53,7 +53,7 @@ expected_str 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); } diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp index d9fc3d72a35..4878a6f20a0 100644 --- a/src/plugins/remotelinux/genericdirectuploadstep.cpp +++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp @@ -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); const QDateTime timestamp = timestampFromStat(file, proc); statEndHandler(storage, file, timestamp); }; - return ProcessTask(setupHandler, endHandler, endHandler); + return ProcessTask(onSetup, onDone); } GroupItem GenericDirectUploadStep::statTree(const TreeStorage &storage, diff --git a/src/plugins/remotelinux/killappstep.cpp b/src/plugins/remotelinux/killappstep.cpp index 3986ebe6b9b..559ddbadcc8 100644 --- a/src/plugins/remotelinux/killappstep.cpp +++ b/src/plugins/remotelinux/killappstep.cpp @@ -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() diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp index e908541aa57..dfbdea33306 100644 --- a/src/plugins/remotelinux/linuxdevicetester.cpp +++ b/src/plugins/remotelinux/linuxdevicetester.cpp @@ -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 &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 diff --git a/src/plugins/remotelinux/tarpackagecreationstep.cpp b/src/plugins/remotelinux/tarpackagecreationstep.cpp index 74b5a8fa423..23b9c34e5ed 100644 --- a/src/plugins/remotelinux/tarpackagecreationstep.cpp +++ b/src/plugins/remotelinux/tarpackagecreationstep.cpp @@ -153,17 +153,18 @@ Tasking::GroupItem TarPackageCreationStep::runRecipe() async.setFutureSynchronizer(&m_synchronizer); return SetupResult::Continue; }; - const auto onDone = [this](const Async &) { + const auto onDone = [this](const Async &, 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 &) { - emit addOutput(Tr::tr("Packaging failed."), OutputFormat::ErrorMessage); - }; - return AsyncTask(onSetup, onDone, onError); + return AsyncTask(onSetup, onDone); } void TarPackageCreationStep::fromMap(const Store &map) diff --git a/src/plugins/remotelinux/tarpackagedeploystep.cpp b/src/plugins/remotelinux/tarpackagedeploystep.cpp index 7475f47d479..6d393b00e40 100644 --- a/src/plugins/remotelinux/tarpackagedeploystep.cpp +++ b/src/plugins/remotelinux/tarpackagedeploystep.cpp @@ -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() diff --git a/tests/manual/tasking/imagescaling/imagescaling.cpp b/tests/manual/tasking/imagescaling/imagescaling.cpp index e3acda749b2..5d2992d87cd 100644 --- a/tests/manual/tasking/imagescaling/imagescaling.cpp +++ b/tests/manual/tasking/imagescaling/imagescaling.cpp @@ -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 &data) { data.setConcurrentCallData(&scale, *storage); }; - const auto onScalingDone = [this, i](const ConcurrentCall &data) { - labels[i]->setPixmap(QPixmap::fromImage(data.result())); - }; - const auto onScalingError = [this, i](const ConcurrentCall &) { - labels[i]->setText(tr("Image\nData\nError.")); + const auto onScalingDone = [this, i](const ConcurrentCall &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(onScalingSetup, onScalingDone, onScalingError) + NetworkQueryTask(onDownloadSetup, onDownloadDone), + ConcurrentCallTask(onScalingSetup, onScalingDone) }; tasks.append(group); ++i;