diff options
author | Katja Marttila <katja.marttila@qt.io> | 2022-03-22 12:01:55 +0200 |
---|---|---|
committer | Katja Marttila <katja.marttila@qt.io> | 2022-03-22 12:03:30 +0200 |
commit | 449afefe542d3411de4bdacd068c1116ec10779c (patch) | |
tree | 08567594bf3be3c1dfd79526cc3c47ae9f44e245 /src/libs | |
parent | 6ec6ac70d98195bb41a5ed60e47984bc640066fc (diff) | |
parent | caee7332c4a049508c91fe23e3e3bed062a4815d (diff) |
Merge remote-tracking branch 'origin/4.3' into master
Change-Id: I449320b3af2c561a0b4a4cb689d072533d8fdb8f
Diffstat (limited to 'src/libs')
-rw-r--r-- | src/libs/installer/fileutils.cpp | 32 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore.cpp | 101 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore.h | 3 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore_p.cpp | 32 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore_p.h | 4 | ||||
-rw-r--r-- | src/libs/installer/uninstallercalculator.cpp | 9 | ||||
-rw-r--r-- | src/libs/installer/uninstallercalculator.h | 2 |
7 files changed, 125 insertions, 58 deletions
diff --git a/src/libs/installer/fileutils.cpp b/src/libs/installer/fileutils.cpp index b46883c5a..5a89073fc 100644 --- a/src/libs/installer/fileutils.cpp +++ b/src/libs/installer/fileutils.cpp @@ -454,21 +454,31 @@ void QInstaller::mkpath(const QString &path) */ QString QInstaller::generateTemporaryFileName(const QString &templ) { - static const QLatin1String staticPart("%1.tmp.XXXXXX"); - - QTemporaryFile f; - if (!templ.isEmpty()) - f.setFileTemplate(QString(staticPart).arg(templ)); - - if (!f.open()) { - if (!templ.isEmpty()) { - throw Error(QCoreApplication::translate("QInstaller", - "Cannot open temporary file for template %1: %2").arg(templ, f.errorString())); - } else { + if (templ.isEmpty()) { + QTemporaryFile f; + if (!f.open()) { throw Error(QCoreApplication::translate("QInstaller", "Cannot open temporary file: %1").arg(f.errorString())); } + return f.fileName(); + } + + static const QString characters = QLatin1String("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"); + QString suffix; + for (int i = 0; i < 5; ++i) + suffix += characters[QRandomGenerator::global()->generate() % characters.length()]; + + const QString tmp = QLatin1String("%1.tmp.%2.%3"); + int count = 1; + while (QFile::exists(tmp.arg(templ, suffix).arg(count))) + ++count; + + QFile f(tmp.arg(templ, suffix).arg(count)); + if (!f.open(QIODevice::WriteOnly)) { + throw Error(QCoreApplication::translate("QInstaller", + "Cannot open temporary file for template %1: %2").arg(templ, f.errorString())); } + f.remove(); return f.fileName(); } diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp index d2c732ddb..918b01ad6 100644 --- a/src/libs/installer/packagemanagercore.cpp +++ b/src/libs/installer/packagemanagercore.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. @@ -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(); @@ -2129,16 +2123,13 @@ bool PackageManagerCore::calculateComponents(QString *displayString) return false; } - // In case of updater mode we don't uninstall components. - if (!isUpdater()) { - QList<Component*> componentsToRemove = componentsToUninstall(); - if (!componentsToRemove.isEmpty()) { - htmlOutput.append(QString::fromLatin1("<h3>%1</h3><ul>").arg(tr("Components about to " - "be removed."))); - foreach (Component *component, componentsToRemove) - htmlOutput.append(QString::fromLatin1("<li> %1 </li>").arg(component->name())); - htmlOutput.append(QLatin1String("</ul>")); - } + QList<Component*> componentsToRemove = componentsToUninstall(); + if (!componentsToRemove.isEmpty()) { + htmlOutput.append(QString::fromLatin1("<h3>%1</h3><ul>").arg(tr("Components about to " + "be removed."))); + foreach (Component *component, componentsToRemove) + htmlOutput.append(QString::fromLatin1("<li> %1 </li>").arg(component->name())); + htmlOutput.append(QLatin1String("</ul>")); } foreach (Component *component, orderedComponentsToInstall()) { @@ -2168,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; @@ -2251,6 +2230,47 @@ QList<Component*> PackageManagerCore::dependees(const Component *_component) con } /*! + Returns a list of components that depend on \a component. The list can be + empty. Dependendants are calculated from components which are about to be updated, + if no update is requested then the dependant is calculated from installed packages. + + \note Automatic dependencies are not resolved. +*/ +QList<Component*> PackageManagerCore::installDependants(const Component *component) const +{ + if (!component) + return QList<Component *>(); + + const QList<QInstaller::Component *> availableComponents = components(ComponentType::All); + if (availableComponents.isEmpty()) + return QList<Component *>(); + + QList<Component *> dependants; + QString name; + QString version; + foreach (Component *availableComponent, availableComponents) { + if (isUpdater() && availableComponent->updateRequested()) { + const QStringList &dependencies = availableComponent->dependencies(); + foreach (const QString &dependency, dependencies) { + parseNameAndVersion(dependency, &name, &version); + if (componentMatches(component, name, version)) { + dependants.append(availableComponent); + } + } + } else { + KDUpdater::LocalPackage localPackage = d->m_localPackageHub->packageInfo(availableComponent->name()); + foreach (const QString &dependency, localPackage.dependencies) { + parseNameAndVersion(dependency, &name, &version); + if (componentMatches(component, name, version)) { + dependants.append(availableComponent); + } + } + } + } + return dependants; +} + +/*! Returns the default component model. */ ComponentModel *PackageManagerCore::defaultComponentModel() const @@ -3835,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 @@ -3844,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.h b/src/libs/installer/packagemanagercore.h index cf1916c48..012c57d58 100644 --- a/src/libs/installer/packagemanagercore.h +++ b/src/libs/installer/packagemanagercore.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. @@ -242,6 +242,7 @@ public: QString installReason(Component *component) const; QList<Component*> dependees(const Component *component) const; + QList<Component*> installDependants(const Component *component) const; ComponentModel *defaultComponentModel() const; ComponentModel *updaterComponentModel() const; 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/src/libs/installer/uninstallercalculator.cpp b/src/libs/installer/uninstallercalculator.cpp index fc5620936..7d5ce9e2a 100644 --- a/src/libs/installer/uninstallercalculator.cpp +++ b/src/libs/installer/uninstallercalculator.cpp @@ -127,10 +127,10 @@ void UninstallerCalculator::appendComponentsToUninstall(const QList<Component*> if (!autoDependOnList.isEmpty()) appendComponentsToUninstall(autoDependOnList); else - continueAppendComponentsToUninstall(); + appendVirtualComponentsToUninstall(); } -void UninstallerCalculator::continueAppendComponentsToUninstall() +void UninstallerCalculator::appendVirtualComponentsToUninstall() { QList<Component*> unneededVirtualList; // Check for virtual components without dependees @@ -141,8 +141,9 @@ void UninstallerCalculator::continueAppendComponentsToUninstall() continue; bool required = false; - for (Component *dependee : m_core->dependees(component)) { - if (dependee->isInstalled() && !m_componentsToUninstall.contains(dependee)) { + // Check if installed or about to be updated -packages are dependant on the package + for (Component *dependant : m_core->installDependants(component)) { + if (dependant->isInstalled() && !m_componentsToUninstall.contains(dependant)) { required = true; break; } diff --git a/src/libs/installer/uninstallercalculator.h b/src/libs/installer/uninstallercalculator.h index 4d1f8816a..fb7035d4e 100644 --- a/src/libs/installer/uninstallercalculator.h +++ b/src/libs/installer/uninstallercalculator.h @@ -52,7 +52,7 @@ public: private: void appendComponentToUninstall(Component *component); - void continueAppendComponentsToUninstall(); + void appendVirtualComponentsToUninstall(); QList<Component *> m_installedComponents; QSet<Component *> m_componentsToUninstall; |