From 716b30b1cdb3fdc7eb75ccffbada0e223a2e7086 Mon Sep 17 00:00:00 2001 From: Katja Marttila Date: Thu, 17 Nov 2022 14:04:52 +0200 Subject: Fix errors occurring in full uninstall on macOS Maintenance Tool can be retrieved from online repositories like any other component. The component contains files which are listed to remove correct files in uninstall. As Maintenance Tool differs a bit from other components in the matter that it should not be deleted in full uninstall as it is running, we need to exclude the Maintenance Tool (which we call also installerbasebinary), from the file list. Maintenance Tool itself is removed in PackageManagerCorePrivate::deleteMaintenanceTool() Task-number: QTIFW-2875 Change-Id: I33a16e632e3b354099b749d8dde7b65f5cef8f43 Reviewed-by: Qt CI Bot Reviewed-by: Arttu Tarkiainen --- src/libs/installer/extractarchiveoperation.cpp | 17 +++++++++-- src/libs/installer/packagemanagercore.cpp | 11 +++++++ src/libs/installer/packagemanagercore.h | 1 + .../installer/extractarchiveoperationtest/data.qrc | 3 ++ .../data/installerbaserepository/A/1.0.0content.7z | Bin 0 -> 98 bytes .../A/1.0.0installerbase.7z | Bin 0 -> 114 bytes .../data/installerbaserepository/Updates.xml | 13 ++++++++ .../tst_extractarchiveoperationtest.cpp | 33 +++++++++++++++++++++ 8 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0content.7z create mode 100644 tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0installerbase.7z create mode 100644 tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/Updates.xml diff --git a/src/libs/installer/extractarchiveoperation.cpp b/src/libs/installer/extractarchiveoperation.cpp index 986b9d8c8..162bd1609 100644 --- a/src/libs/installer/extractarchiveoperation.cpp +++ b/src/libs/installer/extractarchiveoperation.cpp @@ -178,9 +178,13 @@ bool ExtractArchiveOperation::performOperation() QString installDir = targetDir; // If we have package manager in use (normal installer run) then use // TargetDir for saving filenames, otherwise those would be saved to - // extracted folder. - if (packageManager()) - installDir = packageManager()->value(scTargetDir); + // extracted folder. Also initialize installerbasebinary which we use later + // to check if the extracted file in question is the maintenancetool itself. + QString installerBaseBinary; + if (PackageManagerCore *core = packageManager()) { + installDir = core->value(scTargetDir); + installerBaseBinary = core->toNativeSeparators(core->replaceVariables(core->installerBaseBinary())); + } const QString resourcesPath = installDir + QLatin1Char('/') + QLatin1String("installerResources"); QString fileDirectory = resourcesPath + QLatin1Char('/') + archivePath.section(QLatin1Char('/'), 1, 1, @@ -202,6 +206,13 @@ bool ExtractArchiveOperation::performOperation() setDefaultFilePermissions(file.fileName(), DefaultFilePermissions::NonExecutable); QDataStream out (&file); for (int i = 0; i < files.count(); ++i) { + if (!installerBaseBinary.isEmpty() && files[i].startsWith(installerBaseBinary)) { + // Do not write installerbase binary filename to extracted files. Installer binary + // is maintenance tool program, the binary is removed elsewhere + // when we do full uninstall. + files.clear(); + break; + } files[i] = replacePath(files.at(i), installDir, QLatin1String(scRelocatable)); } out << files; diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp index d0d635355..0788387a2 100644 --- a/src/libs/installer/packagemanagercore.cpp +++ b/src/libs/installer/packagemanagercore.cpp @@ -3492,6 +3492,17 @@ void PackageManagerCore::setInstallerBaseBinary(const QString &path) d->m_installerBaseBinaryUnreplaced = path; } +/*! + Returns the value of \c installerbase binary which is used when writing + the maintenance tool. Value can be empty. + + \sa setInstallerBaseBinary() +*/ +QString PackageManagerCore::installerBaseBinary() const +{ + return d->m_installerBaseBinaryUnreplaced; +} + /*! Sets the \c installerbase binary located at \a path to use when writing the offline installer. Setting this makes it possible to run the offline generator diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h index cd1bbf306..911c4b480 100644 --- a/src/libs/installer/packagemanagercore.h +++ b/src/libs/installer/packagemanagercore.h @@ -166,6 +166,7 @@ public: Q_INVOKABLE static QString findPath(const QString &name, const QStringList &paths = QStringList()); Q_INVOKABLE void setInstallerBaseBinary(const QString &path); + QString installerBaseBinary() const; void setOfflineBaseBinary(const QString &path); void addResourcesForOfflineGeneration(const QString &rcPath); diff --git a/tests/auto/installer/extractarchiveoperationtest/data.qrc b/tests/auto/installer/extractarchiveoperationtest/data.qrc index a8cc1a892..87f648568 100644 --- a/tests/auto/installer/extractarchiveoperationtest/data.qrc +++ b/tests/auto/installer/extractarchiveoperationtest/data.qrc @@ -11,5 +11,8 @@ data/xmloperationrepository/A/1.0.0content4.zip data/xmloperationrepository/A/1.0.0anothercontent.7z data/xmloperationrepository/A/1.0.0default.7z + data/installerbaserepository/Updates.xml + data/installerbaserepository/A/1.0.0content.7z + data/installerbaserepository/A/1.0.0installerbase.7z diff --git a/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0content.7z b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0content.7z new file mode 100644 index 000000000..585f58296 Binary files /dev/null and b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0content.7z differ diff --git a/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0installerbase.7z b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0installerbase.7z new file mode 100644 index 000000000..c3b6aec9c Binary files /dev/null and b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0installerbase.7z differ diff --git a/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/Updates.xml b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/Updates.xml new file mode 100644 index 000000000..887300c97 --- /dev/null +++ b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/Updates.xml @@ -0,0 +1,13 @@ + + {AnyApplication} + 1.0.0 + + A + InstallerBase + Example component InstallerBase + 1.0.0 + 2015-01-01 + true + installerbase.7z,content.7z + + diff --git a/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp b/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp index 89492bd94..a8a65e983 100644 --- a/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp +++ b/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp @@ -177,6 +177,39 @@ private slots: QVERIFY(dir.removeRecursively()); } + void testInstallerBaseBinaryExtraction() + { + m_testDirectory = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(m_testDirectory)); + QVERIFY(QDir(m_testDirectory).exists()); + + QScopedPointer core(PackageManager::getPackageManagerWithInit + (m_testDirectory, ":///data/installerbaserepository")); + core->setInstallerBaseBinary(m_testDirectory + QDir::separator() + "testInstallerBase.txt"); + core->installDefaultComponentsSilently(); + + QFile contentResourceFile(m_testDirectory + QDir::separator() + "installerResources" + QDir::separator() + "A" + QDir::separator() + "1.0.0content.txt"); + QVERIFY2(contentResourceFile.open(QIODevice::ReadOnly | QIODevice::Text), "Could not open content resource file for reading."); + QTextStream fileStream(&contentResourceFile); + QString line = fileStream.readLine(); + QVERIFY2(!line.isEmpty(), "Content not written to resource file."); + contentResourceFile.close(); + + QFile installerBaseResourceFile(m_testDirectory + QDir::separator() + "installerResources" + QDir::separator() + "A" + QDir::separator() + "1.0.0installerbase.txt"); + QVERIFY2(installerBaseResourceFile.open(QIODevice::ReadOnly | QIODevice::Text), "Could not open installerbase resource file for reading."); + QTextStream fileStream2(&installerBaseResourceFile); + line = installerBaseResourceFile.readLine(); + QVERIFY2(line.isEmpty(), "Installerbase falsly written to resource file."); + installerBaseResourceFile.close(); + + core->setPackageManager(); + core->commitSessionOperations(); + + QCOMPARE(PackageManagerCore::Success, core->uninstallComponentsSilently(QStringList() << "A")); + QDir dir(m_testDirectory); + QVERIFY(dir.removeRecursively()); + } + private: QString m_testDirectory; }; -- cgit v1.2.3