summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libs/installer/packagemanagercore.cpp41
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp32
-rw-r--r--src/libs/installer/packagemanagercore_p.h4
-rw-r--r--tests/auto/installer/componentreplace/data/installPackagesRepository/C/1.0.0content.7zbin0 -> 152 bytes
-rw-r--r--tests/auto/installer/componentreplace/data/installPackagesRepository/Updates.xml10
-rw-r--r--tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/C/2.0.0content.7zbin0 -> 152 bytes
-rw-r--r--tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/Updates.xml10
-rw-r--r--tests/auto/installer/componentreplace/settings.qrc2
-rw-r--r--tests/auto/installer/componentreplace/tst_componentreplace.cpp72
9 files changed, 138 insertions, 33 deletions
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index f0b923024..918b01ad6 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -570,7 +570,7 @@ void PackageManagerCore::cancelMetaInfoJob()
void PackageManagerCore::componentsToInstallNeedsRecalculation()
{
d->clearInstallerCalculator();
- d->clearUninstallerCalculator();
+
QList<Component*> selectedComponentsToInstall = componentsMarkedForInstallation();
d->m_componentsToInstallCalculated =
@@ -578,13 +578,7 @@ void PackageManagerCore::componentsToInstallNeedsRecalculation()
QList<Component *> componentsToInstall = d->installerCalculator()->orderedComponentsToInstall();
- QList<Component *> selectedComponentsToUninstall;
- foreach (Component *component, components(ComponentType::All)) {
- if (component->uninstallationRequested() && !selectedComponentsToInstall.contains(component))
- selectedComponentsToUninstall.append(component);
- }
-
- d->uninstallerCalculator()->appendComponentsToUninstall(selectedComponentsToUninstall);
+ d->calculateUninstallComponents();
QSet<Component *> componentsToUninstall = d->uninstallerCalculator()->componentsToUninstall();
@@ -2165,20 +2159,8 @@ bool PackageManagerCore::calculateComponentsToUninstall() const
{
emit aboutCalculateComponentsToUninstall();
if (!isUpdater()) {
- // hack to avoid removing needed dependencies
- const QList<Component *> componentsToInstallList
- = d->installerCalculator()->orderedComponentsToInstall();
- QSet<Component*> componentsToInstall(componentsToInstallList.begin(), componentsToInstallList.end());
-
- QList<Component*> componentsToUninstall;
- foreach (Component *component, components(ComponentType::All)) {
- if (component->uninstallationRequested() && !componentsToInstall.contains(component))
- componentsToUninstall.append(component);
- }
-
- d->clearUninstallerCalculator();
+ d->calculateUninstallComponents();
d->storeCheckState();
- d->uninstallerCalculator()->appendComponentsToUninstall(componentsToUninstall);
}
emit finishedCalculateComponentsToUninstall();
return true;
@@ -3873,7 +3855,7 @@ void PackageManagerCore::storeReplacedComponents(QHash<QString, Component *> &co
key = treeNameComponents->value(componentName);
treeNameComponents->remove(componentName);
}
- Component *componentToReplace = components.take(key);
+ Component *componentToReplace = components.value(key);
if (!componentToReplace) {
// If a component replaces another component which is not existing in the
// installer binary or the installed component list, just ignore it. This
@@ -3882,8 +3864,21 @@ void PackageManagerCore::storeReplacedComponents(QHash<QString, Component *> &co
qCWarning(QInstaller::lcDeveloperBuild) << componentName << "- Does not exist in the repositories anymore.";
continue;
}
- d->replacementDependencyComponents().append(componentToReplace);
+ // Remove the replaced component from instal tree if
+ // 1. Running installer (component is replaced by other component)
+ // 2. Replacement is already installed but replacable is not
+ // Do not remove the replaced component from install tree
+ // in updater so that would show as an update
+ // Also do not remove the replaced component from install tree
+ // if it is already installed together with replacable component,
+ // otherwise it does not match what we have defined in components.xml
+ if (!isUpdater()
+ && (isInstaller() || (it.key() && it.key()->isInstalled() && !componentToReplace->isInstalled()))) {
+ components.remove(key);
+ d->m_deletedReplacedComponents.append(componentToReplace);
+ }
d->componentsToReplace().insert(componentName, qMakePair(it.key(), componentToReplace));
+ d->replacementDependencyComponents().append(componentToReplace);
}
}
}
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index 154f2f638..4aaa27cfd 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -514,14 +514,11 @@ void PackageManagerCorePrivate::clearAllComponentLists()
{
QList<QInstaller::Component*> toDelete;
- toDelete << m_rootComponents;
+ toDelete << m_rootComponents << m_deletedReplacedComponents;
m_rootComponents.clear();
-
m_rootDependencyReplacements.clear();
+ m_deletedReplacedComponents.clear();
- const QList<QPair<Component*, Component*> > list = m_componentsToReplaceAllMode.values();
- for (int i = 0; i < list.count(); ++i)
- toDelete << list.at(i).second;
m_componentsToReplaceAllMode.clear();
m_componentsToInstallCalculated = false;
@@ -2783,6 +2780,29 @@ bool PackageManagerCorePrivate::calculateComponentsAndRun()
return false;
}
+void PackageManagerCorePrivate::calculateUninstallComponents()
+{
+ clearUninstallerCalculator();
+ const QList<Component *> componentsToInstallList = installerCalculator()->orderedComponentsToInstall();
+ QSet<Component*> componentsToInstall(componentsToInstallList.begin(), componentsToInstallList.end());
+
+ QList<Component *> selectedComponentsToUninstall;
+ foreach (Component* component, m_core->components(PackageManagerCore::ComponentType::Replacements)) {
+ // Uninstall the component if replacement is selected for install or update
+ QPair<Component*, Component*> comp = componentsToReplace().value(component->name());
+ if (comp.first) {
+ if (comp.first->isSelectedForInstallation() || comp.first->updateRequested()) {
+ selectedComponentsToUninstall.append(comp.second);
+ }
+ }
+ }
+ foreach (Component *component, m_core->components(PackageManagerCore::ComponentType::AllNoReplacements)) {
+ if (component->uninstallationRequested() && !componentsToInstallList.contains(component))
+ selectedComponentsToUninstall.append(component);
+ }
+ uninstallerCalculator()->appendComponentsToUninstall(selectedComponentsToUninstall);
+}
+
bool PackageManagerCorePrivate::acceptLicenseAgreements() const
{
// Always skip for uninstaller
diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h
index 73c378f43..d17a752f9 100644
--- a/src/libs/installer/packagemanagercore_p.h
+++ b/src/libs/installer/packagemanagercore_p.h
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -250,6 +250,7 @@ private:
void findExecutablesRecursive(const QString &path, const QStringList &excludeFiles, QStringList *result);
QStringList runningInstallerProcesses(const QStringList &exludeFiles);
bool calculateComponentsAndRun();
+ void calculateUninstallComponents();
bool acceptLicenseAgreements() const;
bool askUserAcceptLicense(const QString &name, const QString &content) const;
bool askUserConfirmCommand() const;
@@ -294,6 +295,7 @@ private:
void restoreCheckState();
void storeCheckState();
QHash<Component*, Qt::CheckState> m_coreCheckedHash;
+ QList<Component*> m_deletedReplacedComponents;
};
} // namespace QInstaller
diff --git a/tests/auto/installer/componentreplace/data/installPackagesRepository/C/1.0.0content.7z b/tests/auto/installer/componentreplace/data/installPackagesRepository/C/1.0.0content.7z
new file mode 100644
index 000000000..d498f1900
--- /dev/null
+++ b/tests/auto/installer/componentreplace/data/installPackagesRepository/C/1.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/componentreplace/data/installPackagesRepository/Updates.xml b/tests/auto/installer/componentreplace/data/installPackagesRepository/Updates.xml
index 6f02aad2b..e77207777 100644
--- a/tests/auto/installer/componentreplace/data/installPackagesRepository/Updates.xml
+++ b/tests/auto/installer/componentreplace/data/installPackagesRepository/Updates.xml
@@ -42,4 +42,14 @@
<DownloadableArchives>content.7z</DownloadableArchives>
<SHA1>a10463141e30ce3fede9ac84bc52a07b0c5e919e</SHA1>
</PackageUpdate>
+ <PackageUpdate>
+ <Name>C</Name>
+ <DisplayName>C component</DisplayName>
+ <Description>Component C</Description>
+ <Version>1.0.0</Version>
+ <ReleaseDate>2021-01-01</ReleaseDate>
+ <UpdateFile UncompressedSize="89" CompressedSize="247" OS="Any"/>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ <SHA1>a10463141e30ce3fede9ac84bc52a07b0c5e919e</SHA1>
+ </PackageUpdate>
</Updates>
diff --git a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/C/2.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/C/2.0.0content.7z
new file mode 100644
index 000000000..d498f1900
--- /dev/null
+++ b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/C/2.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/Updates.xml b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/Updates.xml
index 5276637ed..e0fb351ff 100644
--- a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/Updates.xml
+++ b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/Updates.xml
@@ -43,4 +43,14 @@
<DownloadableArchives>content.7z</DownloadableArchives>
<SHA1>4331736562fc047a4f47263be75f816298cbda30</SHA1>
</PackageUpdate>
+ <PackageUpdate>
+ <Name>C</Name>
+ <DisplayName>C component</DisplayName>
+ <Description>Component C</Description>
+ <Version>2.0.0</Version>
+ <ReleaseDate>2021-01-01</ReleaseDate>
+ <UpdateFile UncompressedSize="89" CompressedSize="247" OS="Any"/>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ <SHA1>a10463141e30ce3fede9ac84bc52a07b0c5e919e</SHA1>
+ </PackageUpdate>
</Updates>
diff --git a/tests/auto/installer/componentreplace/settings.qrc b/tests/auto/installer/componentreplace/settings.qrc
index 706cf91c6..ba1b0ab98 100644
--- a/tests/auto/installer/componentreplace/settings.qrc
+++ b/tests/auto/installer/componentreplace/settings.qrc
@@ -5,6 +5,7 @@
<file>data/installPackagesRepository/B/1.0.0content.7z</file>
<file>data/installPackagesRepository/A.sub1/1.0.0content.7z</file>
<file>data/installPackagesRepository/B.sub1/1.0.0content.7z</file>
+ <file>data/installPackagesRepository/C/1.0.0content.7z</file>
<file>data/repositoryWithReplace/Updates.xml</file>
<file>data/repositoryWithReplace/A/1.0.0content.7z</file>
<file>data/repositoryWithReplace/B/2.0.0content.7z</file>
@@ -25,5 +26,6 @@
<file>data/repositoryWithMultiReplaceInUpdate/B/2.0.0content.7z</file>
<file>data/repositoryWithMultiReplaceInUpdate/A.sub1/1.0.0content.7z</file>
<file>data/repositoryWithMultiReplaceInUpdate/B.sub1/1.0.0content.7z</file>
+ <file>data/repositoryWithMultiReplaceInUpdate/C/2.0.0content.7z</file>
</qresource>
</RCC>
diff --git a/tests/auto/installer/componentreplace/tst_componentreplace.cpp b/tests/auto/installer/componentreplace/tst_componentreplace.cpp
index 55121019b..98fee27d0 100644
--- a/tests/auto/installer/componentreplace/tst_componentreplace.cpp
+++ b/tests/auto/installer/componentreplace/tst_componentreplace.cpp
@@ -87,11 +87,11 @@ private slots:
core->setPackageManager();
setRepository(":///data/repositoryWithReplace", core);
QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "B"));
-
+ QCOMPARE(core->componentsToUninstall().count(), 1);
QVERIFY(core->componentByName("B.sub1") != 0);
QVERIFY(core->componentByName("B") != 0);
- QVERIFY(core->componentByName("A.sub1") != 0);
- QVERIFY(core->componentByName("A") == 0); // B has replaced A
+ VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt");
VerifyInstaller::verifyInstallerResources(m_installDir, "B", "2.0.0content.txt");
VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt");
VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml"
@@ -117,6 +117,7 @@ private slots:
core->setUpdater();
setRepository(":///data/repositoryWithReplace", core);
QCOMPARE(PackageManagerCore::Success, core->updateComponentsSilently(QStringList() << "B"));
+ QCOMPARE(core->componentsToUninstall().count(), 1);
VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A", "1.0.0content.txt");
VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt");
VerifyInstaller::verifyInstallerResources(m_installDir, "B", "2.0.0content.txt");
@@ -144,6 +145,7 @@ private slots:
core->setUpdater();
setRepository(":///data/repositoryWithUpdateToReplaceble", core);
QCOMPARE(PackageManagerCore::Success, core->updateComponentsSilently(QStringList() << "B"));
+ QCOMPARE(core->componentsToUninstall().count(), 1);
VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A", "1.0.0content.txt");
VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A", "2.0.0content.txt");
VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt");
@@ -169,6 +171,7 @@ private slots:
core->setPackageManager();
setRepository(":///data/repositoryWithMultiReplace", core);
QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "B"));
+ QCOMPARE(core->componentsToUninstall().count(), 2);
VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A", "1.0.0content.txt");
VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A.sub1", "1.0.0content.txt");
VerifyInstaller::verifyInstallerResources(m_installDir, "B", "1.0.0content.txt");
@@ -196,6 +199,7 @@ private slots:
core->setUpdater();
setRepository(":///data/repositoryWithMultiReplaceInUpdate", core);
QCOMPARE(PackageManagerCore::Success, core->updateComponentsSilently(QStringList() << "B"));
+ QCOMPARE(core->componentsToUninstall().count(), 2);
VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A", "1.0.0content.txt");
VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A.sub1", "1.0.0content.txt");
VerifyInstaller::verifyInstallerResources(m_installDir, "B", "2.0.0content.txt");
@@ -205,6 +209,68 @@ private slots:
delete core;
}
+ void installOtherComponentsWhileReplacementsExists()
+ {
+ PackageManagerCore *core = PackageManager::getPackageManagerWithInit
+ (m_installDir, ":///data/installPackagesRepository");
+ QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "A" << "B"));
+
+ QCOMPARE(core->orderedComponentsToInstall().count(), 4);
+ VerifyInstaller::verifyInstallerResources(m_installDir, "A", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "B", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt");
+ VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml"
+ << "Asub1.txt" << "A.txt"<< "Bsub1.txt" << "B.txt");
+
+ core->commitSessionOperations();
+ core->setPackageManager();
+ setRepository(":///data/repositoryWithMultiReplaceInUpdate", core);
+ QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "C"));
+ QCOMPARE(core->orderedComponentsToInstall().count(), 1);
+ QCOMPARE(core->componentsToUninstall().count(), 0);
+ VerifyInstaller::verifyInstallerResources(m_installDir, "A", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "B", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "C", "2.0.0content.txt");
+ VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml"
+ << "Asub1.txt" << "A.txt"<< "Bsub1.txt" << "B.txt" << "C.txt");
+
+ delete core;
+ }
+
+ void updateOtherComponentsWhileReplacementsExists()
+ {
+ PackageManagerCore *core = PackageManager::getPackageManagerWithInit
+ (m_installDir, ":///data/installPackagesRepository");
+ QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "A" << "B" << "C"));
+
+ QCOMPARE(core->orderedComponentsToInstall().count(), 5);
+ VerifyInstaller::verifyInstallerResources(m_installDir, "A", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "B", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt");
+ VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml"
+ << "Asub1.txt" << "A.txt"<< "Bsub1.txt" << "B.txt" << "C.txt");
+
+ core->commitSessionOperations();
+ core->setUpdater();
+ setRepository(":///data/repositoryWithMultiReplaceInUpdate", core);
+ QCOMPARE(PackageManagerCore::Success, core->updateComponentsSilently(QStringList() << "C"));
+ QCOMPARE(core->orderedComponentsToInstall().count(), 1);
+ QCOMPARE(core->componentsToUninstall().count(), 0);
+ VerifyInstaller::verifyInstallerResources(m_installDir, "A", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "B", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt");
+ VerifyInstaller::verifyInstallerResources(m_installDir, "C", "2.0.0content.txt");
+ VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml"
+ << "Asub1.txt" << "A.txt"<< "Bsub1.txt" << "B.txt" << "C.txt");
+
+ delete core;
+ }
+
void cleanup()
{
QDir dir(m_installDir);