McuSupport: manage kits for different SDK versions side-by-side

Task-number: QTCREATORBUG-25044
Change-Id: I6fbadd1e4192e9958ec4bb1a5bbbfe82c168fc2d
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Christiaan Janssen
2021-03-10 16:38:45 +01:00
committed by christiaan.janssen
parent a202301918
commit 5dcf2ba0fa
5 changed files with 173 additions and 6 deletions

View File

@@ -26,6 +26,7 @@
#include "mcusupportconstants.h"
#include "mcusupportoptions.h"
#include "mcusupportsdk.h"
#include "mcusupportplugin.h"
#include <baremetal/baremetalconstants.h>
#include <cmakeprojectmanager/cmaketoolmanager.h>
@@ -57,6 +58,8 @@
#include <QDir>
#include <QFileInfo>
#include <QLabel>
#include <QMessageBox>
#include <QPushButton>
#include <QToolButton>
#include <QVBoxLayout>
#include <QVariant>
@@ -866,11 +869,11 @@ QString McuSupportOptions::kitName(const McuTarget *mcuTarget)
compilerName);
}
QList<Kit *> McuSupportOptions::existingKits(const McuTarget *mcuTarget)
QList<Kit *> 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<McuTarget*> 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<McuPackage*> packages;
QVector<McuTarget*> 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
*/

View File

@@ -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<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTarget);
static QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTarget, bool autoDetectedOnly = true);
static QList<ProjectExplorer::Kit *> 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();

View File

@@ -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()

View File

@@ -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

View File

@@ -44,6 +44,7 @@ public:
bool initialize(const QStringList &arguments, QString *errorString) override;
void extensionsInitialized() override;
static void askUserAboutMcuSupportKitsSetup();
static void askUserAboutMcuSupportKitsUpgrade();
};
} // namespace Internal