diff options
Diffstat (limited to 'src/libs/installer/installercalculator.cpp')
-rw-r--r-- | src/libs/installer/installercalculator.cpp | 201 |
1 files changed, 60 insertions, 141 deletions
diff --git a/src/libs/installer/installercalculator.cpp b/src/libs/installer/installercalculator.cpp index f285158f8..77989e3f8 100644 --- a/src/libs/installer/installercalculator.cpp +++ b/src/libs/installer/installercalculator.cpp @@ -49,7 +49,8 @@ InstallerCalculator::InstallerCalculator(PackageManagerCore *core, const AutoDep InstallerCalculator::InstallReasonType InstallerCalculator::installReasonType(const Component *c) const { - return m_toInstallComponentIdReasonHash.value(c->name()).first; + return m_toInstallComponentIdReasonHash.value(c->name(), + qMakePair(InstallerCalculator::Selected, QString())).first; } QString InstallerCalculator::installReason(const Component *component) const @@ -82,103 +83,77 @@ QString InstallerCalculator::componentsToInstallError() const return m_componentsToInstallError; } -bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &components, bool modelReset, const bool revertFromInstall) +bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &components) { if (components.isEmpty()) return true; QList<Component*> notAppendedComponents; // for example components with unresolved dependencies - foreach (Component *component, components) { + for (Component *component : qAsConst(components)){ if (!component) continue; - // When model has been reseted, there should not be components with the same name if (m_toInstallComponentIds.contains(component->name())) { - if (modelReset) { - const QString errorMessage = recursionError(component); - qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage; - m_componentsToInstallError.append(errorMessage); - Q_ASSERT_X(!m_toInstallComponentIds.contains(component->name()), Q_FUNC_INFO, - qPrintable(errorMessage)); - return false; - } - if (!revertFromInstall && !modelReset) { - // We can end up here if component is already added as dependency and - // user explicitly selects it to install. Increase the references to - // know when the component should be removed from install - const QStringList dependenciesList = component->currentDependencies(); - for (const QString &dependencyComponentName : dependenciesList) - calculateComponentDependencyReferences(dependencyComponentName, component); - continue; - } + const QString errorMessage = recursionError(component); + qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage; + m_componentsToInstallError.append(errorMessage); + Q_ASSERT_X(!m_toInstallComponentIds.contains(component->name()), Q_FUNC_INFO, + qPrintable(errorMessage)); + return false; } if (component->currentDependencies().isEmpty()) - realAppendToInstallComponents(component, QString(), revertFromInstall); + realAppendToInstallComponents(component); else notAppendedComponents.append(component); } - foreach (Component *component, notAppendedComponents) { - if (!appendComponentToInstall(component, QString(), revertFromInstall)) + for (Component *component : qAsConst(notAppendedComponents)) { + if (!appendComponentToInstall(component)) return false; } // All regular dependencies are resolved. Now we are looking for auto depend on components. - QSet<Component *> foundAutoDependOnList = autodependencyComponents(revertFromInstall); + QSet<Component *> foundAutoDependOnList = autodependencyComponents(); if (!foundAutoDependOnList.isEmpty()) - return appendComponentsToInstall(foundAutoDependOnList.values(), modelReset, revertFromInstall); - + return appendComponentsToInstall(foundAutoDependOnList.values()); return true; } -bool InstallerCalculator::removeComponentsFromInstall(const QList<Component *> &components) -{ - return appendComponentsToInstall(components, false, true); -} - QString InstallerCalculator::installReasonReferencedComponent(const Component *component) const { - const QString componentName = component->name(); - if (m_referenceCount.contains(componentName)) - return m_referenceCount.value(componentName).first(); - return m_toInstallComponentIdReasonHash.value(componentName, - qMakePair(InstallerCalculator::Selected, QString())).second; + return m_toInstallComponentIdReasonHash.value(component->name(), + qMakePair(InstallerCalculator::Selected, QString())).second; } -void InstallerCalculator::insertInstallReason(const Component *component, - const InstallReasonType installReason, const QString &referencedComponentName, const bool revertFromInstall) +void InstallerCalculator::insertInstallReason(Component *component, + InstallReasonType installReason, const QString &referencedComponentName) { - if (revertFromInstall && m_toInstallComponentIdReasonHash.contains(component->name())) { - m_toInstallComponentIdReasonHash.remove(component->name()); - } else if (!m_toInstallComponentIdReasonHash.contains(component->name())) { - m_toInstallComponentIdReasonHash.insert(component->name(), - qMakePair(installReason, referencedComponentName)); - } + // keep the first reason + if (m_toInstallComponentIdReasonHash.contains(component->name())) + return; + m_toInstallComponentIdReasonHash.insert(component->name(), + qMakePair(installReason, referencedComponentName)); } -void InstallerCalculator::realAppendToInstallComponents(Component *component, const QString &version, const bool revertFromInstall) +void InstallerCalculator::realAppendToInstallComponents(Component *component, const QString &version) { if (!m_componentsForAutodepencencyCheck.contains(component)) m_componentsForAutodepencencyCheck.append(component); - if (revertFromInstall) { - if (m_toInstallComponentIds.contains(component->name())) { - // Component is no longer added as dependency and is not explicitly selected for install by user - if (m_referenceCount.value(component->name()).isEmpty() && !component->isSelected()) { - m_toInstallComponentIds.remove(component->name()); - m_orderedComponentsToInstall.removeAll(component); - } - } - } else { - if (!component->isInstalled(version) - || (m_core->isUpdater() && component->isUpdateAvailable())) { - m_toInstallComponentIds.insert(component->name()); - m_orderedComponentsToInstall.append(component); - } + + if (!component->isInstalled(version) || (m_core->isUpdater() && component->isUpdateAvailable())) { + m_orderedComponentsToInstall.append(component); + m_toInstallComponentIds.insert(component->name()); } } -bool InstallerCalculator::appendComponentToInstall(Component *component, const QString &version, bool revertFromInstall) +QString InstallerCalculator::recursionError(Component *component) const +{ + return QCoreApplication::translate("InstallerCalculator", "Recursion detected, component \"%1\" " + "already added with reason: \"%2\"").arg(component->name(), installReason(component)); +} + +bool InstallerCalculator::appendComponentToInstall(Component *component, const QString &version) { const QStringList dependenciesList = component->currentDependencies(); QString requiredDependencyVersion = version; @@ -199,8 +174,6 @@ bool InstallerCalculator::appendComponentToInstall(Component *component, const Q return false; } } - if (revertFromInstall && dependencyComponent->forcedInstallation()) - continue; //Check if component requires higher version than what might be already installed bool isUpdateRequired = false; QString requiredName; @@ -221,72 +194,39 @@ bool InstallerCalculator::appendComponentToInstall(Component *component, const Q requiredDependencyVersion = requiredVersion; } } - - // Component can be requested for install by several component (as a dependency). - // Keep the reference count to a dependency component, so we know when component - // needs to be removed from install. Do not increase the reference count when - // the dependency is also autodependency as the component is removed anyway only - // when there are no references to the dependency. - if (revertFromInstall) { - if (m_toInstallComponentIds.contains(dependencyComponentName) - && m_referenceCount.contains(dependencyComponentName)) { - if (!component->autoDependencies().contains(dependencyComponentName)) { - QStringList &value = m_referenceCount[dependencyComponentName]; - if (value.contains(component->name())) { - value.removeOne(component->name()); - if (value.isEmpty()) - m_referenceCount.remove(dependencyComponentName); - } - } - } - insertInstallReason(dependencyComponent, InstallerCalculator::Dependent, - component->name(), true); - if (!appendComponentToInstall(dependencyComponent, requiredDependencyVersion, revertFromInstall)) + //Check dependencies only if + //- Dependency is not installed or update requested, nor newer version of dependency component required + //- And dependency component is not already added for install + //- And component is not already added for install, then dependencies are already resolved + if (((!dependencyComponent->isInstalled() || dependencyComponent->updateRequested()) + || isUpdateRequired) && (!m_toInstallComponentIds.contains(dependencyComponent->name()) + && !m_toInstallComponentIds.contains(component->name()))) { + if (m_visitedComponents.value(component).contains(dependencyComponent)) { + const QString errorMessage = recursionError(component); + qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage; + m_componentsToInstallError = errorMessage; + Q_ASSERT_X(!m_visitedComponents.value(component).contains(dependencyComponent), + Q_FUNC_INFO, qPrintable(errorMessage)); return false; - m_visitedComponents.remove(component); - } else { - //Check dependencies only if - //- Dependency is not installed or update requested, nor newer version of dependency component required - //- And dependency component is not already added for install - //- And component is not already added for install, then dependencies are already resolved - if (((!dependencyComponent->isInstalled() || dependencyComponent->updateRequested()) - || isUpdateRequired) && (!m_toInstallComponentIds.contains(dependencyComponent->name()) - && !m_toInstallComponentIds.contains(component->name()))) { - if (m_visitedComponents.value(component).contains(dependencyComponent)) { - const QString errorMessage = recursionError(component); - qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage; - m_componentsToInstallError = errorMessage; - Q_ASSERT_X(!m_visitedComponents.value(component).contains(dependencyComponent), - Q_FUNC_INFO, qPrintable(errorMessage)); - return false; - } - m_visitedComponents[component].insert(dependencyComponent); } - if (!component->autoDependencies().contains(dependencyComponentName)) - m_referenceCount[dependencyComponentName] << component->name(); + m_visitedComponents[component].insert(dependencyComponent); + // add needed dependency components to the next run + insertInstallReason(dependencyComponent, InstallerCalculator::Dependent, + component->name()); - insertInstallReason(dependencyComponent, InstallerCalculator::Dependent, component->name()); - if (!appendComponentToInstall(dependencyComponent, requiredDependencyVersion, revertFromInstall)) + if (!appendComponentToInstall(dependencyComponent, requiredDependencyVersion)) return false; } } - if (!revertFromInstall && !m_toInstallComponentIds.contains(component->name())) { - realAppendToInstallComponents(component, requiredDependencyVersion, revertFromInstall); + + if (!m_toInstallComponentIds.contains(component->name())) { + realAppendToInstallComponents(component, requiredDependencyVersion); insertInstallReason(component, InstallerCalculator::Resolved); } - if (revertFromInstall && m_toInstallComponentIds.contains(component->name())) { - realAppendToInstallComponents(component, requiredDependencyVersion, revertFromInstall); - } return true; } -QString InstallerCalculator::recursionError(const Component *component) const -{ - return QCoreApplication::translate("InstallerCalculator", "Recursion detected, component \"%1\" " - "already added with reason: \"%2\"").arg(component->name(), installReason(component)); -} - -QSet<Component *> InstallerCalculator::autodependencyComponents(const bool revertFromInstall) +QSet<Component *> InstallerCalculator::autodependencyComponents() { // All regular dependencies are resolved. Now we are looking for auto depend on components. // m_componentsForAutodepencencyCheck is a list of recently calculated components to be installed @@ -295,13 +235,12 @@ QSet<Component *> InstallerCalculator::autodependencyComponents(const bool rever QSet<Component *> foundAutoDependOnList; for (const Component *component : qAsConst(m_componentsForAutodepencencyCheck)) { if (!m_autoDependencyComponentHash.contains(component->name()) - || (!revertFromInstall && m_core->isUpdater() && !component->updateRequested())) + || (m_core->isUpdater() && !component->updateRequested())) continue; for (const QString& autoDependency : m_autoDependencyComponentHash.value(component->name())) { // If a components is already installed or is scheduled for installation, no need to check // for auto depend installation. - if ((!revertFromInstall && m_toInstallComponentIds.contains(autoDependency)) - || (revertFromInstall && !m_toInstallComponentIds.contains(autoDependency))) { + if (m_toInstallComponentIds.contains(autoDependency)) { continue; } Component *autoDependComponent = m_core->componentByName(autoDependency); @@ -316,10 +255,6 @@ QSet<Component *> InstallerCalculator::autodependencyComponents(const bool rever foundAutoDependOnList.insert(autoDependComponent); insertInstallReason(autoDependComponent, InstallerCalculator::Automatic); } - } else if (revertFromInstall - && m_toInstallComponentIds.contains(autoDependComponent->name()) - && !m_toInstallComponentIds.contains(component->name())) { - foundAutoDependOnList.insert(autoDependComponent); } } } @@ -327,20 +262,4 @@ QSet<Component *> InstallerCalculator::autodependencyComponents(const bool rever return foundAutoDependOnList; } -void InstallerCalculator::calculateComponentDependencyReferences(const QString &dependencyComponentName, const Component *component) -{ - Component *dependencyComponent = m_core->componentByName(dependencyComponentName); - if (!dependencyComponent || component->autoDependencies().contains(dependencyComponentName)) - return; - QStringList value = m_referenceCount.value(dependencyComponentName, QStringList()); - value << component->name(); - m_referenceCount.insert(dependencyComponentName, value); - - const QStringList dependenciesList = dependencyComponent->currentDependencies(); - for (const QString &depComponentName : dependenciesList) { - Component *depComponent = m_core->componentByName(depComponentName); - calculateComponentDependencyReferences(depComponentName, depComponent); - } -} - } // namespace QInstaller |