summaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2022-03-22 12:01:55 +0200
committerKatja Marttila <katja.marttila@qt.io>2022-03-22 12:03:30 +0200
commit449afefe542d3411de4bdacd068c1116ec10779c (patch)
tree08567594bf3be3c1dfd79526cc3c47ae9f44e245 /src/libs
parent6ec6ac70d98195bb41a5ed60e47984bc640066fc (diff)
parentcaee7332c4a049508c91fe23e3e3bed062a4815d (diff)
Merge remote-tracking branch 'origin/4.3' into master
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/installer/fileutils.cpp32
-rw-r--r--src/libs/installer/packagemanagercore.cpp101
-rw-r--r--src/libs/installer/packagemanagercore.h3
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp32
-rw-r--r--src/libs/installer/packagemanagercore_p.h4
-rw-r--r--src/libs/installer/uninstallercalculator.cpp9
-rw-r--r--src/libs/installer/uninstallercalculator.h2
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;