forked from qt-creator/qt-creator
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:
@@ -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)
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -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));
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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};
|
||||
|
@@ -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 &) {
|
||||
const auto onDone = [this](const Process &process, bool success) {
|
||||
if (success) {
|
||||
addProgressMessage(Tr::tr("Stopped the running application."));
|
||||
};
|
||||
const auto errorHandler = [this](const Process &process) {
|
||||
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
|
||||
|
@@ -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;
|
||||
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});
|
||||
};
|
||||
const auto onProcessError = [=](const Process &process) {
|
||||
if (!outputHandler)
|
||||
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;
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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}};
|
||||
|
@@ -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)
|
||||
|
@@ -52,13 +52,13 @@ private:
|
||||
streamer.setDestination(m_target);
|
||||
return SetupResult::Continue;
|
||||
};
|
||||
const auto onDone = [this](const FileStreamer &) {
|
||||
const auto onDone = [this](const FileStreamer &, bool success) {
|
||||
if (success)
|
||||
addOutput(Tr::tr("Copying finished."), OutputFormat::NormalMessage);
|
||||
};
|
||||
const auto onError = [this](const FileStreamer &) {
|
||||
else
|
||||
addOutput(Tr::tr("Copying failed."), OutputFormat::ErrorMessage);
|
||||
};
|
||||
return FileStreamerTask(onSetup, onDone, onError);
|
||||
return FileStreamerTask(onSetup, onDone);
|
||||
}
|
||||
|
||||
FilePath m_source;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -119,21 +119,13 @@ 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 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"
|
||||
"Are you sure you want to continue?").arg(fullRemoteDirectory()),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
m_checkResult = answer == QMessageBox::Yes ? CheckResult::RemoveDir : CheckResult::Abort;
|
||||
};
|
||||
const auto errorHandler = [this](const Process &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()));
|
||||
@@ -141,8 +133,16 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::checkDirTask()
|
||||
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"
|
||||
"Are you sure you want to continue?").arg(fullRemoteDirectory()),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
m_checkResult = answer == QMessageBox::Yes ? CheckResult::RemoveDir : CheckResult::Abort;
|
||||
};
|
||||
return ProcessTask(setupHandler, doneHandler, errorHandler);
|
||||
return ProcessTask(onSetup, onDone);
|
||||
}
|
||||
|
||||
GroupItem QnxDeployQtLibrariesDialogPrivate::removeDirTask()
|
||||
|
@@ -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 &) {
|
||||
auto onDone = [this](const Process &process, bool success) {
|
||||
if (success) {
|
||||
emit progressMessage(Tr::tr("Files can be created in /var/run.") + '\n');
|
||||
};
|
||||
auto errorHandler = [this](const Process &process) {
|
||||
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);
|
||||
}
|
||||
|
@@ -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 &) {
|
||||
const auto onTestDone = [this](const Process &, bool success) {
|
||||
if (success) {
|
||||
m_found = true;
|
||||
};
|
||||
const auto testErrorHandler = [this](const Process &) {
|
||||
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));
|
||||
|
@@ -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 &) {
|
||||
const auto onDone = [this](const Process &process, bool success) {
|
||||
if (success) {
|
||||
addProgressMessage(Tr::tr("Remote command finished successfully."));
|
||||
};
|
||||
const auto errorHandler = [this](const Process &process) {
|
||||
if (process.error() != QProcess::UnknownError
|
||||
} 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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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()
|
||||
|
@@ -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 QString reply = Utils::chopIfEndsWith(process.cleanedStdOut(), '\n');
|
||||
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');
|
||||
};
|
||||
const auto error = [this](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) {
|
||||
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');
|
||||
}
|
||||
};
|
||||
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) {
|
||||
const auto onDone = [this](const Process &process, bool success) {
|
||||
if (success) {
|
||||
emit q->progressMessage(process.cleanedStdOut());
|
||||
};
|
||||
const auto error = [this](const Process &process) {
|
||||
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,28 +160,25 @@ 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 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);
|
||||
@@ -182,9 +186,8 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod metho
|
||||
m_device->setExtraData(Constants::SUPPORTS_SFTP, true);
|
||||
else
|
||||
storage->useGenericCopy = true;
|
||||
};
|
||||
const auto error = [this, method, storage](const FileTransfer &transfer) {
|
||||
const QString methodName = FileTransfer::transferMethodName(method);
|
||||
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 &) {
|
||||
const auto onDone = [this, commandName](const Process &process, bool success) {
|
||||
if (success) {
|
||||
emit q->progressMessage(Tr::tr("%1 found.").arg(commandName));
|
||||
};
|
||||
const auto error = [this, commandName](const Process &process) {
|
||||
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
|
||||
|
@@ -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)
|
||||
|
@@ -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 &) {
|
||||
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 &) {
|
||||
const auto onDone = [this](const Process &process, bool success) {
|
||||
if (success) {
|
||||
saveDeploymentTimeStamp(DeployableFile(m_packageFilePath, {}), {});
|
||||
addProgressMessage(Tr::tr("Successfully installed package file."));
|
||||
};
|
||||
const auto errorHandler = [this](const Process &process) {
|
||||
return;
|
||||
}
|
||||
addErrorMessage(Tr::tr("Installing package failed.") + process.errorString());
|
||||
};
|
||||
return ProcessTask(setupHandler, doneHandler, errorHandler);
|
||||
return ProcessTask(onSetup, onDone);
|
||||
}
|
||||
|
||||
GroupItem TarPackageDeployStep::deployRecipe()
|
||||
|
@@ -79,27 +79,27 @@ void Images::process()
|
||||
query.setNetworkAccessManager(&qnam);
|
||||
query.setRequest(QNetworkRequest(url));
|
||||
};
|
||||
const auto onDownloadDone = [storage](const NetworkQuery &query) {
|
||||
const auto onDownloadDone = [this, storage, i](const NetworkQuery &query, bool success) {
|
||||
if (success)
|
||||
*storage = query.reply()->readAll();
|
||||
};
|
||||
const auto onDownloadError = [this, i](const NetworkQuery &query) {
|
||||
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) {
|
||||
const auto onScalingDone = [this, i](const ConcurrentCall<QImage> &data, bool success) {
|
||||
if (success)
|
||||
labels[i]->setPixmap(QPixmap::fromImage(data.result()));
|
||||
};
|
||||
const auto onScalingError = [this, i](const ConcurrentCall<QImage> &) {
|
||||
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;
|
||||
|
Reference in New Issue
Block a user