QbsProjectManager: Rework parsing/rule execution logic again.

It does not seem to be safe to update CPP data etc and then continue
with rule execution. So now we do it like this: We execute rules if and
only if no target artifact data is present, and updates are only done
afterwards.

Change-Id: I580918a8ec434b2c59bd044506c3a8e961c6b674
Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
Christian Kandeler
2016-03-11 17:53:26 +01:00
parent 12574a4c74
commit 0bb8d52269
4 changed files with 58 additions and 36 deletions

View File

@@ -447,31 +447,15 @@ bool QbsProject::checkCancelStatus()
return true;
}
void QbsProject::handleProjectStructureAvailable()
void QbsProject::updateAfterParse()
{
QTC_ASSERT(m_qbsProjectParser, return);
qCDebug(qbsPmLog) << "Project structure available";
if (checkCancelStatus())
return;
m_qbsProject = m_qbsProjectParser->qbsProject();
QTC_ASSERT(m_qbsProject.isValid(), return);
const qbs::ProjectData &projectData = m_qbsProject.projectData();
if (projectData == m_projectData)
return;
qCDebug(qbsPmLog) << "Project data changed.";
m_projectData = projectData;
qCDebug(qbsPmLog) << "Updating data after parse";
rootProjectNode()->update();
updateDocuments(QSet<QString>() << projectFilePath().toString());
auto * const futureInterface = m_qbsUpdateFutureInterface;
m_qbsUpdateFutureInterface = nullptr; // So that isParsing() returns false;
updateBuildTargetData();
updateCppCodeModel();
updateQmlJsCodeModel();
emit fileListChanged();
m_qbsUpdateFutureInterface = futureInterface;
}
void QbsProject::handleQbsParsingDone(bool success)
@@ -479,31 +463,72 @@ void QbsProject::handleQbsParsingDone(bool success)
QTC_ASSERT(m_qbsProjectParser, return);
QTC_ASSERT(m_qbsUpdateFutureInterface, return);
qCDebug(qbsPmLog) << "Parsing done completely, success:" << success;
qCDebug(qbsPmLog) << "Parsing done, success:" << success;
if (checkCancelStatus())
return;
generateErrors(m_qbsProjectParser->error());
m_qbsProject = m_qbsProjectParser->qbsProject();
bool dataChanged = false;
if (success) {
QTC_ASSERT(m_qbsProject.isValid(), return);
m_projectData = m_qbsProject.projectData();
const qbs::ProjectData &projectData = m_qbsProject.projectData();
if (projectData != m_projectData) {
m_projectData = projectData;
dataChanged = true;
}
} else {
m_qbsUpdateFutureInterface->reportCanceled();
}
bool hasTargetArtifacts = false;
if (dataChanged) {
qCDebug(qbsPmLog) << "Project data changed.";
foreach (const qbs::ProductData &product, m_projectData.allProducts()) {
if (!product.targetArtifacts().isEmpty()) {
hasTargetArtifacts = true;
break;
}
}
if (!hasTargetArtifacts) {
qCDebug(qbsPmLog) << "No target artifacts present, executing rules";
m_qbsProjectParser->startRuleExecution();
return;
}
}
m_qbsProjectParser->deleteLater();
m_qbsProjectParser = 0;
m_qbsUpdateFutureInterface->reportFinished();
delete m_qbsUpdateFutureInterface;
m_qbsUpdateFutureInterface = 0;
if (success)
updateAfterBuild();
if (dataChanged)
updateAfterParse();
emit projectParsingDone(success);
}
void QbsProject::handleRuleExecutionDone()
{
qCDebug(qbsPmLog) << "Rule execution done";
if (checkCancelStatus())
return;
m_qbsProjectParser->deleteLater();
m_qbsProjectParser = 0;
m_qbsUpdateFutureInterface->reportFinished();
delete m_qbsUpdateFutureInterface;
m_qbsUpdateFutureInterface = 0;
QTC_ASSERT(m_qbsProject.isValid(), return);
m_projectData = m_qbsProject.projectData();
updateAfterParse();
emit projectParsingDone(true);
}
void QbsProject::targetWasAdded(Target *t)
{
connect(t, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
@@ -613,8 +638,8 @@ void QbsProject::registerQbsProjectParser(QbsProjectParser *p)
m_qbsProjectParser = p;
if (p) {
connect(m_qbsProjectParser, &QbsProjectParser::projectStructureAvailable,
this, &QbsProject::handleProjectStructureAvailable);
connect(m_qbsProjectParser, &QbsProjectParser::ruleExecutionDone,
this, &QbsProject::handleRuleExecutionDone);
connect(m_qbsProjectParser, SIGNAL(done(bool)), this, SLOT(handleQbsParsingDone(bool)));
}
}

View File

@@ -136,8 +136,9 @@ private:
void updateApplicationTargets();
void updateDeploymentInfo();
void updateBuildTargetData();
void handleProjectStructureAvailable();
void handleRuleExecutionDone();
bool checkCancelStatus();
void updateAfterParse();
void projectLoaded() override;
static bool ensureWriteableQbsFile(const QString &file);

View File

@@ -143,12 +143,7 @@ void QbsProjectParser::handleQbsParsingDone(bool success)
// Do not report the operation as canceled here, as we might want to make overlapping
// parses appear atomic to the user.
if (!success) {
emit done(false);
} else {
emit projectStructureAvailable();
startRuleExecution();
}
emit done(success);
}
void QbsProjectParser::startRuleExecution()
@@ -168,10 +163,11 @@ void QbsProjectParser::startRuleExecution()
void QbsProjectParser::handleRuleExecutionDone()
{
QTC_ASSERT(m_ruleExecutionJob, return);
// We always report success here, since execution of some very dynamic rules might fail due
// Execution of some very dynamic rules might fail due
// to artifacts not being present. No genuine errors will get lost, as they will re-appear
// on the next build attempt.
emit done(true);
emit ruleExecutionDone();
}
void QbsProjectParser::handleQbsParsingProgress(int progress)

View File

@@ -48,6 +48,7 @@ public:
~QbsProjectParser();
void parse(const QVariantMap &config, const Utils::Environment &env, const QString &dir);
void startRuleExecution();
void cancel();
qbs::Project qbsProject() const;
@@ -55,7 +56,7 @@ public:
signals:
void done(bool success);
void projectStructureAvailable();
void ruleExecutionDone();
private slots:
void handleQbsParsingDone(bool success);
@@ -67,7 +68,6 @@ private:
QString resourcesBaseDirectory() const;
QString libExecDirectory() const;
void startRuleExecution();
void handleRuleExecutionDone();
QString m_projectFilePath;