summaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2022-11-03 18:08:15 +0200
committerKatja Marttila <katja.marttila@qt.io>2022-11-04 10:29:22 +0200
commitb8877d4c0e09445f8b88797cc7da1f6a38764a41 (patch)
treedf92d6de5aa9c70d8211d20badca008ddfef5daf /src/libs
parent83b669586bd24fab082720876ff8aea75264ec36 (diff)
Fix virtual component uninstallation
Virtual components were still wrongly calculated for uninstall depending on which order the tree was clicked and whether the component had dependencies to already installed components or components about to be installed. Change-Id: I624fd1139d15d5e16c81365064dcea2392dc13b1 Reviewed-by: Arttu Tarkiainen <arttu.tarkiainen@qt.io>
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/installer/packagemanagercore.cpp70
-rw-r--r--src/libs/installer/packagemanagercore.h3
-rw-r--r--src/libs/installer/uninstallercalculator.cpp55
-rw-r--r--src/libs/installer/uninstallercalculator.h3
4 files changed, 77 insertions, 54 deletions
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 655d9cc7e..d0d635355 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -644,7 +644,7 @@ void PackageManagerCore::calculateUserSelectedComponentsToInstall(const QList<QM
UninstallerCalculator::UninstallReasonType::Replaced);
}
}
- // 2. Component is reseleted for install (tapping checkbox off/on)
+ // 2. Component is reselected for install (tapping checkbox off/on)
else if (installComponent->isSelected() && installComponent->isInstalled()
&& !d->installerCalculator()->orderedComponentsToInstall().contains(installComponent)) {
componentsToInstall.append(installComponent);
@@ -669,6 +669,13 @@ void PackageManagerCore::calculateUserSelectedComponentsToInstall(const QList<QM
d->uninstallerCalculator()->appendComponentsToUninstall(componentsToUnInstall, false);
}
d->uninstallerCalculator()->removeComponentsFromUnInstall(componentsToInstall);
+ if (componentsToUnInstall.isEmpty() && !componentsToInstall.isEmpty()) {
+ // There are no new components to be uninstalled but there
+ // are new components to be installed which might have virtual
+ // dependences to components which are already selected for uninstall.
+ // We need to remove those components from uninstall.
+ d->uninstallerCalculator()->appendVirtualComponentsToUninstall(true);
+ }
d->updateComponentCheckedState();
}
@@ -2395,44 +2402,65 @@ QList<Component*> PackageManagerCore::dependees(const Component *_component) con
}
/*!
- Returns a list of components that depend on \a component. The list can be
- empty. Dependendants are calculated from components which are about to be updated,
- if no update is requested then the dependant is calculated from installed packages.
-
- \note Automatic dependencies are not resolved.
+ Returns true if components which are about to be installed or updated
+ are dependent on \a component.
*/
-QList<Component*> PackageManagerCore::installDependants(const Component *component) const
+bool PackageManagerCore::isDependencyForRequestedComponent(const Component *component) const
{
if (!component)
- return QList<Component *>();
+ return false;
const QList<QInstaller::Component *> availableComponents = components(ComponentType::All);
if (availableComponents.isEmpty())
- return QList<Component *>();
+ return false;
- QList<Component *> dependants;
QString name;
QString version;
- foreach (Component *availableComponent, availableComponents) {
- if (isUpdater() && availableComponent->updateRequested()) {
+ for (Component *availableComponent : availableComponents) {
+ if (!availableComponent) {
+ continue;
+ }
+ // 1. In updater mode, component to be updated might have new dependencies
+ // Check if the dependency is still needed
+ // 2. If component is selected and not installed, check if the dependency is needed
+ if (availableComponent->isSelected()
+ && ((isUpdater() && availableComponent->isInstalled())
+ || (isPackageManager() && !availableComponent->isInstalled()))) {
const QStringList &dependencies = availableComponent->dependencies();
foreach (const QString &dependency, dependencies) {
parseNameAndVersion(dependency, &name, &version);
if (componentMatches(component, name, version)) {
- dependants.append(availableComponent);
+ return true;
}
}
- } else {
- KDUpdater::LocalPackage localPackage = d->m_localPackageHub->packageInfo(availableComponent->name());
- foreach (const QString &dependency, localPackage.dependencies) {
- parseNameAndVersion(dependency, &name, &version);
- if (componentMatches(component, name, version)) {
- dependants.append(availableComponent);
- }
+ }
+ }
+ return false;
+}
+
+
+/*!
+ Returns a list of local components which are dependent on \a component.
+*/
+QStringList PackageManagerCore::localDependenciesToComponent(const Component *component) const
+{
+ if (!component)
+ return QStringList();
+
+ QStringList dependents;
+ QString name;
+ QString version;
+
+ QMap<QString, LocalPackage> localPackages = d->m_localPackageHub->localPackages();
+ for (const KDUpdater::LocalPackage &localPackage : qAsConst(localPackages)) {
+ for (const QString &dependency : localPackage.dependencies) {
+ parseNameAndVersion(dependency, &name, &version);
+ if (componentMatches(component, name, version)) {
+ dependents.append(localPackage.name);
}
}
}
- return dependants;
+ return dependents;
}
/*!
diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h
index 2c307971a..cd1bbf306 100644
--- a/src/libs/installer/packagemanagercore.h
+++ b/src/libs/installer/packagemanagercore.h
@@ -248,7 +248,8 @@ public:
QString uninstallReason(Component *component) const;
QList<Component*> dependees(const Component *component) const;
- QList<Component*> installDependants(const Component *component) const;
+ bool isDependencyForRequestedComponent(const Component *component) const;
+ QStringList localDependenciesToComponent(const Component *component) const;
ComponentModel *defaultComponentModel() const;
ComponentModel *updaterComponentModel() const;
diff --git a/src/libs/installer/uninstallercalculator.cpp b/src/libs/installer/uninstallercalculator.cpp
index d54b5c2ab..36d769207 100644
--- a/src/libs/installer/uninstallercalculator.cpp
+++ b/src/libs/installer/uninstallercalculator.cpp
@@ -72,12 +72,16 @@ void UninstallerCalculator::appendComponentToUninstall(Component *component, con
const QStringList &dependencies = PackageManagerCore::parseNames(m_localDependencyComponentHash.value(component->name()));
for (const QString &dependencyComponent : dependencies) {
Component *depComponent = m_core->componentByName(dependencyComponent);
- if (depComponent && depComponent->isInstalled() && !m_componentsToUninstall.contains(depComponent)) {
- appendComponentToUninstall(depComponent, reverse);
- insertUninstallReason(depComponent, UninstallerCalculator::Dependent, component->name());
- } else if (reverse) {
- appendComponentToUninstall(depComponent, true);
- }
+ if (!depComponent)
+ continue;
+ if (depComponent->isInstalled() && !m_componentsToUninstall.contains(depComponent)) {
+ appendComponentToUninstall(depComponent, reverse);
+ insertUninstallReason(depComponent, UninstallerCalculator::Dependent, component->name());
+ } else if (reverse && depComponent->isVirtual()) {
+ // Remove from uninstall only hidden components, user
+ // can select other dependencies manually
+ appendComponentToUninstall(depComponent, true);
+ }
}
}
if (reverse) {
@@ -175,20 +179,8 @@ void UninstallerCalculator::appendVirtualComponentsToUninstall(const bool revers
// Check for virtual components without dependees
if (reverse) {
for (Component *reverseFromUninstall : qAsConst(m_virtualComponentsForReverse)) {
- if (m_componentsToUninstall.contains(reverseFromUninstall)) {
- bool required = false;
- // Check if installed or about to be updated -packages are dependant on the package
- const QList<Component*> installDependants = m_core->installDependants(reverseFromUninstall);
- for (Component *dependant : installDependants) {
- if (dependant->isInstalled() && !m_componentsToUninstall.contains(dependant)) {
- required = true;
- break;
- }
- }
- if (required) {
- unneededVirtualList.append(reverseFromUninstall);
- }
- }
+ if (m_componentsToUninstall.contains(reverseFromUninstall) && (isRequiredVirtualPackage(reverseFromUninstall)))
+ unneededVirtualList.append(reverseFromUninstall);
}
} else {
for (const QString &componentName : qAsConst(m_localVirtualComponents)) {
@@ -201,17 +193,7 @@ void UninstallerCalculator::appendVirtualComponentsToUninstall(const bool revers
if (!virtualComponent->autoDependencies().isEmpty() || virtualComponent->forcedInstallation())
continue;
- bool required = false;
- // Check if installed or about to be updated -packages are dependant on the package
- const QList<Component*> installDependants = m_core->installDependants(virtualComponent);
- for (Component *dependant : installDependants) {
- if ((dependant->isInstalled() && !m_componentsToUninstall.contains(dependant))
- || m_core->orderedComponentsToInstall().contains(dependant)) {
- required = true;
- break;
- }
- }
- if (!required) {
+ if (!isRequiredVirtualPackage(virtualComponent)) {
unneededVirtualList.append(virtualComponent);
m_virtualComponentsForReverse.append(virtualComponent);
insertUninstallReason(virtualComponent, UninstallerCalculator::VirtualDependent);
@@ -224,4 +206,15 @@ void UninstallerCalculator::appendVirtualComponentsToUninstall(const bool revers
appendComponentsToUninstall(unneededVirtualList, reverse);
}
+bool UninstallerCalculator::isRequiredVirtualPackage(Component *component)
+{
+ const QStringList localInstallDependents = m_core->localDependenciesToComponent(component);
+ for (const QString &dependent : localInstallDependents) {
+ Component *comp = m_core->componentByName(dependent);
+ if (!m_componentsToUninstall.contains(comp)) {
+ return true;
+ }
+ }
+ return m_core->isDependencyForRequestedComponent(component);
+}
} // namespace QInstaller
diff --git a/src/libs/installer/uninstallercalculator.h b/src/libs/installer/uninstallercalculator.h
index 76e32c6a6..57f2f926a 100644
--- a/src/libs/installer/uninstallercalculator.h
+++ b/src/libs/installer/uninstallercalculator.h
@@ -68,10 +68,11 @@ public:
QString uninstallReason(Component *component) const;
UninstallerCalculator::UninstallReasonType uninstallReasonType(Component *c) const;
QString uninstallReasonReferencedComponent(Component *component) const;
+ bool isRequiredVirtualPackage(Component *component);
+ void appendVirtualComponentsToUninstall(const bool reverse);
private:
void appendComponentToUninstall(Component *component, const bool reverse);
- void appendVirtualComponentsToUninstall(const bool reverse);
QList<Component *> m_installedComponents;
QSet<Component *> m_componentsToUninstall;