diff options
Diffstat (limited to 'src/libs/installer/uninstallercalculator.cpp')
-rw-r--r-- | src/libs/installer/uninstallercalculator.cpp | 170 |
1 files changed, 92 insertions, 78 deletions
diff --git a/src/libs/installer/uninstallercalculator.cpp b/src/libs/installer/uninstallercalculator.cpp index a8c47e523..9bcacb246 100644 --- a/src/libs/installer/uninstallercalculator.cpp +++ b/src/libs/installer/uninstallercalculator.cpp @@ -42,9 +42,16 @@ namespace QInstaller { \internal */ -UninstallerCalculator::UninstallerCalculator(const QList<Component *> &installedComponents, PackageManagerCore *core) +UninstallerCalculator::UninstallerCalculator(const QList<Component *> &installedComponents + , PackageManagerCore *core + , const QHash<QString, QStringList> &autoDependencyComponentHash + , const QHash<QString, QStringList> &dependencyComponentHash + , const QStringList &localVirtualComponents) : m_installedComponents(installedComponents) , m_core(core) + , m_autoDependencyComponentHash(autoDependencyComponentHash) + , m_dependencyComponentHash(dependencyComponentHash) + , m_localVirtualComponents(localVirtualComponents) { } @@ -53,7 +60,7 @@ QSet<Component *> UninstallerCalculator::componentsToUninstall() const return m_componentsToUninstall; } -void UninstallerCalculator::appendComponentToUninstall(Component *component) +void UninstallerCalculator::appendComponentToUninstall(Component *component, const bool reverse) { if (!component) return; @@ -61,79 +68,64 @@ void UninstallerCalculator::appendComponentToUninstall(Component *component) if (!component->isInstalled()) return; - // remove all already resolved dependees - const QList<Component *> dependeesList = m_core->dependees(component); - QSet<Component *> dependees = QSet<Component *>(dependeesList.begin(), - dependeesList.end()).subtract(m_componentsToUninstall); - - foreach (Component *dependee, dependees) { - appendComponentToUninstall(dependee); - insertUninstallReason(dependee, UninstallerCalculator::Dependent, component->name()); + if (m_dependencyComponentHash.contains(component->name())) { + const QStringList &dependencies = PackageManagerCore::parseNames(m_dependencyComponentHash.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 (reverse) { + m_componentsToUninstall.remove(component); + } else { + m_componentsToUninstall.insert(component); } - - m_componentsToUninstall.insert(component); } -void UninstallerCalculator::appendComponentsToUninstall(const QList<Component*> &components) +void UninstallerCalculator::appendComponentsToUninstall(const QList<Component*> &components, const bool reverse) { + if (components.isEmpty()) + return; foreach (Component *component, components) - appendComponentToUninstall(component); - + appendComponentToUninstall(component, reverse); QList<Component*> autoDependOnList; // All regular dependees are resolved. Now we are looking for auto depend on components. - foreach (Component *component, m_installedComponents) { + for (Component *component : components) { // If a components is installed and not yet scheduled for un-installation, check for auto depend. - if (component->isInstalled() && !m_componentsToUninstall.contains(component)) { - QStringList autoDependencies = PackageManagerCore::parseNames(component->autoDependencies()); - if (autoDependencies.isEmpty()) - continue; - - // This code needs to be enabled once the scripts use isInstalled, installationRequested and - // uninstallationRequested... - if (autoDependencies.first().compare(scScript, Qt::CaseInsensitive) == 0) { - //QScriptValue valueFromScript; - //try { - // valueFromScript = callScriptMethod(QLatin1String("isAutoDependOn")); - //} catch (const Error &error) { - // // keep the component, should do no harm - // continue; - //} - - //if (valueFromScript.isValid() && !valueFromScript.toBool()) - // autoDependOnList.append(component); - continue; - } - - foreach (Component *c, m_installedComponents) { - const QString replaces = c->value(scReplaces); - const QStringList possibleNames = replaces.split(QInstaller::commaRegExp(), - Qt::SkipEmptyParts) << c->name(); - foreach (const QString &possibleName, possibleNames) { - - Component *cc = PackageManagerCore::componentByName(possibleName, m_installedComponents); - if (cc && (cc->installAction() != ComponentModelHelper::AutodependUninstallation)) { - autoDependencies.removeAll(possibleName); - - } - } - } - - // A component requested auto uninstallation, keep it to resolve their dependencies as well. - if (!autoDependencies.isEmpty()) { - autoDependOnList.append(component); - insertUninstallReason(component, UninstallerCalculator::AutoDependent, autoDependencies.join(QLatin1String(", "))); - component->setInstallAction(ComponentModelHelper::AutodependUninstallation); + if (!m_autoDependencyComponentHash.contains(component->name())) + continue; + const QStringList autoDependencies = PackageManagerCore::parseNames(m_autoDependencyComponentHash.value(component->name())); + for (const QString &autoDependencyComponent : autoDependencies) { + Component *autoDepComponent = m_core->componentByName(autoDependencyComponent); + if (autoDepComponent && autoDepComponent->isInstalled()) { + // A component requested auto uninstallation, keep it to resolve their dependencies as well. + if (reverse) { + autoDependOnList.append(autoDepComponent); + } else if (!m_componentsToUninstall.contains(autoDepComponent)) { + insertUninstallReason(autoDepComponent, UninstallerCalculator::AutoDependent, component->name()); + autoDepComponent->setInstallAction(ComponentModelHelper::AutodependUninstallation); + autoDependOnList.append(autoDepComponent); + } } } } - if (!autoDependOnList.isEmpty()) - appendComponentsToUninstall(autoDependOnList); + appendComponentsToUninstall(autoDependOnList, reverse); else - appendVirtualComponentsToUninstall(); + appendVirtualComponentsToUninstall(reverse); +} + +void UninstallerCalculator::removeComponentsFromUnInstall(const QList<Component*> &components) +{ + appendComponentsToUninstall(components, true); } -void UninstallerCalculator::insertUninstallReason(Component *component, UninstallReasonType uninstallReason, +void UninstallerCalculator::insertUninstallReason(Component *component, const UninstallReasonType uninstallReason, const QString &referencedComponentName) { // keep the first reason @@ -176,34 +168,56 @@ QString UninstallerCalculator::uninstallReasonReferencedComponent(Component *com return m_toUninstallComponentIdReasonHash.value(component->name()).second; } - -void UninstallerCalculator::appendVirtualComponentsToUninstall() +void UninstallerCalculator::appendVirtualComponentsToUninstall(const bool reverse) { QList<Component*> unneededVirtualList; + // Check for virtual components without dependees - for (Component *component : qAsConst(m_installedComponents)) { - if (component->isInstalled() && component->isVirtual() && !m_componentsToUninstall.contains(component)) { - // Components with auto dependencies were handled in the previous step - if (!component->autoDependencies().isEmpty() || component->forcedInstallation()) - continue; - - bool required = false; - // Check if installed or about to be updated -packages are dependant on the package - for (Component *dependant : m_core->installDependants(component)) { - if (dependant->isInstalled() && !m_componentsToUninstall.contains(dependant)) { - required = true; - break; + 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 (!required) { - unneededVirtualList.append(component); - insertUninstallReason(component, UninstallerCalculator::VirtualDependent); + } + } else { + for (const QString &componentName : qAsConst(m_localVirtualComponents)) { + Component *virtualComponent = m_core->componentByName(componentName); + if (virtualComponent->isInstalled() && !m_componentsToUninstall.contains(virtualComponent)) { + // Components with auto dependencies were handled in the previous step + 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)) { + required = true; + break; + } + } + if (!required) { + unneededVirtualList.append(virtualComponent); + m_virtualComponentsForReverse.append(virtualComponent); + insertUninstallReason(virtualComponent, UninstallerCalculator::VirtualDependent); + } } } } if (!unneededVirtualList.isEmpty()) - appendComponentsToUninstall(unneededVirtualList); + appendComponentsToUninstall(unneededVirtualList, reverse); } } // namespace QInstaller |