From 3922b1a917c1b52fad8af82d60319f1e734457fd Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Tue, 21 Sep 2021 22:22:37 +0200 Subject: [PATCH] CMakePM: Add issue icon and tooltip description on project failure If a project fails to load it will be displayed with a warning icon. If the CMake configuration fails and the backup configuration is restored, the project is also marked with a warning icon. Change-Id: I95ccc5d171f5b789fe317fbb1da9e13dcd81a5dd Reviewed-by: Eike Ziller --- .../cmakeprojectmanager/cmakebuildsystem.cpp | 32 ++++++++++++++++--- .../cmakeprojectmanager/cmakebuildsystem.h | 7 ++-- .../cmakeprojectmanager/cmakeproject.cpp | 14 +++++++- .../cmakeprojectmanager/cmakeproject.h | 6 ++++ .../cmakeprojectmanager/fileapireader.cpp | 16 +++++++--- .../cmakeprojectmanager/fileapireader.h | 6 ++-- 6 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index eaded9a9683..d3a95645304 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -30,6 +30,7 @@ #include "cmakebuildstep.h" #include "cmakebuildtarget.h" #include "cmakekitinformation.h" +#include "cmakeproject.h" #include "cmakeprojectconstants.h" #include "cmakeprojectnodes.h" #include "cmakeprojectplugin.h" @@ -373,6 +374,8 @@ QString CMakeBuildSystem::reparseParametersString(int reparseFlags) void CMakeBuildSystem::setParametersAndRequestParse(const BuildDirParameters ¶meters, const int reparseParameters) { + project()->clearIssues(); + qCDebug(cmakeBuildSystemLog) << cmakeBuildConfiguration()->displayName() << "setting parameters and requesting reparse" << reparseParametersString(reparseParameters); @@ -467,7 +470,7 @@ void CMakeBuildSystem::handleTreeScanningFinished() m_waitingForScan = false; - combineScanAndParse(); + combineScanAndParse(m_reader.lastCMakeExitCode() != 0); } bool CMakeBuildSystem::persistCMakeState() @@ -528,7 +531,7 @@ std::unique_ptr CMakeBuildSystem::generateProjectTree( return root; } -void CMakeBuildSystem::combineScanAndParse() +void CMakeBuildSystem::combineScanAndParse(bool restoredFromBackup) { if (cmakeBuildConfiguration()->isActive()) { if (m_waitingForParse || m_waitingForScan) @@ -537,8 +540,22 @@ void CMakeBuildSystem::combineScanAndParse() if (m_combinedScanAndParseResult) { updateProjectData(); m_currentGuard.markAsSuccess(); + + if (restoredFromBackup) + project()->addIssue( + CMakeProject::IssueType::Error, + tr("CMake configuration failed" + "

The backup of the previous configuration has been restored.

" + "

Have a look at the Issues pane or in the \"Projects > Build\" settings " + "for more information about the failure.addIssue( + CMakeProject::IssueType::Error, + tr("Failed to load project" + "

Have a look at the Issues pane or in the \"Projects > Build\" settings " + "for more information about the failure.setConfigurationFromCMake(cmakeConfig); } -void CMakeBuildSystem::handleParsingSucceeded() +void CMakeBuildSystem::handleParsingSucceeded(bool restoredFromBackup) { if (!cmakeBuildConfiguration()->isActive()) { stopParsingAndClearState(); @@ -755,7 +772,7 @@ void CMakeBuildSystem::handleParsingSucceeded() QTC_ASSERT(m_waitingForParse, return ); m_waitingForParse = false; - combineScanAndParse(); + combineScanAndParse(restoredFromBackup); } void CMakeBuildSystem::handleParsingFailed(const QString &msg) @@ -772,7 +789,7 @@ void CMakeBuildSystem::handleParsingFailed(const QString &msg) m_waitingForParse = false; m_combinedScanAndParseResult = false; - combineScanAndParse(); + combineScanAndParse(false); } void CMakeBuildSystem::wireUpConnections() @@ -1073,6 +1090,11 @@ bool CMakeBuildSystem::usesAllCapsTargets() const return m_reader.usesAllCapsTargets(); } +CMakeProject *CMakeBuildSystem::project() const +{ + return static_cast(ProjectExplorer::BuildSystem::project()); +} + const QList CMakeBuildSystem::testcasesInfo() const { return m_testNames; diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h index 68a745a4dd5..4ed4342b01d 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h @@ -42,6 +42,7 @@ namespace ProjectExplorer { class ExtraCompiler; } namespace CMakeProjectManager { class CMakeBuildConfiguration; +class CMakeProject; namespace Internal { @@ -101,6 +102,8 @@ public: bool isMultiConfig() const; bool usesAllCapsTargets() const; + CMakeProject *project() const; + private: // Actually ask for parsing: enum ReparseParameters { @@ -128,7 +131,7 @@ private: void handleTreeScanningFinished(); // Combining Treescanner and Parser states: - void combineScanAndParse(); + void combineScanAndParse(bool restoredFromBackup); std::unique_ptr generateProjectTree( const ProjectExplorer::TreeScanner::Result &allFiles, bool failedToParse); @@ -143,7 +146,7 @@ private: const QList &moduleMappings); void updateInitialCMakeExpandableVars(); - void handleParsingSucceeded(); + void handleParsingSucceeded(bool restoredFromBackup); void handleParsingFailed(const QString &msg); void wireUpConnections(); diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index e683cca9054..9f881802c5d 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -26,8 +26,8 @@ #include "cmakeproject.h" #include "cmakebuildconfiguration.h" -#include "cmakebuildsystem.h" #include "cmakebuildstep.h" +#include "cmakebuildsystem.h" #include "cmakekitinformation.h" #include "cmakeprojectconstants.h" #include "cmakeprojectimporter.h" @@ -75,6 +75,8 @@ Tasks CMakeProject::projectIssues(const Kit *k) const if (ToolChainKitAspect::toolChains(k).isEmpty()) result.append(createProjectTask(Task::TaskType::Warning, tr("No compilers set in kit."))); + result.append(m_issues); + return result; } @@ -86,6 +88,16 @@ ProjectImporter *CMakeProject::projectImporter() const return m_projectImporter; } +void CMakeProject::addIssue(IssueType type, const QString &text) +{ + m_issues.append(createProjectTask(type, text)); +} + +void CMakeProject::clearIssues() +{ + m_issues.clear(); +} + bool CMakeProject::setupTarget(Target *t) { t->updateDefaultBuildConfigurations(); diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index c10bcbd32e1..3ff9303936b 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -48,6 +48,10 @@ public: ProjectExplorer::ProjectImporter *projectImporter() const final; + using IssueType = ProjectExplorer::Task::TaskType; + void addIssue(IssueType type, const QString &text); + void clearIssues(); + protected: bool setupTarget(ProjectExplorer::Target *t) final; @@ -59,6 +63,8 @@ private: mutable Internal::CMakeProjectImporter *m_projectImporter = nullptr; friend class Internal::CMakeBuildSystem; + + ProjectExplorer::Tasks m_issues; }; } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/fileapireader.cpp b/src/plugins/cmakeprojectmanager/fileapireader.cpp index eae84e18047..15f95637e2d 100644 --- a/src/plugins/cmakeprojectmanager/fileapireader.cpp +++ b/src/plugins/cmakeprojectmanager/fileapireader.cpp @@ -154,7 +154,7 @@ void FileApiReader::parse(bool forceCMakeRun, .arg(args.join("\", \"")); startCMakeState(args); } else { - endState(replyFile); + endState(replyFile, false); } } @@ -245,7 +245,7 @@ void FileApiReader::startState() emit configurationStarted(); } -void FileApiReader::endState(const FilePath &replyFilePath) +void FileApiReader::endState(const FilePath &replyFilePath, bool restoredFromBackup) { qCDebug(cmakeFileApiMode) << "FileApiReader: END STATE."; QTC_ASSERT(m_isParsing, return ); @@ -283,7 +283,7 @@ void FileApiReader::endState(const FilePath &replyFilePath) }); onResultReady(m_future.value(), this, - [this, topCmakeFile, sourceDirectory, buildDirectory]( + [this, topCmakeFile, sourceDirectory, buildDirectory, restoredFromBackup]( const std::shared_ptr &value) { m_isParsing = false; m_cache = std::move(value->cache); @@ -297,7 +297,7 @@ void FileApiReader::endState(const FilePath &replyFilePath) m_usesAllCapsTargets = std::move(value->usesAllCapsTargets); if (value->errorMessage.isEmpty()) { - emit this->dataAvailable(); + emit this->dataAvailable(restoredFromBackup); } else { emit this->errorOccurred(value->errorMessage); } @@ -352,6 +352,11 @@ void FileApiReader::writeConfigurationIntoBuildDirectory(const QStringList &conf QTC_CHECK(settingsFile.writeFileContents(contents)); } +int FileApiReader::lastCMakeExitCode() const +{ + return m_lastCMakeExitCode; +} + void FileApiReader::startCMakeState(const QStringList &configurationArguments) { qCDebug(cmakeFileApiMode) << "FileApiReader: START CMAKE STATE."; @@ -383,7 +388,8 @@ void FileApiReader::cmakeFinishedState() FileApiParser::setupCMakeFileApi(m_parameters.buildDirectory, m_watcher); - endState(FileApiParser::scanForCMakeReplyFile(m_parameters.buildDirectory)); + endState(FileApiParser::scanForCMakeReplyFile(m_parameters.buildDirectory), + m_lastCMakeExitCode != 0); } void FileApiReader::replyDirectoryHasChanged(const QString &directory) const diff --git a/src/plugins/cmakeprojectmanager/fileapireader.h b/src/plugins/cmakeprojectmanager/fileapireader.h index 30cdae42679..384e711df73 100644 --- a/src/plugins/cmakeprojectmanager/fileapireader.h +++ b/src/plugins/cmakeprojectmanager/fileapireader.h @@ -78,15 +78,17 @@ public: bool isMultiConfig() const; bool usesAllCapsTargets() const; + int lastCMakeExitCode() const; + signals: void configurationStarted() const; - void dataAvailable() const; + void dataAvailable(bool restoredFromBackup) const; void dirty() const; void errorOccurred(const QString &message) const; private: void startState(); - void endState(const Utils::FilePath &replyFilePath); + void endState(const Utils::FilePath &replyFilePath, bool restoredFromBackup); void startCMakeState(const QStringList &configurationArguments); void cmakeFinishedState();