summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libs/installer/component.cpp8
-rw-r--r--src/libs/installer/component.h2
-rw-r--r--src/libs/installer/installercalculator.cpp66
-rw-r--r--src/libs/installer/installercalculator.h4
-rw-r--r--tests/auto/installer/solver/tst_solver.cpp40
5 files changed, 91 insertions, 29 deletions
diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp
index db9f2689d..d74b7ce7e 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -1241,9 +1241,13 @@ bool Component::isDefault() const
return d->m_vars.value(scDefault).compare(scTrue, Qt::CaseInsensitive) == 0;
}
-bool Component::isInstalled() const
+bool Component::isInstalled(const QString version) const
{
- return scInstalled == d->m_vars.value(scCurrentState);
+ if (version.isEmpty()) {
+ return scInstalled == d->m_vars.value(scCurrentState);
+ } else {
+ return d->m_vars.value(scInstalledVersion) == version;
+ }
}
/*!
diff --git a/src/libs/installer/component.h b/src/libs/installer/component.h
index 7492eaf54..01622548f 100644
--- a/src/libs/installer/component.h
+++ b/src/libs/installer/component.h
@@ -166,7 +166,7 @@ public:
Q_INVOKABLE bool isAutoDependOn(const QSet<QString> &componentsToInstall) const;
Q_INVOKABLE void setInstalled();
- Q_INVOKABLE bool isInstalled() const;
+ Q_INVOKABLE bool isInstalled(const QString version = QString()) const;
Q_INVOKABLE bool installationRequested() const;
bool isSelectedForInstallation() const;
diff --git a/src/libs/installer/installercalculator.cpp b/src/libs/installer/installercalculator.cpp
index 03c62033e..064dbafa5 100644
--- a/src/libs/installer/installercalculator.cpp
+++ b/src/libs/installer/installercalculator.cpp
@@ -92,9 +92,9 @@ QString InstallerCalculator::componentsToInstallError() const
return m_componentsToInstallError;
}
-void InstallerCalculator::realAppendToInstallComponents(Component *component)
+void InstallerCalculator::realAppendToInstallComponents(Component *component, const QString &version)
{
- if (!component->isInstalled() || component->updateRequested()) {
+ if (!component->isInstalled(version) || component->updateRequested()) {
m_orderedComponentsToInstall.append(component);
m_toInstallComponentIds.insert(component->name());
}
@@ -154,10 +154,10 @@ bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &co
return true;
}
-bool InstallerCalculator::appendComponentToInstall(Component *component)
+bool InstallerCalculator::appendComponentToInstall(Component *component, const QString &version)
{
QSet<QString> allDependencies = component->dependencies().toSet();
-
+ QString requiredDependencyVersion = version;
foreach (const QString &dependencyComponentName, allDependencies) {
// PackageManagerCore::componentByName returns 0 if dependencyComponentName contains a
// version which is not available
@@ -171,30 +171,50 @@ bool InstallerCalculator::appendComponentToInstall(Component *component)
m_componentsToInstallError.append(errorMessage);
return false;
}
+ //Check if component requires higher version than what might be already installed
+ bool isUpdateRequired = false;
+ if (dependencyComponentName.contains(QChar::fromLatin1('-')) &&
+ !dependencyComponent->value(scInstalledVersion).isEmpty()) {
+ QRegExp compEx(QLatin1String("([<=>]+)(.*)"));
+ const QString installedVersion = compEx.exactMatch(dependencyComponent->value(scInstalledVersion)) ?
+ compEx.cap(2) : dependencyComponent->value(scInstalledVersion);
+
+ QString requiredVersion = dependencyComponentName.section(QLatin1Char('-'), 1);
+ requiredVersion = compEx.exactMatch(requiredVersion) ? compEx.cap(2) : requiredVersion;
+
+ if (KDUpdater::compareVersion(requiredVersion, installedVersion) >= 1 ) {
+ isUpdateRequired = true;
+ requiredDependencyVersion = requiredVersion;
+ }
+ }
+ //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);
+ qWarning().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);
+
+ // add needed dependency components to the next run
+ insertInstallReason(dependencyComponent, InstallerCalculator::Dependent,
+ component->name());
- if ((!dependencyComponent->isInstalled() || dependencyComponent->updateRequested())
- && !m_toInstallComponentIds.contains(dependencyComponent->name())) {
- if (m_visitedComponents.value(component).contains(dependencyComponent)) {
- const QString errorMessage = recursionError(component);
- qWarning().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);
-
- // add needed dependency components to the next run
- insertInstallReason(dependencyComponent, InstallerCalculator::Dependent,
- component->name());
-
- if (!appendComponentToInstall(dependencyComponent))
- return false;
+ if (!appendComponentToInstall(dependencyComponent, requiredDependencyVersion))
+ return false;
}
}
if (!m_toInstallComponentIds.contains(component->name())) {
- realAppendToInstallComponents(component);
+ realAppendToInstallComponents(component, requiredDependencyVersion);
insertInstallReason(component, InstallerCalculator::Resolved);
}
return true;
diff --git a/src/libs/installer/installercalculator.h b/src/libs/installer/installercalculator.h
index 08dd47f78..b2d05bdbe 100644
--- a/src/libs/installer/installercalculator.h
+++ b/src/libs/installer/installercalculator.h
@@ -64,8 +64,8 @@ private:
void insertInstallReason(Component *component,
InstallReasonType installReasonType,
const QString &referencedComponentName = QString());
- void realAppendToInstallComponents(Component *component);
- bool appendComponentToInstall(Component *components);
+ void realAppendToInstallComponents(Component *component, const QString &version = QString());
+ bool appendComponentToInstall(Component *components, const QString &version = QString());
QString recursionError(Component *component);
QList<Component*> m_allComponents;
diff --git a/tests/auto/installer/solver/tst_solver.cpp b/tests/auto/installer/solver/tst_solver.cpp
index 5ccf0b2c8..5829621f2 100644
--- a/tests/auto/installer/solver/tst_solver.cpp
+++ b/tests/auto/installer/solver/tst_solver.cpp
@@ -155,15 +155,19 @@ private slots:
componentA->appendComponent(componentAA);
componentA->appendComponent(componentAB);
NamedComponent *componentB = new NamedComponent(core, QLatin1String("B"));
+ NamedComponent *componentB_NewVersion = new NamedComponent(core, QLatin1String("B_version"), QLatin1String("2.0.0"));
componentB->addDependency(QLatin1String("A.B"));
+ componentAB->addDependency(QLatin1String("B_version->=2.0.0"));
core->appendRootComponent(componentA);
core->appendRootComponent(componentB);
+ core->appendRootComponent(componentB_NewVersion);
QTest::newRow("Installer resolved") << core
<< (QList<Component *>() << componentB)
- << (QList<Component *>() << componentAB << componentB)
+ << (QList<Component *>() << componentB_NewVersion << componentAB << componentB)
<< (QList<int>()
<< InstallerCalculator::Dependent
+ << InstallerCalculator::Dependent
<< InstallerCalculator::Resolved);
}
@@ -186,6 +190,40 @@ private slots:
delete core;
}
+ void unresolvedDependencyVersion_data()
+ {
+ QTest::addColumn<PackageManagerCore *>("core");
+ QTest::addColumn<QList<Component *> >("selectedComponents");
+ QTest::addColumn<QList<Component *> >("expectedResult");
+
+ PackageManagerCore *core = new PackageManagerCore();
+ core->setPackageManager();
+ NamedComponent *componentA = new NamedComponent(core, QLatin1String("A"));
+ NamedComponent *componentB = new NamedComponent(core, QLatin1String("B"), QLatin1String("1.0.0"));
+ componentA->addDependency(QLatin1String("B->=2.0.0"));
+ core->appendRootComponent(componentA);
+ core->appendRootComponent(componentB);
+
+ QTest::newRow("Installer resolved") << core
+ << (QList<Component *>() << componentA)
+ << (QList<Component *>());
+ }
+
+ void unresolvedDependencyVersion()
+ {
+ QFETCH(PackageManagerCore *, core);
+ QFETCH(QList<Component *> , selectedComponents);
+ QFETCH(QList<Component *> , expectedResult);
+
+ InstallerCalculator calc(core->components(PackageManagerCore::ComponentType::AllNoReplacements));
+ QTest::ignoreMessage(QtWarningMsg, "Cannot find missing dependency \"B->=2.0.0\" for \"A\".");
+ calc.appendComponentsToInstall(selectedComponents);
+
+ QList<Component *> result = calc.orderedComponentsToInstall();
+ QCOMPARE(result.count(), expectedResult.count());
+ delete core;
+ }
+
void resolveUninstaller_data()
{
QTest::addColumn<PackageManagerCore *>("core");