From 82c175d76f1c40868b47f18d95376dce34e0416e Mon Sep 17 00:00:00 2001 From: Katja Marttila Date: Tue, 10 May 2022 07:29:03 +0300 Subject: Fix updating autodependency components Autodependency components were always forcely updated, even if 'Deselect All' was selected in component selection page. Fixed so that the autodependency component update is updated only when one of its dependants is updated. Task-number: QTIFW-2595 Change-Id: I05ececc45ef32ff80d53b008f839b358158a3316 Reviewed-by: Arttu Tarkiainen --- doc/installerfw.qdoc | 5 ++- doc/scripting-api/component.qdoc | 6 +++ src/libs/installer/component.cpp | 10 +++++ src/libs/installer/component.h | 1 + src/libs/installer/installercalculator.cpp | 11 ++++-- src/libs/installer/installercalculator.h | 3 +- src/libs/installer/packagemanagercore.cpp | 5 ++- src/libs/installer/packagemanagercore_p.cpp | 2 +- .../commandlineupdate/tst_commandlineupdate.cpp | 45 ++++++++++++++++++++-- tests/auto/installer/solver/tst_solver.cpp | 5 ++- 10 files changed, 78 insertions(+), 15 deletions(-) diff --git a/doc/installerfw.qdoc b/doc/installerfw.qdoc index 7c4fce45a..e4927f316 100644 --- a/doc/installerfw.qdoc +++ b/doc/installerfw.qdoc @@ -875,8 +875,9 @@ be selected for installation only when all components from this list are also selected for installation. If the component was already installed, it will - be selected for uninstallation when at least one of the components - from this list is also selected for uninstallation. + be selected for uninstallation or for update when at least one + of the components from this list is also selected for + uninstallation or for update. For more information, see \l{Component Dependencies}. \row \li Virtual diff --git a/doc/scripting-api/component.qdoc b/doc/scripting-api/component.qdoc index 4179914a1..51f36ac11 100644 --- a/doc/scripting-api/component.qdoc +++ b/doc/scripting-api/component.qdoc @@ -421,6 +421,12 @@ Determines whether the user wants to install the update for this component. */ +/*! + \qmlmethod boolean component::isUpdateAvailable() + + Determines whether update is available for component. +*/ + /*! \qmlmethod boolean component::componentChangeRequested() diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp index d8485f02a..702dd2763 100644 --- a/src/libs/installer/component.cpp +++ b/src/libs/installer/component.cpp @@ -1504,6 +1504,16 @@ void Component::setUpdateAvailable(bool isUpdateAvailable) d->m_updateIsAvailable = isUpdateAvailable; } +/*! + Returns whether update is available for this component. + + \sa {component::isUpdateAvailable}{component.isUpdateAvailable} +*/ +bool Component::isUpdateAvailable() const +{ + return d->m_updateIsAvailable && !isUnstable(); +} + /*! Returns whether the user wants to install the update for this component. diff --git a/src/libs/installer/component.h b/src/libs/installer/component.h index 1e83a1e9e..dbf604a56 100644 --- a/src/libs/installer/component.h +++ b/src/libs/installer/component.h @@ -194,6 +194,7 @@ public: Q_INVOKABLE bool isFromOnlineRepository() const; Q_INVOKABLE void setUpdateAvailable(bool isUpdateAvailable); + Q_INVOKABLE bool isUpdateAvailable() const; Q_INVOKABLE bool updateRequested(); Q_INVOKABLE bool componentChangeRequested(); diff --git a/src/libs/installer/installercalculator.cpp b/src/libs/installer/installercalculator.cpp index 60c0e5efd..21e82fc9a 100644 --- a/src/libs/installer/installercalculator.cpp +++ b/src/libs/installer/installercalculator.cpp @@ -41,8 +41,9 @@ namespace QInstaller { \internal */ -InstallerCalculator::InstallerCalculator(const QList &allComponents, const AutoDependencyHash &autoDependencyComponentHash) - : m_allComponents(allComponents) +InstallerCalculator::InstallerCalculator(PackageManagerCore *core, const QList &allComponents, const AutoDependencyHash &autoDependencyComponentHash) + : m_core(core) + , m_allComponents(allComponents) , m_autoDependencyComponentHash(autoDependencyComponentHash) { } @@ -166,7 +167,8 @@ void InstallerCalculator::realAppendToInstallComponents(Component *component, co } } } else { - if (!component->isInstalled(version) || component->updateRequested()) { + if (!component->isInstalled(version) + || (m_core->isUpdater() && component->isUpdateAvailable())) { m_toInstallComponentIds.insert(component->name()); m_orderedComponentsToInstall.append(component); } @@ -305,7 +307,8 @@ QSet InstallerCalculator::autodependencyComponents(const bool rever Component *autoDependComponent = PackageManagerCore::componentByName(autoDependency, m_allComponents); if (!autoDependComponent) continue; - if ((!autoDependComponent->isInstalled() || autoDependComponent->updateRequested()) + if ((!autoDependComponent->isInstalled() + || (m_core->isUpdater() && autoDependComponent->isUpdateAvailable())) && !m_toInstallComponentIds.contains(autoDependComponent->name())) { // One of the components autodependons is requested for install, check if there // are other autodependencies as well diff --git a/src/libs/installer/installercalculator.h b/src/libs/installer/installercalculator.h index 38909fde9..21b3775eb 100644 --- a/src/libs/installer/installercalculator.h +++ b/src/libs/installer/installercalculator.h @@ -43,7 +43,7 @@ class Component; class INSTALLER_EXPORT InstallerCalculator { public: - InstallerCalculator(const QList &allComponents, const AutoDependencyHash &autoDependencyComponentHash); + InstallerCalculator(PackageManagerCore *core, const QList &allComponents, const AutoDependencyHash &autoDependencyComponentHash); enum InstallReasonType { @@ -73,6 +73,7 @@ private: QSet autodependencyComponents(const bool revertFromInstall); private: + PackageManagerCore *m_core; QList m_allComponents; QHash > m_visitedComponents; QList m_componentsForAutodepencencyCheck; diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp index 1b1ca1eec..8ebaefd62 100644 --- a/src/libs/installer/packagemanagercore.cpp +++ b/src/libs/installer/packagemanagercore.cpp @@ -4242,8 +4242,9 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const return false; component->loadComponentScript(); - if (!component->isUnstable()) + if (!component->isUnstable() && component->autoDependencies().isEmpty()) component->setCheckState(Qt::Checked); + d->createDependencyHashes(component); } // after everything is set up, check installed components @@ -4252,7 +4253,7 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const return false; // even for possible dependency we need to load the script for example to get archives component->loadComponentScript(); - if (component->isInstalled()) { + if (component->isInstalled() && !component->autoDependencies().isEmpty()) { // since we do not put them into the model, which would force a update of e.g. tri state // components, we have to check all installed components ourselves if (!component->isUnstable()) diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp index 8f59fba81..85e902ac3 100644 --- a/src/libs/installer/packagemanagercore_p.cpp +++ b/src/libs/installer/packagemanagercore_p.cpp @@ -570,7 +570,7 @@ InstallerCalculator *PackageManagerCorePrivate::installerCalculator() const { if (!m_installerCalculator) { PackageManagerCorePrivate *const pmcp = const_cast (this); - pmcp->m_installerCalculator = new InstallerCalculator( + pmcp->m_installerCalculator = new InstallerCalculator(m_core, m_core->components(PackageManagerCore::ComponentType::AllNoReplacements), pmcp->m_autoDependencyComponentHash); } return m_installerCalculator; diff --git a/tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp b/tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp index 2aebb1c06..04b11d427 100644 --- a/tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp +++ b/tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp @@ -216,12 +216,11 @@ private slots: componentResourcesAfterUpdate.clear(); componentResourcesAfterUpdate.append(ComponentResource("componentA", "1.0.0content.txt")); componentResourcesAfterUpdate.append(ComponentResource("componentB", "1.0.0content.txt")); - componentResourcesAfterUpdate.append(ComponentResource("componentD", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentD", "1.0.0content.txt"));//AutodepenOn componentA,componentB componentResourcesAfterUpdate.append(ComponentResource("componentE", "2.0.0content.txt")); componentResourcesAfterUpdate.append(ComponentResource("componentG", "2.0.0content.txt")); deletedComponentResources.clear(); - deletedComponentResources.append(ComponentResource("componentD", "1.0.0content.txt")); deletedComponentResources.append(ComponentResource("componentE", "1.0.0content.txt")); deletedComponentResources.append(ComponentResource("componentG", "1.0.0content.txt")); @@ -240,7 +239,7 @@ private slots: << PackageManagerCore::Success << componentResourcesAfterUpdate << (QStringList() << "components.xml" << "installcontent.txt" << "installcontentA.txt" - << "installcontentD_update.txt" << "installcontentB.txt" + << "installcontentD.txt" << "installcontentB.txt" << "installcontentE_update.txt" << "installcontentG_update.txt") << deletedComponentResources; @@ -310,6 +309,46 @@ private slots: << "installcontentF_1_2.txt" << "installcontentF_2_update.txt" << "installcontentF_2_1.txt" << "installcontentF_2_2.txt" << "installcontentG_update.txt" << "installcontentH.txt") << deletedComponentResources; + + /*********** Update packages with AutoDependOn **********/ + componentResources.clear(); + componentResources.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentB", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentD", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentE", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentG", "1.0.0content.txt")); + + installDir = QInstaller::generateTemporaryFileName(); + core = PackageManager::getPackageManagerWithInit(installDir); + componentResourcesAfterUpdate.clear(); + componentResourcesAfterUpdate.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentB", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentD", "2.0.0content.txt"));//AutodepenOn componentA,componentB + componentResourcesAfterUpdate.append(ComponentResource("componentE", "2.0.0content.txt"));//ForcedInstall + componentResourcesAfterUpdate.append(ComponentResource("componentG", "1.0.0content.txt")); + + deletedComponentResources.clear(); + deletedComponentResources.append(ComponentResource("componentB", "1.0.0content.txt")); + deletedComponentResources.append(ComponentResource("componentD", "1.0.0content.txt")); + + QTest::newRow("Update packages with AutoDependOn") + << installDir + << core + << ":///data/installPackagesRepository" + << (QStringList()<< "componentA" << "componentB" << "componentE" << "componentG") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "installcontent.txt" << "installcontentA.txt" + << "installcontentD.txt" << "installcontentB.txt" << "installcontentE.txt" + << "installcontentG.txt") + << ":///data/installPackagesRepositoryUpdate" + << (QStringList() << "componentB") + << PackageManagerCore::Success + << componentResourcesAfterUpdate + << (QStringList() << "components.xml" << "installcontent.txt" << "installcontentA.txt" + << "installcontentD_update.txt" << "installcontentB_update.txt" + << "installcontentE_update.txt" << "installcontentG.txt") + << deletedComponentResources; } void testUpdate() diff --git a/tests/auto/installer/solver/tst_solver.cpp b/tests/auto/installer/solver/tst_solver.cpp index f4e10f5e7..45fadc4e6 100644 --- a/tests/auto/installer/solver/tst_solver.cpp +++ b/tests/auto/installer/solver/tst_solver.cpp @@ -192,7 +192,8 @@ private slots: QFETCH(QList, installReason); QFETCH(AutoDependencyHash, autodependencyHash); - InstallerCalculator calc(core->components(PackageManagerCore::ComponentType::AllNoReplacements), autodependencyHash); + InstallerCalculator calc(core, core->components(PackageManagerCore::ComponentType::AllNoReplacements) + , autodependencyHash); calc.appendComponentsToInstall(selectedComponents); QList result = calc.orderedComponentsToInstall(); @@ -235,7 +236,7 @@ private slots: QFETCH(QList , selectedComponents); QFETCH(QList , expectedResult); - InstallerCalculator calc(core->components(PackageManagerCore::ComponentType::AllNoReplacements), QHash()); + InstallerCalculator calc(core, core->components(PackageManagerCore::ComponentType::AllNoReplacements), QHash()); QTest::ignoreMessage(QtWarningMsg, "Cannot find missing dependency \"B->=2.0.0\" for \"A\"."); calc.appendComponentsToInstall(selectedComponents); -- cgit v1.2.3