AbstractProcessStep: Clean up code

Change-Id: Iae3d1e7cbd02d34da5cebbf0291948dbdd2e95df
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Tobias Hunger
2016-12-05 21:14:40 +01:00
parent 83028f76a8
commit 732b832973
4 changed files with 49 additions and 85 deletions

View File

@@ -273,11 +273,6 @@ void AndroidBuildApkStep::setUseGradle(bool b)
} }
} }
bool AndroidBuildApkStep::runInGuiThread() const
{
return true;
}
bool AndroidBuildApkStep::verboseOutput() const bool AndroidBuildApkStep::verboseOutput() const
{ {
return m_verbose; return m_verbose;

View File

@@ -73,8 +73,6 @@ public:
bool useGradle() const; bool useGradle() const;
void setUseGradle(bool b); void setUseGradle(bool b);
bool runInGuiThread() const override;
QString buildTargetSdk() const; QString buildTargetSdk() const;
void setBuildTargetSdk(const QString &sdk); void setBuildTargetSdk(const QString &sdk);

View File

@@ -26,12 +26,12 @@
#include "abstractprocessstep.h" #include "abstractprocessstep.h"
#include "ansifilterparser.h" #include "ansifilterparser.h"
#include "buildstep.h" #include "buildstep.h"
#include "ioutputparser.h"
#include "project.h" #include "project.h"
#include "task.h" #include "task.h"
#include <coreplugin/reaper.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <QTimer> #include <QTimer>
#include <QDir> #include <QDir>
@@ -84,21 +84,16 @@ using namespace ProjectExplorer;
AbstractProcessStep::AbstractProcessStep(BuildStepList *bsl, Core::Id id) : AbstractProcessStep::AbstractProcessStep(BuildStepList *bsl, Core::Id id) :
BuildStep(bsl, id) BuildStep(bsl, id)
{ } {
m_timer.setInterval(500);
connect(&m_timer, &QTimer::timeout, this, &AbstractProcessStep::checkForCancel);
}
AbstractProcessStep::AbstractProcessStep(BuildStepList *bsl, AbstractProcessStep::AbstractProcessStep(BuildStepList *bsl,
AbstractProcessStep *bs) : AbstractProcessStep *bs) :
BuildStep(bsl, bs), m_ignoreReturnValue(bs->m_ignoreReturnValue) BuildStep(bsl, bs), m_ignoreReturnValue(bs->m_ignoreReturnValue)
{ } { }
AbstractProcessStep::~AbstractProcessStep()
{
delete m_process;
delete m_timer;
// do not delete m_futureInterface, we do not own it.
delete m_outputParserChain;
}
/*! /*!
Deletes all existing output parsers and starts a new chain with the Deletes all existing output parsers and starts a new chain with the
given parser. given parser.
@@ -108,18 +103,16 @@ AbstractProcessStep::~AbstractProcessStep()
void AbstractProcessStep::setOutputParser(IOutputParser *parser) void AbstractProcessStep::setOutputParser(IOutputParser *parser)
{ {
delete m_outputParserChain; m_outputParserChain.reset(new AnsiFilterParser);
m_outputParserChain = new AnsiFilterParser;
m_outputParserChain->appendOutputParser(parser); m_outputParserChain->appendOutputParser(parser);
connect(m_outputParserChain, &IOutputParser::addOutput, this, &AbstractProcessStep::outputAdded); connect(m_outputParserChain.get(), &IOutputParser::addOutput, this, &AbstractProcessStep::outputAdded);
connect(m_outputParserChain, &IOutputParser::addTask, this, &AbstractProcessStep::taskAdded); connect(m_outputParserChain.get(), &IOutputParser::addTask, this, &AbstractProcessStep::taskAdded);
} }
/*! /*!
Appends the given output parser to the existing chain of parsers. Appends the given output parser to the existing chain of parsers.
*/ */
void AbstractProcessStep::appendOutputParser(IOutputParser *parser) void AbstractProcessStep::appendOutputParser(IOutputParser *parser)
{ {
if (!parser) if (!parser)
@@ -127,12 +120,11 @@ void AbstractProcessStep::appendOutputParser(IOutputParser *parser)
QTC_ASSERT(m_outputParserChain, return); QTC_ASSERT(m_outputParserChain, return);
m_outputParserChain->appendOutputParser(parser); m_outputParserChain->appendOutputParser(parser);
return;
} }
IOutputParser *AbstractProcessStep::outputParser() const IOutputParser *AbstractProcessStep::outputParser() const
{ {
return m_outputParserChain; return m_outputParserChain.get();
} }
void AbstractProcessStep::emitFaultyConfigurationMessage() void AbstractProcessStep::emitFaultyConfigurationMessage()
@@ -176,7 +168,6 @@ bool AbstractProcessStep::init(QList<const BuildStep *> &earlierSteps)
void AbstractProcessStep::run(QFutureInterface<bool> &fi) void AbstractProcessStep::run(QFutureInterface<bool> &fi)
{ {
m_futureInterface = &fi;
QDir wd(m_param.effectiveWorkingDirectory()); QDir wd(m_param.effectiveWorkingDirectory());
if (!wd.exists()) { if (!wd.exists()) {
if (!wd.mkpath(wd.absolutePath())) { if (!wd.mkpath(wd.absolutePath())) {
@@ -195,35 +186,30 @@ void AbstractProcessStep::run(QFutureInterface<bool> &fi)
return; return;
} }
m_process = new Utils::QtcProcess(); m_futureInterface.reset(&fi);
if (Utils::HostOsInfo::isWindowsHost())
m_process->setUseCtrlCStub(true); m_process.reset(new Utils::QtcProcess());
m_process->setUseCtrlCStub(Utils::HostOsInfo::isWindowsHost());
m_process->setWorkingDirectory(wd.absolutePath()); m_process->setWorkingDirectory(wd.absolutePath());
m_process->setEnvironment(m_param.environment()); m_process->setEnvironment(m_param.environment());
m_process->setCommand(effectiveCommand, m_param.effectiveArguments());
connect(m_process, &QProcess::readyReadStandardOutput, connect(m_process.get(), &QProcess::readyReadStandardOutput,
this, &AbstractProcessStep::processReadyReadStdOutput); this, &AbstractProcessStep::processReadyReadStdOutput);
connect(m_process, &QProcess::readyReadStandardError, connect(m_process.get(), &QProcess::readyReadStandardError,
this, &AbstractProcessStep::processReadyReadStdError); this, &AbstractProcessStep::processReadyReadStdError);
connect(m_process.get(), static_cast<void (QProcess::*)(int,QProcess::ExitStatus)>(&QProcess::finished),
connect(m_process, static_cast<void (QProcess::*)(int,QProcess::ExitStatus)>(&QProcess::finished),
this, &AbstractProcessStep::slotProcessFinished); this, &AbstractProcessStep::slotProcessFinished);
m_process->setCommand(effectiveCommand, m_param.effectiveArguments());
m_process->start(); m_process->start();
if (!m_process->waitForStarted()) { if (!m_process->waitForStarted()) {
processStartupFailed(); processStartupFailed();
delete m_process; m_process.reset();
m_process = nullptr;
reportRunResult(fi, false); reportRunResult(fi, false);
return; return;
} }
processStarted(); processStarted();
m_timer.start();
m_timer = new QTimer();
connect(m_timer, &QTimer::timeout, this, &AbstractProcessStep::checkForCancel);
m_timer->start(500);
m_killProcess = false;
} }
void AbstractProcessStep::cleanUp() void AbstractProcessStep::cleanUp()
@@ -232,19 +218,12 @@ void AbstractProcessStep::cleanUp()
processFinished(m_process->exitCode(), m_process->exitStatus()); processFinished(m_process->exitCode(), m_process->exitStatus());
const bool returnValue = processSucceeded(m_process->exitCode(), m_process->exitStatus()) || m_ignoreReturnValue; const bool returnValue = processSucceeded(m_process->exitCode(), m_process->exitStatus()) || m_ignoreReturnValue;
// Clean up output parsers m_outputParserChain.reset();
if (m_outputParserChain) { m_process.reset();
delete m_outputParserChain;
m_outputParserChain = nullptr;
}
// Clean up process
delete m_process;
m_process = nullptr;
// Report result // Report result
reportRunResult(*m_futureInterface, returnValue); reportRunResult(*(m_futureInterface.get()), returnValue);
m_futureInterface = nullptr; m_futureInterface.reset();
} }
/*! /*!
@@ -298,6 +277,7 @@ void AbstractProcessStep::processStartupFailed()
.arg(QDir::toNativeSeparators(m_param.effectiveCommand()), .arg(QDir::toNativeSeparators(m_param.effectiveCommand()),
m_param.prettyArguments()), m_param.prettyArguments()),
BuildStep::ErrorMessageOutput); BuildStep::ErrorMessageOutput);
m_timer.stop();
} }
/*! /*!
@@ -358,20 +338,14 @@ void AbstractProcessStep::stdError(const QString &line)
QFutureInterface<bool> *AbstractProcessStep::futureInterface() const QFutureInterface<bool> *AbstractProcessStep::futureInterface() const
{ {
return m_futureInterface; return m_futureInterface.get();
} }
void AbstractProcessStep::checkForCancel() void AbstractProcessStep::checkForCancel()
{ {
if (m_futureInterface->isCanceled() && m_timer->isActive()) { if (m_futureInterface->isCanceled() && m_timer.isActive()) {
if (!m_killProcess) { m_timer.stop();
m_process->terminate(); Core::Reaper::reap(m_process.release());
m_timer->start(5000);
m_killProcess = true;
} else {
m_process->kill();
m_timer->stop();
}
} }
} }
@@ -437,17 +411,15 @@ void AbstractProcessStep::outputAdded(const QString &string, BuildStep::OutputFo
void AbstractProcessStep::slotProcessFinished(int, QProcess::ExitStatus) void AbstractProcessStep::slotProcessFinished(int, QProcess::ExitStatus)
{ {
m_timer->stop(); m_timer.stop();
delete m_timer;
m_timer = nullptr;
QString line = QString::fromLocal8Bit(m_process->readAllStandardError()); const QString stdErrLine = QString::fromLocal8Bit(m_process->readAllStandardError());
if (!line.isEmpty()) if (!stdErrLine.isEmpty())
stdError(line); stdError(stdErrLine);
line = QString::fromLocal8Bit(m_process->readAllStandardOutput()); const QString stdoutLine = QString::fromLocal8Bit(m_process->readAllStandardOutput());
if (!line.isEmpty()) if (!stdoutLine.isEmpty())
stdOutput(line); stdOutput(stdoutLine);
cleanUp(); cleanUp();
} }

View File

@@ -28,29 +28,29 @@
#include "buildstep.h" #include "buildstep.h"
#include "processparameters.h" #include "processparameters.h"
#include <QString> #include <projectexplorer/ioutputparser.h>
#include <QProcess>
QT_BEGIN_NAMESPACE #include <utils/qtcprocess.h>
class QEventLoop;
class QTimer; #include <QString>
QT_END_NAMESPACE #include <QTimer>
#include <memory>
namespace Utils { class QtcProcess; } namespace Utils { class QtcProcess; }
namespace ProjectExplorer { namespace ProjectExplorer {
class IOutputParser; class IOutputParser;
// Documentation inside. // Documentation inside.
class PROJECTEXPLORER_EXPORT AbstractProcessStep : public BuildStep class PROJECTEXPLORER_EXPORT AbstractProcessStep : public BuildStep
{ {
Q_OBJECT Q_OBJECT
public: public:
~AbstractProcessStep() override;
bool init(QList<const BuildStep *> &earlierSteps) override; bool init(QList<const BuildStep *> &earlierSteps) override;
void run(QFutureInterface<bool> &) override; void run(QFutureInterface<bool> &) override;
bool runInGuiThread() const override { return true; } bool runInGuiThread() const final { return true; }
ProcessParameters *processParameters() { return &m_param; } ProcessParameters *processParameters() { return &m_param; }
@@ -88,14 +88,13 @@ private:
void outputAdded(const QString &string, BuildStep::OutputFormat format); void outputAdded(const QString &string, BuildStep::OutputFormat format);
QTimer *m_timer = nullptr; QTimer m_timer;
QFutureInterface<bool> *m_futureInterface = nullptr; std::unique_ptr<QFutureInterface<bool>> m_futureInterface;
std::unique_ptr<Utils::QtcProcess> m_process;
std::unique_ptr<IOutputParser> m_outputParserChain;
ProcessParameters m_param; ProcessParameters m_param;
bool m_ignoreReturnValue = false; bool m_ignoreReturnValue = false;
bool m_killProcess = false;
bool m_skipFlush = false; bool m_skipFlush = false;
Utils::QtcProcess *m_process = nullptr;
IOutputParser *m_outputParserChain = nullptr;
}; };
} // namespace ProjectExplorer } // namespace ProjectExplorer