(Re-)Start replacing ApplicationLauncher in SimpleTargetRunner

This is a second attempt, as just replacing with QtcProcess lost
functionality. Try again with baby steps.

This here effectively reverts commit b05fc053ef
and starts with pimpl'ing SimpleTargetRunner instead. Plan is to
follow-up with dissolving the ApplicationLauncher in the pimpl,
combine combinable pieces, and finally clean up. Ideally, not much
more that a slightly customized QtcProcess should be left.

Change-Id: I69e7b01588259fe60bb76ef1ba741a183322c4de
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
hjk
2022-05-23 11:01:05 +02:00
parent f4b7faff18
commit 21d0175dab
2 changed files with 47 additions and 46 deletions

View File

@@ -25,6 +25,7 @@
#include "runcontrol.h" #include "runcontrol.h"
#include "applicationlauncher.h"
#include "devicesupport/desktopdevice.h" #include "devicesupport/desktopdevice.h"
#include "devicesupport/idevice.h" #include "devicesupport/idevice.h"
#include "abi.h" #include "abi.h"
@@ -1189,16 +1190,33 @@ void RunControlPrivate::debugMessage(const QString &msg)
// SimpleTargetRunner // SimpleTargetRunner
namespace Internal {
class SimpleTargetRunnerPrivate
{
public:
ApplicationLauncher m_launcher;
std::function<void()> m_starter;
bool m_stopReported = false;
bool m_stopForced = false;
};
} // Internal
SimpleTargetRunner::SimpleTargetRunner(RunControl *runControl) SimpleTargetRunner::SimpleTargetRunner(RunControl *runControl)
: RunWorker(runControl) : RunWorker(runControl), d(new Internal::SimpleTargetRunnerPrivate)
{ {
setId("SimpleTargetRunner"); setId("SimpleTargetRunner");
} }
SimpleTargetRunner::~SimpleTargetRunner() = default;
void SimpleTargetRunner::start() void SimpleTargetRunner::start()
{ {
if (m_starter) { if (d->m_starter) {
m_starter(); d->m_starter();
} else { } else {
Runnable runnable = runControl()->runnable(); Runnable runnable = runControl()->runnable();
runnable.device = runControl()->device(); runnable.device = runControl()->device();
@@ -1216,55 +1234,40 @@ void SimpleTargetRunner::doStart(const Runnable &runnable)
if (auto runAsRootAspect = runControl()->aspect<RunAsRootAspect>()) if (auto runAsRootAspect = runControl()->aspect<RunAsRootAspect>())
runAsRoot = runAsRootAspect->value; runAsRoot = runAsRootAspect->value;
Environment env = runnable.environment; d->m_stopForced = false;
if (runAsRoot) d->m_stopReported = false;
RunControl::provideAskPassEntry(env); d->m_launcher.disconnect(this);
d->m_launcher.setUseTerminal(useTerminal);
m_stopForced = false; d->m_launcher.setRunAsRoot(runAsRoot);
m_stopReported = false;
m_launcher.disconnect(this);
m_launcher.setTerminalMode(useTerminal ? TerminalMode::On : TerminalMode::Off);
m_launcher.setRunAsRoot(runAsRoot);
m_launcher.setCommand(runnable.command);
m_launcher.setWorkingDirectory(runnable.workingDirectory);
m_launcher.setEnvironment(env);
m_launcher.setExtraData(runnable.extraData);
const QString msg = RunControl::tr("Starting %1...").arg(runnable.command.toUserOutput()); const QString msg = RunControl::tr("Starting %1...").arg(runnable.command.toUserOutput());
appendMessage(msg, Utils::NormalMessageFormat); appendMessage(msg, Utils::NormalMessageFormat);
connect(&m_launcher, &QtcProcess::done, this, [this, runnable] { connect(&d->m_launcher, &ApplicationLauncher::done, this, [this, runnable] {
if (m_stopReported) if (d->m_stopReported)
return; return;
const QString executable = runnable.command.executable().toUserOutput(); const QString executable = runnable.command.executable().toUserOutput();
const ProcessResultData resultData = m_launcher.resultData(); const ProcessResultData resultData = d->m_launcher.resultData();
QString msg = tr("%2 exited with code %1").arg(resultData.m_exitCode).arg(executable); QString msg = tr("%2 exited with code %1").arg(resultData.m_exitCode).arg(executable);
if (resultData.m_exitStatus == QProcess::CrashExit) if (resultData.m_exitStatus == QProcess::CrashExit)
msg = tr("%1 crashed.").arg(executable); msg = tr("%1 crashed.").arg(executable);
else if (m_stopForced) else if (d->m_stopForced)
msg = tr("The process was ended forcefully."); msg = tr("The process was ended forcefully.");
else if (resultData.m_error != QProcess::UnknownError) else if (resultData.m_error != QProcess::UnknownError)
msg = userMessageForProcessError(resultData.m_error, runnable.command.executable()); msg = userMessageForProcessError(resultData.m_error, runnable.command.executable());
appendMessage(msg, NormalMessageFormat); appendMessage(msg, NormalMessageFormat);
m_stopReported = true; d->m_stopReported = true;
reportStopped(); reportStopped();
}); });
connect(&m_launcher, &QtcProcess::readyReadStandardOutput, this, [this] { connect(&d->m_launcher, &ApplicationLauncher::appendMessage, this, &RunWorker::appendMessage);
appendMessage(QString::fromUtf8(m_launcher.readAllStandardOutput()), StdOutFormat);
});
connect(&m_launcher, &QtcProcess::readyReadStandardError, this, [this] {
appendMessage(QString::fromUtf8(m_launcher.readAllStandardError()), StdErrFormat);
});
const bool isDesktop = runnable.device.isNull() const bool isDesktop = runnable.device.isNull()
|| runnable.device.dynamicCast<const DesktopDevice>(); || runnable.device.dynamicCast<const DesktopDevice>();
if (isDesktop) { if (isDesktop) {
connect(&m_launcher, &QtcProcess::started, this, [this] { connect(&d->m_launcher, &ApplicationLauncher::started, this, [this] {
// Console processes only know their pid after being started // Console processes only know their pid after being started
ProcessHandle pid = ProcessHandle(m_launcher.processId()); ProcessHandle pid = d->m_launcher.applicationPID();
runControl()->setApplicationProcessHandle(pid); runControl()->setApplicationProcessHandle(pid);
pid.activate(); pid.activate();
reportStarted(); reportStarted();
@@ -1275,20 +1278,21 @@ void SimpleTargetRunner::doStart(const Runnable &runnable)
return; return;
} }
} else { } else {
connect(&m_launcher, &QtcProcess::started, this, &RunWorker::reportStarted); connect(&d->m_launcher, &ApplicationLauncher::started, this, &RunWorker::reportStarted);
} }
m_launcher.start(); d->m_launcher.setRunnable(runnable);
d->m_launcher.start();
} }
void SimpleTargetRunner::stop() void SimpleTargetRunner::stop()
{ {
m_stopForced = true; d->m_stopForced = true;
m_launcher.kill(); d->m_launcher.stop();
} }
void SimpleTargetRunner::setStarter(const std::function<void ()> &starter) void SimpleTargetRunner::setStarter(const std::function<void ()> &starter)
{ {
m_starter = starter; d->m_starter = starter;
} }

View File

@@ -25,7 +25,6 @@
#pragma once #pragma once
#include "applicationlauncher.h"
#include "buildconfiguration.h" #include "buildconfiguration.h"
#include "devicesupport/idevicefwd.h" #include "devicesupport/idevicefwd.h"
#include "projectexplorerconstants.h" #include "projectexplorerconstants.h"
@@ -33,21 +32,21 @@
#include <utils/commandline.h> #include <utils/commandline.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/icon.h> #include <utils/outputformatter.h>
#include <utils/processhandle.h> #include <utils/processhandle.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <QHash> #include <QHash>
#include <QProcess> // FIXME: Remove
#include <QVariant> #include <QVariant>
#include <functional> #include <functional>
#include <memory> #include <memory>
namespace Utils { namespace Utils {
class Icon;
class MacroExpander; class MacroExpander;
class OutputLineParser; class OutputLineParser;
class OutputFormatter;
} // Utils } // Utils
namespace ProjectExplorer { namespace ProjectExplorer {
@@ -60,6 +59,7 @@ class Target;
namespace Internal { namespace Internal {
class RunControlPrivate; class RunControlPrivate;
class RunWorkerPrivate; class RunWorkerPrivate;
class SimpleTargetRunnerPrivate;
} // Internal } // Internal
@@ -285,7 +285,7 @@ private:
/** /**
* A simple TargetRunner for cases where a plain QtcProcess is * A simple TargetRunner for cases where a plain ApplicationLauncher is
* sufficient for running purposes. * sufficient for running purposes.
*/ */
@@ -295,6 +295,7 @@ class PROJECTEXPLORER_EXPORT SimpleTargetRunner : public RunWorker
public: public:
explicit SimpleTargetRunner(RunControl *runControl); explicit SimpleTargetRunner(RunControl *runControl);
~SimpleTargetRunner() override;
protected: protected:
void setStarter(const std::function<void()> &starter); void setStarter(const std::function<void()> &starter);
@@ -306,11 +307,7 @@ private:
const Runnable &runnable() const = delete; const Runnable &runnable() const = delete;
Utils::QtcProcess m_launcher; const std::unique_ptr<Internal::SimpleTargetRunnerPrivate> d;
std::function<void()> m_starter;
bool m_stopReported = false;
bool m_stopForced = false;
}; };
class PROJECTEXPLORER_EXPORT OutputFormatterFactory class PROJECTEXPLORER_EXPORT OutputFormatterFactory