diff options
author | Katja Marttila <katja.marttila@qt.io> | 2022-11-03 18:08:15 +0200 |
---|---|---|
committer | Katja Marttila <katja.marttila@qt.io> | 2022-11-04 10:29:22 +0200 |
commit | b8877d4c0e09445f8b88797cc7da1f6a38764a41 (patch) | |
tree | df92d6de5aa9c70d8211d20badca008ddfef5daf | |
parent | 83b669586bd24fab082720876ff8aea75264ec36 (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>
-rw-r--r-- | src/libs/installer/packagemanagercore.cpp | 70 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore.h | 3 | ||||
-rw-r--r-- | src/libs/installer/uninstallercalculator.cpp | 55 | ||||
-rw-r--r-- | src/libs/installer/uninstallercalculator.h | 3 |
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; |