From 5dcf2ba0fa303960ff9dbe40cb7a7e6a0043cd46 Mon Sep 17 00:00:00 2001 From: Christiaan Janssen Date: Wed, 10 Mar 2021 16:38:45 +0100 Subject: [PATCH] McuSupport: manage kits for different SDK versions side-by-side Task-number: QTCREATORBUG-25044 Change-Id: I6fbadd1e4192e9958ec4bb1a5bbbfe82c168fc2d Reviewed-by: Alessandro Portale --- src/plugins/mcusupport/mcusupportoptions.cpp | 137 +++++++++++++++++- src/plugins/mcusupport/mcusupportoptions.h | 11 +- .../mcusupport/mcusupportoptionspage.cpp | 2 + src/plugins/mcusupport/mcusupportplugin.cpp | 28 ++++ src/plugins/mcusupport/mcusupportplugin.h | 1 + 5 files changed, 173 insertions(+), 6 deletions(-) diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp index 698182f2ed2..3291bf1f2b0 100644 --- a/src/plugins/mcusupport/mcusupportoptions.cpp +++ b/src/plugins/mcusupport/mcusupportoptions.cpp @@ -26,6 +26,7 @@ #include "mcusupportconstants.h" #include "mcusupportoptions.h" #include "mcusupportsdk.h" +#include "mcusupportplugin.h" #include #include @@ -57,6 +58,8 @@ #include #include #include +#include +#include #include #include #include @@ -866,11 +869,11 @@ QString McuSupportOptions::kitName(const McuTarget *mcuTarget) compilerName); } -QList McuSupportOptions::existingKits(const McuTarget *mcuTarget) +QList McuSupportOptions::existingKits(const McuTarget *mcuTarget, bool autoDetectedOnly) { using namespace Constants; - return Utils::filtered(KitManager::kits(), [mcuTarget](Kit *kit) { - return kit->isAutoDetected() + return Utils::filtered(KitManager::kits(), [mcuTarget, autoDetectedOnly](Kit *kit) { + return (!autoDetectedOnly || kit->isAutoDetected()) && kit->value(KIT_MCUTARGET_KITVERSION_KEY) == KIT_VERSION && (!mcuTarget || ( kit->value(KIT_MCUTARGET_VENDOR_KEY) == mcuTarget->platform().vendor @@ -929,6 +932,42 @@ void printMessage(const QString &message, bool important) Core::MessageManager::writeSilently(displayMessage); } +QVersionNumber kitQulVersion(const Kit *kit) +{ + return QVersionNumber::fromString( + kit->value(McuSupport::Constants::KIT_MCUTARGET_SDKVERSION_KEY) + .toString()); +} + +QString kitDependencyPath(const Kit *kit, const QString &variableName) +{ + for (const NameValueItem &nameValueItem : EnvironmentKitAspect::environmentChanges(kit)) { + if (nameValueItem.name == variableName) + return nameValueItem.value; + } + return QString(); +} + +McuSupportOptions::UpgradeOption McuSupportOptions::askForKitUpgrades() +{ + QMessageBox upgradePopup(Core::ICore::dialogParent()); + upgradePopup.setStandardButtons(QMessageBox::Cancel); + QPushButton *replaceButton = upgradePopup.addButton(tr("Replace existing kits"),QMessageBox::NoRole); + QPushButton *keepButton = upgradePopup.addButton(tr("Create new kits"),QMessageBox::NoRole); + upgradePopup.setWindowTitle(tr("Qt for MCUs")); + upgradePopup.setText(tr("New version of Qt for MCUs detected. Upgrade existing Kits?")); + + upgradePopup.exec(); + + if (upgradePopup.clickedButton() == keepButton) + return Keep; + + if (upgradePopup.clickedButton() == replaceButton) + return Replace; + + return Ignore; +} + void McuSupportOptions::createAutomaticKits() { auto qtForMCUsPackage = Sdk::createQtForMCUsPackage(); @@ -974,15 +1013,32 @@ void McuSupportOptions::createAutomaticKits() QVector mcuTargets; Sdk::targetsAndPackages(dir, &packages, &mcuTargets); - for (auto target: qAsConst(mcuTargets)) - if (existingKits(target).isEmpty()) { + bool needsUpgrade = false; + for (auto target: qAsConst(mcuTargets)) { + const auto kitsForTarget = existingKits(target, false); + if (Utils::anyOf(kitsForTarget, [&target, &qtForMCUsPackage](const Kit *kit) { + return kitQulVersion(kit) == target->qulVersion() && + kitDependencyPath(kit, qtForMCUsPackage->environmentVariableName()) == qtForMCUsPackage->path(); + })) { + // if kit already exists, skip + continue; + } + if (!kitsForTarget.empty()) { + // if kit exists but wrong version/path + needsUpgrade = true; + } else { + // if no kits for this target, create if (target->isValid()) newKit(target, qtForMCUsPackage); target->printPackageProblems(); } + } qDeleteAll(packages); qDeleteAll(mcuTargets); + + if (needsUpgrade) + McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade(); } }; @@ -990,6 +1046,77 @@ void McuSupportOptions::createAutomaticKits() delete qtForMCUsPackage; } +void McuSupportOptions::checkUpgradeableKits() +{ + if (!qtForMCUsSdkPackage->validStatus() || mcuTargets.length() == 0) + return; + + const auto performCheck = [this]() { + const QString envVar = qtForMCUsSdkPackage->environmentVariableName(); + const QString path = qtForMCUsSdkPackage->path(); + for (auto target: qAsConst(this->mcuTargets)) { + const auto kitsForTarget = existingKits(target, false); + if (!kitsForTarget.empty() && + Utils::allOf(kitsForTarget, [&target, &envVar, &path](const Kit *kit) { + return kitQulVersion(kit) != target->qulVersion() || + kitDependencyPath(kit,envVar) != path; + })) + return true; + } + return false; + }; + + if (performCheck()) + upgradeKits(askForKitUpgrades()); +} + +void McuSupportOptions::upgradeKits(UpgradeOption upgradeOption) +{ + if (upgradeOption == Ignore) + return; + + auto qtForMCUsPackage = Sdk::createQtForMCUsPackage(); + + auto dir = FilePath::fromUserInput(qtForMCUsPackage->path()); + QVector packages; + QVector mcuTargets; + Sdk::targetsAndPackages(dir, &packages, &mcuTargets); + + const QString envVar = qtForMCUsPackage->environmentVariableName(); + const QString path = qtForMCUsPackage->path(); + + for (auto target: qAsConst(mcuTargets)) { + const auto kitsForTarget = existingKits(target, false); + if (Utils::anyOf(kitsForTarget, [&target, &envVar, &path](const Kit *kit) { + return kitQulVersion(kit) == target->qulVersion() && kitDependencyPath(kit, envVar) == path; + })) { + // already up-to-date + continue; + } + if (!kitsForTarget.empty()) { + for (auto existingKit : kitsForTarget) { + switch (upgradeOption) { + case Keep: + existingKit->setAutoDetected(false); + break; + case Replace: + KitManager::deregisterKit(existingKit); + break; + default: break; + } + } + + if (target->isValid()) + newKit(target, qtForMCUsPackage); + target->printPackageProblems(); + } + } + + qDeleteAll(packages); + qDeleteAll(mcuTargets); + delete qtForMCUsPackage; +} + /** * @brief Fix/update existing kits if needed */ diff --git a/src/plugins/mcusupport/mcusupportoptions.h b/src/plugins/mcusupport/mcusupportoptions.h index f94a8b5e8c8..3f44e215149 100644 --- a/src/plugins/mcusupport/mcusupportoptions.h +++ b/src/plugins/mcusupport/mcusupportoptions.h @@ -204,6 +204,12 @@ class McuSupportOptions : public QObject Q_OBJECT public: + enum UpgradeOption { + Ignore, + Keep, + Replace + }; + McuSupportOptions(QObject *parent = nullptr); ~McuSupportOptions() override; @@ -216,11 +222,14 @@ public: static QString kitName(const McuTarget* mcuTarget); - static QList existingKits(const McuTarget *mcuTarget); + static QList existingKits(const McuTarget *mcuTarget, bool autoDetectedOnly = true); static QList outdatedKits(); static void removeOutdatedKits(); static ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget, const McuPackage *qtForMCUsSdk); static void createAutomaticKits(); + static UpgradeOption askForKitUpgrades(); + static void upgradeKits(UpgradeOption upgradeOption); + void checkUpgradeableKits(); static void fixExistingKits(); void populatePackagesAndTargets(); static void registerQchFiles(); diff --git a/src/plugins/mcusupport/mcusupportoptionspage.cpp b/src/plugins/mcusupport/mcusupportoptionspage.cpp index c7e714856a3..dd56347c2ba 100644 --- a/src/plugins/mcusupport/mcusupportoptionspage.cpp +++ b/src/plugins/mcusupport/mcusupportoptionspage.cpp @@ -282,6 +282,8 @@ void McuSupportOptionsWidget::apply() m_options.qtForMCUsSdkPackage->writeToSettings(); for (auto package : qAsConst(m_options.packages)) package->writeToSettings(); + + m_options.checkUpgradeableKits(); } void McuSupportOptionsWidget::populateMcuTargetsComboBox() diff --git a/src/plugins/mcusupport/mcusupportplugin.cpp b/src/plugins/mcusupport/mcusupportplugin.cpp index 4a81ba2699a..65b588bce8b 100644 --- a/src/plugins/mcusupport/mcusupportplugin.cpp +++ b/src/plugins/mcusupport/mcusupportplugin.cpp @@ -122,5 +122,33 @@ void McuSupportPlugin::askUserAboutMcuSupportKitsSetup() ICore::infoBar()->addInfo(info); } +void McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade() +{ + const char upgradeMcuSupportKits[] = "UpgradeMcuSupportKits"; + + if (!ICore::infoBar()->canInfoBeAdded(upgradeMcuSupportKits)) + return; + + Utils::InfoBarEntry info(upgradeMcuSupportKits, + tr("New version of Qt for MCUs detected. Upgrade existing Kits?"), + Utils::InfoBarEntry::GlobalSuppression::Enabled); + + static McuSupportOptions::UpgradeOption selectedOption; + const QStringList options = { tr("Create new kits"), tr("Replace existing kits") }; + selectedOption = McuSupportOptions::UpgradeOption::Keep; + info.setComboInfo(options, [upgradeMcuSupportKits, options](const QString &selected) { + selectedOption = options.indexOf(selected) == 0 ? + McuSupportOptions::UpgradeOption::Keep : + McuSupportOptions::UpgradeOption::Replace; + }); + + info.setCustomButtonInfo(tr("Proceed"), [upgradeMcuSupportKits] { + ICore::infoBar()->removeInfo(upgradeMcuSupportKits); + QTimer::singleShot(0, []() { McuSupportOptions::upgradeKits(selectedOption); }); + }); + + ICore::infoBar()->addInfo(info); +} + } // namespace Internal } // namespace McuSupport diff --git a/src/plugins/mcusupport/mcusupportplugin.h b/src/plugins/mcusupport/mcusupportplugin.h index d3a1d8779ae..b8237f34128 100644 --- a/src/plugins/mcusupport/mcusupportplugin.h +++ b/src/plugins/mcusupport/mcusupportplugin.h @@ -44,6 +44,7 @@ public: bool initialize(const QStringList &arguments, QString *errorString) override; void extensionsInitialized() override; static void askUserAboutMcuSupportKitsSetup(); + static void askUserAboutMcuSupportKitsUpgrade(); }; } // namespace Internal