McuSupport: Deregister kits for uninstalled target

Before the fix when the user uninstall a target, kits of the target will
remain visible on kits screen and can be selected when configuring a
project which is not a good user experience.

This change will use infobar to notify the user about the existence of
kits for uninstalled targets and ask the user if these kits should be
removed.

The change uses the fact that a kit description file have the
naming convention "toolchain-vendor-device" and compare it to the kits
exists in profile.xml. If a kit exists in profile.xml but its
description file doesn't (which mean the target has been uninstalled),
it will be removed from kits.

Task-number: QTCREATORBUG-28921
Change-Id: I9d4d1687429f26b6a42b77c5aa398f6bca5455d5
Reviewed-by: Sivert Krøvel <sivert.krovel@qt.io>
Reviewed-by: Yasser Grimes <yasser.grimes@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
This commit is contained in:
Karim Abdelrahman
2023-03-17 12:59:50 +02:00
parent 094b5294f6
commit 06c4a46a6c
4 changed files with 100 additions and 1 deletions

View File

@@ -721,5 +721,68 @@ void removeOutdatedKits()
KitManager::deregisterKit(kit); KitManager::deregisterKit(kit);
} }
/*
* using kitQmlImportPath of kit found in profile.xml to get the path to Qul
* installation where description file (.json) of the kit is located.
*/
static const FilePaths kitsFiles(const Kit *kit)
{
const FilePath qulRoot = kitDependencyPath(kit, Legacy::Constants::QUL_CMAKE_VAR);
return kitsPath(qulRoot).dirEntries(Utils::FileFilter({"*.json"}, QDir::Files));
}
/*
* When file description (.json) of a kit exists in the Qul installation that means
* target is installed.
*/
static bool anyKitDescriptionFileExists(const FilePaths &jsonFiles,
const QStringList &kitsProperties)
{
static const QRegularExpression re("(\\w+)-(\\w+)-(.+)\\.json");
for (const FilePath &jsonFile : jsonFiles) {
const QRegularExpressionMatch match = re.match(jsonFile.fileName());
QStringList kitsPropertiesFromFileName;
if (match.hasMatch()) {
const QString toolchain = match.captured(1).replace(
"gnu", "gcc"); // kitFileName contains gnu while profiles.xml contains gcc
const QString vendor = match.captured(2);
const QString device = match.captured(3);
kitsPropertiesFromFileName << toolchain << vendor << device;
}
if (kitsPropertiesFromFileName == kitsProperties)
return true;
}
return false;
}
const QList<Kit *> findUninstalledTargetsKits()
{
QList<Kit *> uninstalledTargetsKits;
for (Kit *kit : KitManager::kits()) {
if (!kit->hasValue(Constants::KIT_MCUTARGET_KITVERSION_KEY))
continue;
const QStringList kitsProperties = {
kit->value(Constants::KIT_MCUTARGET_TOOLCHAIN_KEY).toString().toLower(),
kit->value(Constants::KIT_MCUTARGET_VENDOR_KEY).toString().toLower(),
kit->value(Constants::KIT_MCUTARGET_MODEL_KEY).toString().toLower(),
};
const FilePaths kitsDescriptionFiles = kitsFiles(kit);
if (!anyKitDescriptionFileExists(kitsDescriptionFiles, kitsProperties))
uninstalledTargetsKits << kit;
}
return uninstalledTargetsKits;
}
void removeUninstalledTargetsKits(const QList<Kit *> uninstalledTargetsKits)
{
for (const auto &kit : uninstalledTargetsKits)
KitManager::deregisterKit(kit);
}
} // namespace McuKitManager } // namespace McuKitManager
} // namespace McuSupport::Internal } // namespace McuSupport::Internal

View File

@@ -56,6 +56,10 @@ void fixExistingKits(const SettingsHandler::Ptr &);
// Outdated kits: // Outdated kits:
void removeOutdatedKits(); void removeOutdatedKits();
// kits for uninstalled targets:
const QList<ProjectExplorer::Kit *> findUninstalledTargetsKits();
void removeUninstalledTargetsKits(const QList<ProjectExplorer::Kit *> uninstalledTargetsKits);
} // namespace McuKitManager } // namespace McuKitManager
} // namespace McuSupport::Internal } // namespace McuSupport::Internal

View File

@@ -135,6 +135,7 @@ void McuSupportPlugin::extensionsInitialized()
McuKitManager::createAutomaticKits(dd->m_settingsHandler); McuKitManager::createAutomaticKits(dd->m_settingsHandler);
McuKitManager::fixExistingKits(dd->m_settingsHandler); McuKitManager::fixExistingKits(dd->m_settingsHandler);
askUserAboutMcuSupportKitsSetup(); askUserAboutMcuSupportKitsSetup();
askUserAboutRemovingUninstalledTargetsKits();
}); });
} }
@@ -188,4 +189,34 @@ void McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade(const SettingsHandler::
ICore::infoBar()->addInfo(info); ICore::infoBar()->addInfo(info);
} }
} // McuSupport::Internal void McuSupportPlugin::askUserAboutRemovingUninstalledTargetsKits()
{
const char removeUninstalledKits[] = "RemoveUninstalledKits";
QList<Kit *> uninstalledTargetsKits;
if (!ICore::infoBar()->canInfoBeAdded(removeUninstalledKits)
|| (uninstalledTargetsKits = McuKitManager::findUninstalledTargetsKits()).isEmpty())
return;
Utils::InfoBarEntry
info(removeUninstalledKits,
Tr::tr("Detected %n uninstalled MCU target(s). Remove corresponding kits?",
nullptr,
uninstalledTargetsKits.size()),
Utils::InfoBarEntry::GlobalSuppression::Enabled);
info.addCustomButton(Tr::tr("Keep"), [removeUninstalledKits] {
ICore::infoBar()->removeInfo(removeUninstalledKits);
});
info.addCustomButton(Tr::tr("Remove"), [removeUninstalledKits, uninstalledTargetsKits] {
ICore::infoBar()->removeInfo(removeUninstalledKits);
QTimer::singleShot(0, [uninstalledTargetsKits]() {
McuKitManager::removeUninstalledTargetsKits(uninstalledTargetsKits);
});
});
ICore::infoBar()->addInfo(info);
}
} // namespace McuSupport::Internal

View File

@@ -24,6 +24,7 @@ public:
void askUserAboutMcuSupportKitsSetup(); void askUserAboutMcuSupportKitsSetup();
static void askUserAboutMcuSupportKitsUpgrade(const SettingsHandler::Ptr &settingsHandler); static void askUserAboutMcuSupportKitsUpgrade(const SettingsHandler::Ptr &settingsHandler);
static void askUserAboutRemovingUninstalledTargetsKits();
}; };
} // McuSupport::Internal } // McuSupport::Internal