summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2022-12-13 09:04:55 +0200
committerKatja Marttila <katja.marttila@qt.io>2022-12-13 09:08:15 +0200
commitc02d33db5723b7605dc953de078c26d54f284d5e (patch)
tree2aa841ad0ac416bf9baed474e90c75abd6fc67f9
parent662110e1594788ddc54ec379d61776e1bdd82670 (diff)
parentb7929635dcdbd01135c04e0a7ffc8fa29d647d4d (diff)
Merge remote-tracking branch 'origin/4.5' into master
-rw-r--r--Changelog16
-rw-r--r--coin/instructions/qmake_module_build.yaml2
-rw-r--r--doc/installerfw.qdoc7
-rw-r--r--src/libs/installer/component.cpp10
-rw-r--r--src/libs/installer/componentmodel.cpp38
-rw-r--r--src/libs/installer/componentmodel.h7
-rw-r--r--src/libs/installer/componentselectionpage_p.cpp46
-rw-r--r--src/libs/installer/componentselectionpage_p.h10
-rw-r--r--src/libs/installer/elevatedexecuteoperation.cpp39
-rw-r--r--src/libs/installer/extractarchiveoperation.cpp17
-rw-r--r--src/libs/installer/fileutils.cpp4
-rw-r--r--src/libs/installer/genericdatacache.cpp6
-rw-r--r--src/libs/installer/installercalculator.cpp201
-rw-r--r--src/libs/installer/installercalculator.h27
-rw-r--r--src/libs/installer/metadatajob.cpp1
-rw-r--r--src/libs/installer/metadatajob_p.h10
-rw-r--r--src/libs/installer/packagemanagercore.cpp77
-rw-r--r--src/libs/installer/packagemanagercore.h2
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp29
-rw-r--r--src/libs/installer/packagemanagercore_p.h1
-rw-r--r--src/libs/installer/packagemanagergui.cpp15
-rw-r--r--src/libs/installer/packagemanagergui.h2
-rw-r--r--src/libs/installer/qinstallerglobal.cpp8
-rw-r--r--src/libs/installer/settingsoperation.cpp27
-rw-r--r--src/libs/installer/uninstallercalculator.cpp86
-rw-r--r--src/libs/installer/uninstallercalculator.h14
-rw-r--r--src/libs/kdtools/localpackagehub.cpp1
-rw-r--r--src/libs/kdtools/updateoperation.cpp33
-rw-r--r--src/libs/kdtools/updateoperation.h1
-rw-r--r--src/sdk/tabcontroller.cpp2
-rw-r--r--tests/auto/installer/commandlineupdate/data/installPackagesRepository/Updates.xml16
-rw-r--r--tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator.enterprise.plugins/1.0.0content.7zbin0 -> 98 bytes
-rw-r--r--tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator/1.0.0content.7zbin0 -> 98 bytes
-rw-r--r--tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/Updates.xml32
-rw-r--r--tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator/2.0.0content.7zbin0 -> 106 bytes
-rw-r--r--tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui.enterprise.plugins/2.0.0content.7zbin0 -> 106 bytes
-rw-r--r--tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui/2.0.0content.7zbin0 -> 90 bytes
-rw-r--r--tests/auto/installer/commandlineupdate/settings.qrc6
-rw-r--r--tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp34
-rw-r--r--tests/auto/installer/extractarchiveoperationtest/data.qrc3
-rw-r--r--tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0content.7zbin0 -> 98 bytes
-rw-r--r--tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0installerbase.7zbin0 -> 114 bytes
-rw-r--r--tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/Updates.xml13
-rw-r--r--tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp33
-rw-r--r--tests/auto/installer/settingsoperation/data/repository/B/1.0.0meta.7zbin0 -> 967 bytes
-rw-r--r--tests/auto/installer/settingsoperation/data/repository/C/1.0.0meta.7zbin0 -> 958 bytes
-rw-r--r--tests/auto/installer/settingsoperation/data/repository/Updates.xml20
-rw-r--r--tests/auto/installer/settingsoperation/settings.qrc2
-rw-r--r--tests/auto/installer/settingsoperation/tst_settingsoperation.cpp66
-rw-r--r--tests/auto/installer/solver/tst_solver.cpp6
50 files changed, 561 insertions, 409 deletions
diff --git a/Changelog b/Changelog
index 78bd21d99..f6aa2711d 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,13 @@
+4.5.1
+- Make Settings operation to support _OLD and placeholders (QTIFW-2882)
+- ExtractOp: fix leftover empty directories when 'targetDir' arg is used (QTIFW-2764)
+- Fix errors occurring in full uninstall on macOS (QTIFW-2875)
+- Fix updater view behavior for non-checkable components (QTIFW-836)
+- Execute operation: fix overwritten error string for crashed processes (QTIFW-2875)
+- MetadataJob: fix removing compressed repositories after extracting (QTIFW-2876)
+- Fix replaced removal on update (QTIFW-2887)
+- Fix user set binary marker not having any effect on maintenance tool (QTIFW-2884)
+
4.5.0
- Fix required virtual components still uninstalled in some occasions
- Update translations (QTIFW-2814)
@@ -11,6 +21,12 @@
- Fix installer stalling when there's only one CPU core (QTIFW-2786)
- Adjust the 'ready to install' message to avoid repeating the app name (SQUISH-9672)
- CLI: add support for hiding values of printed options (QTIFW-2756)
+- Replace .vbs hack to update maintenance tool binary on Windows (QTIFW-2625)
+- Disable package manager and updater for offline maintenance tool (QTIFW-2627)
+- Display progress for loading component install scripts (QTIFW-2701)
+- Fix separators for localInstallerBinaryUsed() (QTIFW-2700)
+- Allow searching components also in the updater view (QTIFW-2667)
+- Add list of components to uninstall to installation log (QTIFW-2666)
4.4.2
- Fix uninstallation of needed virtual components
diff --git a/coin/instructions/qmake_module_build.yaml b/coin/instructions/qmake_module_build.yaml
index 023927567..4a475b600 100644
--- a/coin/instructions/qmake_module_build.yaml
+++ b/coin/instructions/qmake_module_build.yaml
@@ -9,7 +9,7 @@ instructions:
maxTimeInSeconds: 600
maxTimeBetweenOutput: 600
project: qtsdk/qtsdk
- ref: master
+ ref: 8d9c6bb366b0f3c1e46c045a6453776ae98a8051
directory: qtsdk/qtsdk
userMessageOnFailure: "Could not install qtsdk/qtsdk source archive. Please investigate why."
diff --git a/doc/installerfw.qdoc b/doc/installerfw.qdoc
index a45ba0f9d..6e403dc6b 100644
--- a/doc/installerfw.qdoc
+++ b/doc/installerfw.qdoc
@@ -992,7 +992,8 @@
\row
\li ForcedInstallation
\li Determines that the package must always be installed. End users
- cannot deselect it in the installer.
+ cannot deselect it in the installer. When updating components, the
+ component can still be deselected from an update.
\row
\li ForcedUpdate
\li Marks the package as \c ForcedUpdate to force a restart of the
@@ -1018,7 +1019,9 @@
\row
\li Checkable
\li Set to \c false if you want to hide the checkbox for an item. This is useful
- when only a few subcomponents should be selected instead of all. Optional.
+ when only a few subcomponents should be selected instead of all. When updating
+ components, the checkbox is still visible to allow toggling the component for
+ update. Optional.
\row
\li ExpandedByDefault
\li Set to \c true if you want this item to be expanded by default. Optional.
diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp
index 2ce948e7e..8e32ad347 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -89,6 +89,8 @@ static const QLatin1String scUnstable("Unstable");
Component has dependencies to missing components.
\value InvalidTreeName
Component has an invalid tree name.
+ \value DescendantOfUnstable
+ Component is descendant of an unstable component.
*/
/*!
@@ -461,12 +463,14 @@ void Component::setValue(const QString &key, const QString &value)
if (key == scName)
d->m_componentName = normalizedValue;
- if (key == scCheckable)
- this->setCheckable(normalizedValue.toLower() == scTrue);
+ if (key == scCheckable) // Non-checkable components can still be toggled in updater
+ this->setCheckable(normalizedValue.toLower() == scTrue || d->m_core->isUpdater());
if (key == scExpandedByDefault)
this->setExpandedByDefault(normalizedValue.toLower() == scTrue);
if (key == scForcedInstallation) {
- if (value == scTrue && !PackageManagerCore::noForceInstallation()) {
+ if (value == scTrue && !d->m_core->isUpdater() && !PackageManagerCore::noForceInstallation()) {
+ // Forced installation components can still be toggled in updater or when
+ // core is set to ignore forced installations.
setCheckable(false);
setCheckState(Qt::Checked);
}
diff --git a/src/libs/installer/componentmodel.cpp b/src/libs/installer/componentmodel.cpp
index 8407e5f2d..873175937 100644
--- a/src/libs/installer/componentmodel.cpp
+++ b/src/libs/installer/componentmodel.cpp
@@ -60,14 +60,7 @@ namespace QInstaller {
*/
/*!
- \fn void QInstaller::ComponentModel::componentsCheckStateChanged(const QList<QModelIndex> &indexes)
-
- This signal is emitted whenever the checked state of components are changed. The \a indexes value
- indicates the QModelIndexes representation of the components as seen from the model.
-*/
-
-/*!
- \fn void QInstaller::ComponentModel::modelCheckStateChanged(QInstaller::ComponentModel::ModelState state)
+ \fn void QInstaller::ComponentModel::checkStateChanged(QInstaller::ComponentModel::ModelState state)
This signal is emitted whenever the checked state of a model is changed after all state
calculations have taken place. The \a state is a combination of \c ModelStateFlag values
@@ -240,7 +233,6 @@ QVariant ComponentModel::data(const QModelIndex &index, int role) const
/*!
Sets the \a role data for the item at \a index to \a value. Returns true if successful;
otherwise returns false. The dataChanged() signal is emitted if the data was successfully set.
- The componentsCheckStateChanged() signal is emitted in addition if the checked state of the item is set.
*/
bool ComponentModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
@@ -262,13 +254,10 @@ bool ComponentModel::setData(const QModelIndex &index, const QVariant &value, in
const Qt::CheckState oldValue = component->checkState();
newValue = (oldValue == Qt::Checked) ? Qt::Unchecked : Qt::Checked;
}
- const QList<QModelIndex> changed = updateCheckedState(nodes << component, newValue);
- foreach (const QModelIndex &changedIndex, changed) {
+ const QSet<QModelIndex> changed = updateCheckedState(nodes << component, newValue);
+ foreach (const QModelIndex &changedIndex, changed)
emit dataChanged(changedIndex, changedIndex);
- }
- updateModelState();
- if (changed.count() > 0)
- emit componentsCheckStateChanged(changed);
+ updateAndEmitModelState(); // update the internal state
} else {
component->setData(value, role);
emit dataChanged(index, index);
@@ -448,8 +437,7 @@ void ComponentModel::setCheckedState(QInstaller::ComponentModel::ModelStateFlag
default:
break;
}
- updateModelState();
- emit modelCheckStateChanged(m_modelState);
+ updateAndEmitModelState(); // update the internal state
}
@@ -487,11 +475,10 @@ void ComponentModel::postModelReset()
}
m_currentCheckedState = m_initialCheckedState;
- updateModelState(); // update the internal state
- emit modelCheckStateChanged(m_modelState);
+ updateAndEmitModelState(); // update the internal state
}
-void ComponentModel::updateModelState()
+void ComponentModel::updateAndEmitModelState()
{
if (m_rootComponentList.isEmpty()) {
m_modelState = ComponentModel::Empty;
@@ -510,6 +497,8 @@ void ComponentModel::updateModelState()
m_modelState |= ComponentModel::AllChecked;
m_modelState &= ~ComponentModel::PartiallyChecked;
}
+
+ emit checkStateChanged(m_modelState);
}
void ComponentModel::collectComponents(Component *const component, const QModelIndex &parent) const
@@ -553,7 +542,7 @@ static Qt::CheckState verifyPartiallyChecked(Component *component)
} // namespace ComponentModelPrivate
-QList<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &components, const Qt::CheckState state)
+QSet<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &components, const Qt::CheckState state)
{
// get all parent nodes for the components we're going to update
QMultiMap<QString, Component *> sortedNodesMap;
@@ -564,7 +553,7 @@ QList<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &compon
}
}
- QList<QModelIndex> changed;
+ QSet<QModelIndex> changed;
const ComponentList sortedNodes = sortedNodesMap.values();
// we can start in descending order to check node and tri-state nodes properly
for (int i = sortedNodes.count(); i > 0; i--) {
@@ -586,10 +575,7 @@ QList<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &compon
continue;
node->setCheckState(newState);
- QModelIndex index = indexFromComponentName(node->treeName());
- //Prepend to the list so that install order is correct (parent first)
- if (!changed.contains(index))
- changed.prepend(indexFromComponentName(node->treeName()));
+ changed.insert(indexFromComponentName(node->treeName()));
m_currentCheckedState[Qt::Checked].remove(node);
m_currentCheckedState[Qt::Unchecked].remove(node);
diff --git a/src/libs/installer/componentmodel.h b/src/libs/installer/componentmodel.h
index 001753055..b6b489888 100644
--- a/src/libs/installer/componentmodel.h
+++ b/src/libs/installer/componentmodel.h
@@ -91,17 +91,16 @@ public Q_SLOTS:
void setCheckedState(QInstaller::ComponentModel::ModelStateFlag state);
Q_SIGNALS:
- void componentsCheckStateChanged(const QList<QModelIndex> &indexes);
- void modelCheckStateChanged(QInstaller::ComponentModel::ModelState state);
+ void checkStateChanged(QInstaller::ComponentModel::ModelState state);
private Q_SLOTS:
void onVirtualStateChanged();
private:
void postModelReset();
- void updateModelState();
+ void updateAndEmitModelState();
void collectComponents(Component *const component, const QModelIndex &parent) const;
- QList<QModelIndex> updateCheckedState(const ComponentSet &components, const Qt::CheckState state);
+ QSet<QModelIndex> updateCheckedState(const ComponentSet &components, const Qt::CheckState state);
private:
PackageManagerCore *m_core;
diff --git a/src/libs/installer/componentselectionpage_p.cpp b/src/libs/installer/componentselectionpage_p.cpp
index 42b9c2a86..83bcaae14 100644
--- a/src/libs/installer/componentselectionpage_p.cpp
+++ b/src/libs/installer/componentselectionpage_p.cpp
@@ -44,7 +44,6 @@
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QCheckBox>
-#include <QHeaderView>
#include <QStandardPaths>
#include <QFileDialog>
#include <QStackedLayout>
@@ -73,8 +72,10 @@ ComponentSelectionPagePrivate::ComponentSelectionPagePrivate(ComponentSelectionP
, m_categoryWidget(Q_NULLPTR)
, m_categoryLayoutVisible(false)
, m_proxyModel(new ComponentSortFilterProxyModel(q))
+ , m_headerStretchLastSection(false)
{
m_treeView->setObjectName(QLatin1String("ComponentsTreeView"));
+ m_treeView->setUniformRowHeights(true);
m_proxyModel->setRecursiveFilteringEnabled(true);
m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
@@ -185,16 +186,10 @@ ComponentSelectionPagePrivate::ComponentSelectionPagePrivate(ComponentSelectionP
m_stackedLayout->addWidget(progressStackedWidget);
m_stackedLayout->setCurrentIndex(0);
- connect(m_allModel, &ComponentModel::modelCheckStateChanged,
- this, &ComponentSelectionPagePrivate::onModelStateChanged);
- connect(m_updaterModel, &ComponentModel::modelCheckStateChanged,
- this, &ComponentSelectionPagePrivate::onModelStateChanged);
-
- connect(m_allModel, &ComponentModel::componentsCheckStateChanged, this,
- [=]() { onModelStateChanged(m_allModel->checkedState());});
-
- connect(m_updaterModel, &ComponentModel::componentsCheckStateChanged, this,
- [=]() { onModelStateChanged(m_allModel->checkedState());});
+ connect(m_allModel, &ComponentModel::checkStateChanged,
+ this, &ComponentSelectionPagePrivate::onModelStateChanged);
+ connect(m_updaterModel, &ComponentModel::checkStateChanged,
+ this, &ComponentSelectionPagePrivate::onModelStateChanged);
connect(m_core, SIGNAL(metaJobProgress(int)), this, SLOT(onProgressChanged(int)));
connect(m_core, SIGNAL(metaJobInfoMessage(QString)), this, SLOT(setMessage(QString)));
@@ -374,6 +369,9 @@ void ComponentSelectionPagePrivate::expandDefault()
*/
void ComponentSelectionPagePrivate::expandSearchResults()
{
+ // Avoid resizing the sections after each expand of a node
+ storeHeaderResizeModes();
+
// Expand parents of root indexes accepted by filter
const QVector<QModelIndex> acceptedIndexes = m_proxyModel->directlyAcceptedIndexes();
for (auto proxyModelIndex : acceptedIndexes) {
@@ -389,6 +387,7 @@ void ComponentSelectionPagePrivate::expandSearchResults()
index = index.parent();
}
}
+ restoreHeaderResizeModes();
}
void ComponentSelectionPagePrivate::currentSelectedChanged(const QModelIndex &current)
@@ -588,4 +587,29 @@ void ComponentSelectionPagePrivate::setSearchPattern(const QString &text)
}
}
+/*!
+ Stores the current resize modes of the tree view header's columns, and sets
+ the new resize modes to \c QHeaderView::Fixed.
+*/
+void ComponentSelectionPagePrivate::storeHeaderResizeModes()
+{
+ m_headerStretchLastSection = m_treeView->header()->stretchLastSection();
+ for (int i = 0; i < ComponentModelHelper::LastColumn; ++i)
+ m_headerResizeModes.insert(i, m_treeView->header()->sectionResizeMode(i));
+
+ m_treeView->header()->setStretchLastSection(false);
+ m_treeView->header()->setSectionResizeMode(QHeaderView::Fixed);
+}
+
+/*!
+ Restores the resize modes of the tree view header's columns, that were
+ stored when calling \l storeHeaderResizeModes().
+*/
+void ComponentSelectionPagePrivate::restoreHeaderResizeModes()
+{
+ m_treeView->header()->setStretchLastSection(m_headerStretchLastSection);
+ for (int i = 0; i < ComponentModelHelper::LastColumn; ++i)
+ m_treeView->header()->setSectionResizeMode(i, m_headerResizeModes.value(i));
+}
+
} // namespace QInstaller
diff --git a/src/libs/installer/componentselectionpage_p.h b/src/libs/installer/componentselectionpage_p.h
index fc37ebdaa..7c2f6a38e 100644
--- a/src/libs/installer/componentselectionpage_p.h
+++ b/src/libs/installer/componentselectionpage_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.
@@ -31,6 +31,7 @@
#include <QObject>
#include <QWidget>
+#include <QHeaderView>
#include "componentmodel.h"
#include "packagemanagergui.h"
@@ -90,6 +91,10 @@ public slots:
void setSearchPattern(const QString &text);
private:
+ void storeHeaderResizeModes();
+ void restoreHeaderResizeModes();
+
+private:
ComponentSelectionPage *q;
PackageManagerCore *m_core;
QTreeView *m_treeView;
@@ -113,6 +118,9 @@ private:
QStackedLayout *m_stackedLayout;
ComponentSortFilterProxyModel *m_proxyModel;
QLineEdit *m_searchLineEdit;
+
+ bool m_headerStretchLastSection;
+ QHash<int, QHeaderView::ResizeMode> m_headerResizeModes;
};
} // namespace QInstaller
diff --git a/src/libs/installer/elevatedexecuteoperation.cpp b/src/libs/installer/elevatedexecuteoperation.cpp
index 092b0f0eb..6f2393799 100644
--- a/src/libs/installer/elevatedexecuteoperation.cpp
+++ b/src/libs/installer/elevatedexecuteoperation.cpp
@@ -221,30 +221,29 @@ int ElevatedExecuteOperation::Private::run(QStringList &arguments, const Operati
q->setValue(QLatin1String("ExitCode"), process->exitCode());
- if (process->exitStatus() == QProcessWrapper::CrashExit) {
- q->setError(UserDefinedError);
- q->setErrorString(tr("Program crashed: \"%1\"").arg(callstr));
- returnValue = Error;
- }
+ if (success) {
+ const QByteArray standardErrorOutput = process->readAllStandardError();
+ // in error case it would be useful to see something in verbose output
+ if (!standardErrorOutput.isEmpty())
+ qCWarning(QInstaller::lcInstallerInstallLog).noquote() << standardErrorOutput;
- if (!allowedExitCodes.contains(process->exitCode()) && returnValue != NeedsRerun) {
- if (!needsRerunWithReplacedVariables(arguments, type)) {
+ if (process->exitStatus() == QProcessWrapper::CrashExit) {
q->setError(UserDefinedError);
- if (customErrorMessage.isEmpty()) {
- q->setErrorString(tr("Execution failed (Unexpected exit code: %1): \"%2\"")
- .arg(QString::number(process->exitCode()), callstr));
+ q->setErrorString(tr("Program crashed: \"%1\"").arg(callstr));
+ returnValue = Error;
+ } else if (!allowedExitCodes.contains(process->exitCode()) && returnValue != NeedsRerun) {
+ if (!needsRerunWithReplacedVariables(arguments, type)) {
+ q->setError(UserDefinedError);
+ if (customErrorMessage.isEmpty()) {
+ q->setErrorString(tr("Execution failed (Unexpected exit code: %1): \"%2\"")
+ .arg(QString::number(process->exitCode()), callstr));
+ } else {
+ q->setErrorString(customErrorMessage);
+ }
+ returnValue = Error;
} else {
- q->setErrorString(customErrorMessage);
+ returnValue = NeedsRerun;
}
-
- QByteArray standardErrorOutput = process->readAllStandardError();
- // in error case it would be useful to see something in verbose output
- if (!standardErrorOutput.isEmpty())
- qCWarning(QInstaller::lcInstallerInstallLog).noquote() << standardErrorOutput;
-
- returnValue = Error;
- } else {
- returnValue = NeedsRerun;
}
}
Q_ASSERT(process);
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/fileutils.cpp b/src/libs/installer/fileutils.cpp
index 16502383c..633d283bb 100644
--- a/src/libs/installer/fileutils.cpp
+++ b/src/libs/installer/fileutils.cpp
@@ -485,7 +485,7 @@ bool QInstaller::createDirectoryWithParents(const QString &path)
return false;
QDir dir(path);
- if (dir.mkdir(path))
+ if (dir.exists() || dir.mkdir(path))
return true;
// mkdir failed, try to create the parent directory
@@ -493,7 +493,7 @@ bool QInstaller::createDirectoryWithParents(const QString &path)
return false;
// now try again
- if (dir.mkdir(path))
+ if (dir.exists() || dir.mkdir(path))
return true;
// directory may be have also been created elsewhere
diff --git a/src/libs/installer/genericdatacache.cpp b/src/libs/installer/genericdatacache.cpp
index b70cbcb0b..45f3fa3e8 100644
--- a/src/libs/installer/genericdatacache.cpp
+++ b/src/libs/installer/genericdatacache.cpp
@@ -75,7 +75,7 @@ static const QLatin1String scManifestFile("manifest.json");
*/
/*!
- \fn QInstaller::CacheableItem::isActive const
+ \fn QInstaller::CacheableItem::isActive() const
Returns \c true if this item is an actively used cache item, \c false otherwise.
This information is used as a hint for filtering obsolete entries, an active item
@@ -532,11 +532,11 @@ void GenericDataCache<T>::invalidate()
}
/*!
- \fn template <typename T> QInstaller::GenericDataCache<T>::setErrorString(const QString &error)
+ \fn template <typename T> QInstaller::GenericDataCache<T>::setErrorString(const QString &error) const
Sets the current error string to \a error and prints it as a warning to the console.
*/
-template<typename T>
+template <typename T>
void GenericDataCache<T>::setErrorString(const QString &error) const
{
m_error = error;
diff --git a/src/libs/installer/installercalculator.cpp b/src/libs/installer/installercalculator.cpp
index f285158f8..77989e3f8 100644
--- a/src/libs/installer/installercalculator.cpp
+++ b/src/libs/installer/installercalculator.cpp
@@ -49,7 +49,8 @@ InstallerCalculator::InstallerCalculator(PackageManagerCore *core, const AutoDep
InstallerCalculator::InstallReasonType InstallerCalculator::installReasonType(const Component *c) const
{
- return m_toInstallComponentIdReasonHash.value(c->name()).first;
+ return m_toInstallComponentIdReasonHash.value(c->name(),
+ qMakePair(InstallerCalculator::Selected, QString())).first;
}
QString InstallerCalculator::installReason(const Component *component) const
@@ -82,103 +83,77 @@ QString InstallerCalculator::componentsToInstallError() const
return m_componentsToInstallError;
}
-bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &components, bool modelReset, const bool revertFromInstall)
+bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &components)
{
if (components.isEmpty())
return true;
QList<Component*> notAppendedComponents; // for example components with unresolved dependencies
- foreach (Component *component, components) {
+ for (Component *component : qAsConst(components)){
if (!component)
continue;
- // When model has been reseted, there should not be components with the same name
if (m_toInstallComponentIds.contains(component->name())) {
- if (modelReset) {
- const QString errorMessage = recursionError(component);
- qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage;
- m_componentsToInstallError.append(errorMessage);
- Q_ASSERT_X(!m_toInstallComponentIds.contains(component->name()), Q_FUNC_INFO,
- qPrintable(errorMessage));
- return false;
- }
- if (!revertFromInstall && !modelReset) {
- // We can end up here if component is already added as dependency and
- // user explicitly selects it to install. Increase the references to
- // know when the component should be removed from install
- const QStringList dependenciesList = component->currentDependencies();
- for (const QString &dependencyComponentName : dependenciesList)
- calculateComponentDependencyReferences(dependencyComponentName, component);
- continue;
- }
+ const QString errorMessage = recursionError(component);
+ qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage;
+ m_componentsToInstallError.append(errorMessage);
+ Q_ASSERT_X(!m_toInstallComponentIds.contains(component->name()), Q_FUNC_INFO,
+ qPrintable(errorMessage));
+ return false;
}
if (component->currentDependencies().isEmpty())
- realAppendToInstallComponents(component, QString(), revertFromInstall);
+ realAppendToInstallComponents(component);
else
notAppendedComponents.append(component);
}
- foreach (Component *component, notAppendedComponents) {
- if (!appendComponentToInstall(component, QString(), revertFromInstall))
+ for (Component *component : qAsConst(notAppendedComponents)) {
+ if (!appendComponentToInstall(component))
return false;
}
// All regular dependencies are resolved. Now we are looking for auto depend on components.
- QSet<Component *> foundAutoDependOnList = autodependencyComponents(revertFromInstall);
+ QSet<Component *> foundAutoDependOnList = autodependencyComponents();
if (!foundAutoDependOnList.isEmpty())
- return appendComponentsToInstall(foundAutoDependOnList.values(), modelReset, revertFromInstall);
-
+ return appendComponentsToInstall(foundAutoDependOnList.values());
return true;
}
-bool InstallerCalculator::removeComponentsFromInstall(const QList<Component *> &components)
-{
- return appendComponentsToInstall(components, false, true);
-}
-
QString InstallerCalculator::installReasonReferencedComponent(const Component *component) const
{
- const QString componentName = component->name();
- if (m_referenceCount.contains(componentName))
- return m_referenceCount.value(componentName).first();
- return m_toInstallComponentIdReasonHash.value(componentName,
- qMakePair(InstallerCalculator::Selected, QString())).second;
+ return m_toInstallComponentIdReasonHash.value(component->name(),
+ qMakePair(InstallerCalculator::Selected, QString())).second;
}
-void InstallerCalculator::insertInstallReason(const Component *component,
- const InstallReasonType installReason, const QString &referencedComponentName, const bool revertFromInstall)
+void InstallerCalculator::insertInstallReason(Component *component,
+ InstallReasonType installReason, const QString &referencedComponentName)
{
- if (revertFromInstall && m_toInstallComponentIdReasonHash.contains(component->name())) {
- m_toInstallComponentIdReasonHash.remove(component->name());
- } else if (!m_toInstallComponentIdReasonHash.contains(component->name())) {
- m_toInstallComponentIdReasonHash.insert(component->name(),
- qMakePair(installReason, referencedComponentName));
- }
+ // keep the first reason
+ if (m_toInstallComponentIdReasonHash.contains(component->name()))
+ return;
+ m_toInstallComponentIdReasonHash.insert(component->name(),
+ qMakePair(installReason, referencedComponentName));
}
-void InstallerCalculator::realAppendToInstallComponents(Component *component, const QString &version, const bool revertFromInstall)
+void InstallerCalculator::realAppendToInstallComponents(Component *component, const QString &version)
{
if (!m_componentsForAutodepencencyCheck.contains(component))
m_componentsForAutodepencencyCheck.append(component);
- if (revertFromInstall) {
- if (m_toInstallComponentIds.contains(component->name())) {
- // Component is no longer added as dependency and is not explicitly selected for install by user
- if (m_referenceCount.value(component->name()).isEmpty() && !component->isSelected()) {
- m_toInstallComponentIds.remove(component->name());
- m_orderedComponentsToInstall.removeAll(component);
- }
- }
- } else {
- if (!component->isInstalled(version)
- || (m_core->isUpdater() && component->isUpdateAvailable())) {
- m_toInstallComponentIds.insert(component->name());
- m_orderedComponentsToInstall.append(component);
- }
+
+ if (!component->isInstalled(version) || (m_core->isUpdater() && component->isUpdateAvailable())) {
+ m_orderedComponentsToInstall.append(component);
+ m_toInstallComponentIds.insert(component->name());
}
}
-bool InstallerCalculator::appendComponentToInstall(Component *component, const QString &version, bool revertFromInstall)
+QString InstallerCalculator::recursionError(Component *component) const
+{
+ return QCoreApplication::translate("InstallerCalculator", "Recursion detected, component \"%1\" "
+ "already added with reason: \"%2\"").arg(component->name(), installReason(component));
+}
+
+bool InstallerCalculator::appendComponentToInstall(Component *component, const QString &version)
{
const QStringList dependenciesList = component->currentDependencies();
QString requiredDependencyVersion = version;
@@ -199,8 +174,6 @@ bool InstallerCalculator::appendComponentToInstall(Component *component, const Q
return false;
}
}
- if (revertFromInstall && dependencyComponent->forcedInstallation())
- continue;
//Check if component requires higher version than what might be already installed
bool isUpdateRequired = false;
QString requiredName;
@@ -221,72 +194,39 @@ bool InstallerCalculator::appendComponentToInstall(Component *component, const Q
requiredDependencyVersion = requiredVersion;
}
}
-
- // Component can be requested for install by several component (as a dependency).
- // Keep the reference count to a dependency component, so we know when component
- // needs to be removed from install. Do not increase the reference count when
- // the dependency is also autodependency as the component is removed anyway only
- // when there are no references to the dependency.
- if (revertFromInstall) {
- if (m_toInstallComponentIds.contains(dependencyComponentName)
- && m_referenceCount.contains(dependencyComponentName)) {
- if (!component->autoDependencies().contains(dependencyComponentName)) {
- QStringList &value = m_referenceCount[dependencyComponentName];
- if (value.contains(component->name())) {
- value.removeOne(component->name());
- if (value.isEmpty())
- m_referenceCount.remove(dependencyComponentName);
- }
- }
- }
- insertInstallReason(dependencyComponent, InstallerCalculator::Dependent,
- component->name(), true);
- if (!appendComponentToInstall(dependencyComponent, requiredDependencyVersion, revertFromInstall))
+ //Check dependencies only if
+ //- Dependency is not installed or update requested, nor newer version of dependency component required
+ //- And dependency component is not already added for install
+ //- And component is not already added for install, then dependencies are already resolved
+ if (((!dependencyComponent->isInstalled() || dependencyComponent->updateRequested())
+ || isUpdateRequired) && (!m_toInstallComponentIds.contains(dependencyComponent->name())
+ && !m_toInstallComponentIds.contains(component->name()))) {
+ if (m_visitedComponents.value(component).contains(dependencyComponent)) {
+ const QString errorMessage = recursionError(component);
+ qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage;
+ m_componentsToInstallError = errorMessage;
+ Q_ASSERT_X(!m_visitedComponents.value(component).contains(dependencyComponent),
+ Q_FUNC_INFO, qPrintable(errorMessage));
return false;
- m_visitedComponents.remove(component);
- } else {
- //Check dependencies only if
- //- Dependency is not installed or update requested, nor newer version of dependency component required
- //- And dependency component is not already added for install
- //- And component is not already added for install, then dependencies are already resolved
- if (((!dependencyComponent->isInstalled() || dependencyComponent->updateRequested())
- || isUpdateRequired) && (!m_toInstallComponentIds.contains(dependencyComponent->name())
- && !m_toInstallComponentIds.contains(component->name()))) {
- if (m_visitedComponents.value(component).contains(dependencyComponent)) {
- const QString errorMessage = recursionError(component);
- qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage;
- m_componentsToInstallError = errorMessage;
- Q_ASSERT_X(!m_visitedComponents.value(component).contains(dependencyComponent),
- Q_FUNC_INFO, qPrintable(errorMessage));
- return false;
- }
- m_visitedComponents[component].insert(dependencyComponent);
}
- if (!component->autoDependencies().contains(dependencyComponentName))
- m_referenceCount[dependencyComponentName] << component->name();
+ m_visitedComponents[component].insert(dependencyComponent);
+ // add needed dependency components to the next run
+ insertInstallReason(dependencyComponent, InstallerCalculator::Dependent,
+ component->name());
- insertInstallReason(dependencyComponent, InstallerCalculator::Dependent, component->name());
- if (!appendComponentToInstall(dependencyComponent, requiredDependencyVersion, revertFromInstall))
+ if (!appendComponentToInstall(dependencyComponent, requiredDependencyVersion))
return false;
}
}
- if (!revertFromInstall && !m_toInstallComponentIds.contains(component->name())) {
- realAppendToInstallComponents(component, requiredDependencyVersion, revertFromInstall);
+
+ if (!m_toInstallComponentIds.contains(component->name())) {
+ realAppendToInstallComponents(component, requiredDependencyVersion);
insertInstallReason(component, InstallerCalculator::Resolved);
}
- if (revertFromInstall && m_toInstallComponentIds.contains(component->name())) {
- realAppendToInstallComponents(component, requiredDependencyVersion, revertFromInstall);
- }
return true;
}
-QString InstallerCalculator::recursionError(const Component *component) const
-{
- return QCoreApplication::translate("InstallerCalculator", "Recursion detected, component \"%1\" "
- "already added with reason: \"%2\"").arg(component->name(), installReason(component));
-}
-
-QSet<Component *> InstallerCalculator::autodependencyComponents(const bool revertFromInstall)
+QSet<Component *> InstallerCalculator::autodependencyComponents()
{
// All regular dependencies are resolved. Now we are looking for auto depend on components.
// m_componentsForAutodepencencyCheck is a list of recently calculated components to be installed
@@ -295,13 +235,12 @@ QSet<Component *> InstallerCalculator::autodependencyComponents(const bool rever
QSet<Component *> foundAutoDependOnList;
for (const Component *component : qAsConst(m_componentsForAutodepencencyCheck)) {
if (!m_autoDependencyComponentHash.contains(component->name())
- || (!revertFromInstall && m_core->isUpdater() && !component->updateRequested()))
+ || (m_core->isUpdater() && !component->updateRequested()))
continue;
for (const QString& autoDependency : m_autoDependencyComponentHash.value(component->name())) {
// If a components is already installed or is scheduled for installation, no need to check
// for auto depend installation.
- if ((!revertFromInstall && m_toInstallComponentIds.contains(autoDependency))
- || (revertFromInstall && !m_toInstallComponentIds.contains(autoDependency))) {
+ if (m_toInstallComponentIds.contains(autoDependency)) {
continue;
}
Component *autoDependComponent = m_core->componentByName(autoDependency);
@@ -316,10 +255,6 @@ QSet<Component *> InstallerCalculator::autodependencyComponents(const bool rever
foundAutoDependOnList.insert(autoDependComponent);
insertInstallReason(autoDependComponent, InstallerCalculator::Automatic);
}
- } else if (revertFromInstall
- && m_toInstallComponentIds.contains(autoDependComponent->name())
- && !m_toInstallComponentIds.contains(component->name())) {
- foundAutoDependOnList.insert(autoDependComponent);
}
}
}
@@ -327,20 +262,4 @@ QSet<Component *> InstallerCalculator::autodependencyComponents(const bool rever
return foundAutoDependOnList;
}
-void InstallerCalculator::calculateComponentDependencyReferences(const QString &dependencyComponentName, const Component *component)
-{
- Component *dependencyComponent = m_core->componentByName(dependencyComponentName);
- if (!dependencyComponent || component->autoDependencies().contains(dependencyComponentName))
- return;
- QStringList value = m_referenceCount.value(dependencyComponentName, QStringList());
- value << component->name();
- m_referenceCount.insert(dependencyComponentName, value);
-
- const QStringList dependenciesList = dependencyComponent->currentDependencies();
- for (const QString &depComponentName : dependenciesList) {
- Component *depComponent = m_core->componentByName(depComponentName);
- calculateComponentDependencyReferences(depComponentName, depComponent);
- }
-}
-
} // namespace QInstaller
diff --git a/src/libs/installer/installercalculator.h b/src/libs/installer/installercalculator.h
index bdb8ac404..422de439c 100644
--- a/src/libs/installer/installercalculator.h
+++ b/src/libs/installer/installercalculator.h
@@ -39,6 +39,7 @@
namespace QInstaller {
class Component;
+class PackageManagerCore;
class INSTALLER_EXPORT InstallerCalculator
{
@@ -53,33 +54,27 @@ public:
Resolved // "Component(s) that have resolved Dependencies"
};
- InstallReasonType installReasonType(const Component *c) const;
+ InstallReasonType installReasonType(const Component *component) const;
QString installReason(const Component *component) const;
QList<Component*> orderedComponentsToInstall() const;
QString componentsToInstallError() const;
-
- bool appendComponentsToInstall(const QList<Component*> &components, bool modelReset = false, const bool revertFromInstall = false);
- bool removeComponentsFromInstall(const QList<Component*> &components);
+ bool appendComponentsToInstall(const QList<Component*> &components);
private:
QString installReasonReferencedComponent(const Component *component) const;
- void insertInstallReason(const Component *component,
- const InstallReasonType installReason,
- const QString &referencedComponentName = QString(),
- const bool revertFromInstall = false);
- void realAppendToInstallComponents(Component *component, const QString &version, const bool revertFromInstall);
- bool appendComponentToInstall(Component *component, const QString &version, const bool revertFromInstall);
- QString recursionError(const Component *component) const;
- QSet<Component *> autodependencyComponents(const bool revertFromInstall);
- void calculateComponentDependencyReferences(const QString &dependencyComponentName, const Component *component);
+ void insertInstallReason(Component *component,
+ InstallReasonType installReasonType,
+ const QString &referencedComponentName = QString());
+ void realAppendToInstallComponents(Component *component, const QString &version = QString());
+ bool appendComponentToInstall(Component *components, const QString &version = QString());
+ QSet<Component *> autodependencyComponents();
+ QString recursionError(Component *component) const;
private:
PackageManagerCore *m_core;
QHash<Component*, QSet<Component*> > m_visitedComponents;
QList<const Component*> m_componentsForAutodepencencyCheck;
- //for faster lookups.
- QSet<QString> m_toInstallComponentIds;
- QHash<QString, QStringList> m_referenceCount;
+ QSet<QString> m_toInstallComponentIds; //for faster lookups
QString m_componentsToInstallError;
//calculate installation order variables
QList<Component*> m_orderedComponentsToInstall;
diff --git a/src/libs/installer/metadatajob.cpp b/src/libs/installer/metadatajob.cpp
index 5179896ac..5a7aa66f4 100644
--- a/src/libs/installer/metadatajob.cpp
+++ b/src/libs/installer/metadatajob.cpp
@@ -582,6 +582,7 @@ void MetadataJob::metadataTaskFinished()
}
UnzipArchiveTask *task = new UnzipArchiveTask(result.target(),
item.value(TaskRole::UserRole).toString());
+ task->setRemoveArchive(true);
QFutureWatcher<void> *watcher = new QFutureWatcher<void>();
m_unzipTasks.insert(watcher, qobject_cast<QObject*> (task));
diff --git a/src/libs/installer/metadatajob_p.h b/src/libs/installer/metadatajob_p.h
index 5a4fcad2d..7dcb0b34c 100644
--- a/src/libs/installer/metadatajob_p.h
+++ b/src/libs/installer/metadatajob_p.h
@@ -62,10 +62,12 @@ class UnzipArchiveTask : public AbstractTask<void>
public:
UnzipArchiveTask(const QString &arcive, const QString &target)
- : m_archive(arcive), m_targetDir(target)
+ : m_archive(arcive), m_targetDir(target), m_removeArchive(false)
{}
QString target() { return m_targetDir; }
QString archive() { return m_archive; }
+ void setRemoveArchive(bool remove) { m_removeArchive = remove; }
+
void doTask(QFutureInterface<void> &fi) override
{
fi.reportStarted();
@@ -87,9 +89,10 @@ public:
fi.reportException(UnzipArchiveException(MetadataJob::tr("Error while extracting "
"archive \"%1\": %2").arg(QDir::toNativeSeparators(m_archive), archive->errorString())));
}
- // Don't need the archive anymore
+
archive->close();
- QFile::remove(m_archive);
+ if (m_removeArchive)
+ QFile::remove(m_archive);
fi.reportFinished();
}
@@ -97,6 +100,7 @@ public:
private:
QString m_archive;
QString m_targetDir;
+ bool m_removeArchive;
};
class CacheTaskException : public QException
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 45f8864a7..5100c62ed 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -622,7 +622,7 @@ void PackageManagerCore::componentsToInstallNeedsRecalculation()
QList<Component*> selectedComponentsToInstall = componentsMarkedForInstallation();
d->m_componentsToInstallCalculated =
- d->installerCalculator()->appendComponentsToInstall(selectedComponentsToInstall, true);
+ d->installerCalculator()->appendComponentsToInstall(selectedComponentsToInstall);
d->calculateUninstallComponents();
d->updateComponentCheckedState();
@@ -633,66 +633,6 @@ void PackageManagerCore::componentsToInstallNeedsRecalculation()
}
/*!
- Calculates components to install based on user selection. \a indexes
- contains list of model indexes user has selected for install, dependencies
- and autodependencies are resolved later.
- */
-void PackageManagerCore::calculateUserSelectedComponentsToInstall(const QList<QModelIndex> &indexes)
-{
- QList<Component*> componentsToInstall;
- QList<Component*> componentsToUnInstall;
- ComponentModel *model = isUpdater() ? updaterComponentModel() : defaultComponentModel();
- for (QModelIndex index : indexes) {
- Component *installComponent = model->componentFromIndex(index);
- // 1. Component is selected for install
- if (installComponent->isSelected() && !installComponent->isInstalled()) {
- componentsToInstall.append(installComponent);
- // Check if component has replacements that needs to be removed
- const QList<Component*> replacedComponents = d->replacedComponentsByName(installComponent->name());
- for (Component *replacedComponent : replacedComponents) {
- componentsToUnInstall.append(replacedComponent);
- d->uninstallerCalculator()->insertUninstallReason(replacedComponent,
- UninstallerCalculator::UninstallReasonType::Replaced);
- }
- }
- // 2. Component is reselected for install (tapping checkbox off/on)
- else if (installComponent->isSelected() && installComponent->isInstalled()
- && !d->installerCalculator()->orderedComponentsToInstall().contains(installComponent)) {
- componentsToInstall.append(installComponent);
- }
- // 3. Component is selected for uninstall
- else if (!isUpdater() && !installComponent->isSelected() && installComponent->isInstalled()) {
- componentsToUnInstall.append(installComponent);
- }
- // 4. Component is reselected for uninstall (tapping checkbox on/off)
- else if (!installComponent->isSelected()
- && d->installerCalculator()->orderedComponentsToInstall().contains(installComponent)) {
- componentsToUnInstall.append(installComponent);
- // Check if component has replacements that needs to be readded
- componentsToInstall.append(d->replacedComponentsByName(installComponent->name()));
- }
- }
-
- d->installerCalculator()->removeComponentsFromInstall(componentsToUnInstall);
- d->m_componentsToInstallCalculated
- = d->installerCalculator()->appendComponentsToInstall(componentsToInstall, false);
- if (!isUpdater()) {
- d->uninstallerCalculator()->appendComponentsToUninstall(componentsToUnInstall, false);
- }
- d->uninstallerCalculator()->removeComponentsFromUnInstall(componentsToInstall);
- if (componentsToUnInstall.isEmpty() && !componentsToInstall.isEmpty()) {
- // There are no new components to be uninstalled but there
- // are new components to be installed which might have virtual
- // dependences to components which are already selected for uninstall.
- // We need to remove those components from uninstall.
- d->uninstallerCalculator()->appendVirtualComponentsToUninstall(true);
- }
-
- d->updateComponentCheckedState();
-}
-
-
-/*!
Forces a recalculation of components to install.
\sa {installer::clearComponentsToInstallCalculated}{installer.clearComponentsToInstallCalculated}
*/
@@ -3505,6 +3445,17 @@ void PackageManagerCore::setInstallerBaseBinary(const QString &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
in cases where we are not running a real installer, i.e. when executing autotests.
@@ -4577,10 +4528,8 @@ ComponentModel *PackageManagerCore::componentModel(PackageManagerCore *core, con
ComponentModel::tr("Release Date"));
model->setHeaderData(ComponentModelHelper::UncompressedSizeColumn, Qt::Horizontal,
ComponentModel::tr("Size"));
- connect(model, &ComponentModel::modelCheckStateChanged,
+ connect(model, &ComponentModel::checkStateChanged,
this, &PackageManagerCore::componentsToInstallNeedsRecalculation);
- connect(model, &ComponentModel::componentsCheckStateChanged,
- this, &PackageManagerCore::calculateUserSelectedComponentsToInstall);
return model;
}
diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h
index cd44c2ef1..8a0b09c02 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);
@@ -362,7 +363,6 @@ public Q_SLOTS:
void setCompleteUninstallation(bool complete);
void cancelMetaInfoJob();
void componentsToInstallNeedsRecalculation();
- void calculateUserSelectedComponentsToInstall(const QList<QModelIndex> &indexes);
void clearComponentsToInstallCalculated();
Q_SIGNALS:
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index 9b77dd657..721e0d867 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -544,21 +544,6 @@ QHash<QString, QStringList> &PackageManagerCorePrivate::componentReplaces()
return m_componentReplaces;
}
-QList<Component*> PackageManagerCorePrivate::replacedComponentsByName(const QString &name)
-{
- // Creates a list of components which are replaced by component 'name'
- QList<Component*> replacedComponents;
- if (m_componentReplaces.contains(name)) {
- for (const QString &replacedComponentName : m_componentReplaces.value(name)) {
- Component *replacedComponent = m_core->componentByName(replacedComponentName,
- m_core->components(PackageManagerCore::ComponentType::All));
- if (replacedComponent)
- replacedComponents.append(replacedComponent);
- }
- }
- return replacedComponents;
-}
-
void PackageManagerCorePrivate::clearInstallerCalculator()
{
delete m_installerCalculator;
@@ -593,7 +578,7 @@ UninstallerCalculator *PackageManagerCorePrivate::uninstallerCalculator() const
}
}
- pmcp->m_uninstallerCalculator = new UninstallerCalculator(installedComponents, m_core,
+ pmcp->m_uninstallerCalculator = new UninstallerCalculator(m_core,
pmcp->m_autoDependencyComponentHash, pmcp->m_localDependencyComponentHash, pmcp->m_localVirtualComponents);
}
return m_uninstallerCalculator;
@@ -1950,7 +1935,7 @@ bool PackageManagerCorePrivate::runPackageUpdater()
// There is a replacement, but the replacement is not scheduled for update, keep it as well.
if (m_componentsToReplaceUpdaterMode.contains(name)
- && !m_componentsToReplaceUpdaterMode.value(name).first->updateRequested()) {
+ && !m_installerCalculator->orderedComponentsToInstall().contains(m_componentsToReplaceUpdaterMode.value(name).first)) {
nonRevertedOperations.append(operation);
continue;
}
@@ -3114,12 +3099,10 @@ void PackageManagerCorePrivate::calculateUninstallComponents()
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()) {
- uninstallerCalculator()->insertUninstallReason(component,
- UninstallerCalculator::Replaced, comp.first->name());
- selectedComponentsToUninstall.append(comp.second);
- }
+ if (comp.first && m_installerCalculator->orderedComponentsToInstall().contains(comp.first)) {
+ uninstallerCalculator()->insertUninstallReason(component,
+ UninstallerCalculator::Replaced, comp.first->name());
+ selectedComponentsToUninstall.append(comp.second);
}
}
foreach (Component *component, m_core->components(PackageManagerCore::ComponentType::AllNoReplacements)) {
diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h
index d45e2f219..8d6ba0c89 100644
--- a/src/libs/installer/packagemanagercore_p.h
+++ b/src/libs/installer/packagemanagercore_p.h
@@ -119,7 +119,6 @@ public:
QList<Component*> &replacementDependencyComponents();
QHash<QString, QPair<Component*, Component*> > &componentsToReplace();
QHash<QString, QStringList > &componentReplaces();
- QList<Component*> replacedComponentsByName(const QString &name);
void clearInstallerCalculator();
InstallerCalculator *installerCalculator() const;
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index f7c500811..b093838a3 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -1740,6 +1740,17 @@ void IntroductionPage::setMaintainerToolsEnabled(bool enable)
&& ProductKeyCheck::instance()->hasValidKey());
}
+/*!
+ Resets the internal page state, so that on clicking \uicontrol Next the metadata needs to be
+ fetched again.
+*/
+void IntroductionPage::resetFetchedState()
+{
+ m_updatesFetched = false;
+ m_allPackagesFetched = false;
+ m_forceUpdate = false;
+}
+
// -- public slots
/*!
@@ -1881,9 +1892,7 @@ void IntroductionPage::initializePage()
*/
void IntroductionPage::onCoreNetworkSettingsChanged()
{
- m_updatesFetched = false;
- m_allPackagesFetched = false;
- m_forceUpdate = false;
+ resetFetchedState();
PackageManagerCore *core = packageManagerCore();
if (core->isUninstaller() || core->isMaintainer()) {
diff --git a/src/libs/installer/packagemanagergui.h b/src/libs/installer/packagemanagergui.h
index cce36e4ae..a25329b9c 100644
--- a/src/libs/installer/packagemanagergui.h
+++ b/src/libs/installer/packagemanagergui.h
@@ -236,6 +236,8 @@ public:
void setMaintenanceToolsEnabled(bool enable);
void setMaintainerToolsEnabled(bool enable);
+ void resetFetchedState();
+
public Q_SLOTS:
void onCoreNetworkSettingsChanged();
void setMessage(const QString &msg);
diff --git a/src/libs/installer/qinstallerglobal.cpp b/src/libs/installer/qinstallerglobal.cpp
index 8b1b9c6ad..457690892 100644
--- a/src/libs/installer/qinstallerglobal.cpp
+++ b/src/libs/installer/qinstallerglobal.cpp
@@ -39,6 +39,7 @@
\value ExtractionError
\value UserIgnoreError
\value RepositoryUpdatesReceived
+ \value CacheError
*/
/*!
@@ -66,9 +67,10 @@
*/
/*!
- \typedef QInstaller::LocalPackagesHash
+ \typedef QInstaller::LocalPackagesMap
- Synonym for QHash<QString, KDUpdater::LocalPackage>.
+ Synonym for QMap<QString, KDUpdater::LocalPackage>. The map key is component name,
+ and value contains information about the local package.
*/
/*!
@@ -85,7 +87,7 @@
*/
/*!
- \typedef QInstaller::DependencyHash
+ \typedef QInstaller::LocalDependencyHash
Synonym for QHash<QString, QStringList>. The hash key is component name,
which other components depend on. The value can contain several component
diff --git a/src/libs/installer/settingsoperation.cpp b/src/libs/installer/settingsoperation.cpp
index 4c983b17a..a74161178 100644
--- a/src/libs/installer/settingsoperation.cpp
+++ b/src/libs/installer/settingsoperation.cpp
@@ -46,6 +46,7 @@ SettingsOperation::SettingsOperation(PackageManagerCore *core)
: UpdateOperation(core)
{
setName(QLatin1String("Settings"));
+ setRequiresUnreplacedVariables(true);
}
void SettingsOperation::backup()
@@ -104,10 +105,17 @@ bool SettingsOperation::performOperation()
if (!checkArguments())
return false;
- const QString path = argumentKeyValue(QLatin1String("path"));
+ QString path = argumentKeyValue(QLatin1String("path"));
const QString method = argumentKeyValue(QLatin1String("method"));
const QString key = argumentKeyValue(QLatin1String("key"));
- const QString aValue = argumentKeyValue(QLatin1String("value"));
+ QString aValue = argumentKeyValue(QLatin1String("value"));
+
+ if (requiresUnreplacedVariables()) {
+ if (PackageManagerCore *const core = packageManager()) {
+ path = core->replaceVariables(path);
+ aValue = core->replaceVariables(aValue);
+ }
+ }
// use MkdirOperation to get the path so it can remove it with MkdirOperation::undoOperation later
KDUpdater::MkdirOperation mkDirOperation;
@@ -152,14 +160,25 @@ bool SettingsOperation::undoOperation()
{
if (!checkArguments())
return false;
- const QString path = argumentKeyValue(QLatin1String("path"));
+ QString path = argumentKeyValue(QLatin1String("path"));
const QString method = argumentKeyValue(QLatin1String("method"));
const QString key = argumentKeyValue(QLatin1String("key"));
- const QString aValue = argumentKeyValue(QLatin1String("value"));
+ QString aValue = argumentKeyValue(QLatin1String("value"));
if (method.startsWith(QLatin1String("remove")))
return true;
+ if (requiresUnreplacedVariables()) {
+ if (PackageManagerCore *const core = packageManager()) {
+ path = core->replaceVariables(path);
+ aValue = core->replaceVariables(aValue);
+ // Check is different settings file is wanted to be used.
+ // Old settings file name should be set to variable <variable_name>_OLD,
+ // and new path is then read from <variable_name> variable.
+ variableReplacement(&path);
+ }
+ }
+
bool cleanUp = false;
{ // kill the scope to kill settings object, else remove file will not work
QSettingsWrapper settings(path, QSettings::IniFormat);
diff --git a/src/libs/installer/uninstallercalculator.cpp b/src/libs/installer/uninstallercalculator.cpp
index 36d769207..2f029630f 100644
--- a/src/libs/installer/uninstallercalculator.cpp
+++ b/src/libs/installer/uninstallercalculator.cpp
@@ -30,9 +30,6 @@
#include "component.h"
#include "packagemanagercore.h"
-#include "globals.h"
-
-#include <QDebug>
namespace QInstaller {
@@ -42,13 +39,11 @@ namespace QInstaller {
\internal
*/
-UninstallerCalculator::UninstallerCalculator(const QList<Component *> &installedComponents
- , PackageManagerCore *core
+UninstallerCalculator::UninstallerCalculator(PackageManagerCore *core
, const AutoDependencyHash &autoDependencyComponentHash
, const LocalDependencyHash &localDependencyComponentHash
, const QStringList &localVirtualComponents)
- : m_installedComponents(installedComponents)
- , m_core(core)
+ : m_core(core)
, m_autoDependencyComponentHash(autoDependencyComponentHash)
, m_localDependencyComponentHash(localDependencyComponentHash)
, m_localVirtualComponents(localVirtualComponents)
@@ -60,7 +55,7 @@ QSet<Component *> UninstallerCalculator::componentsToUninstall() const
return m_componentsToUninstall;
}
-void UninstallerCalculator::appendComponentToUninstall(Component *component, const bool reverse)
+void UninstallerCalculator::appendComponentToUninstall(Component *component)
{
if (!component)
return;
@@ -74,29 +69,22 @@ void UninstallerCalculator::appendComponentToUninstall(Component *component, con
Component *depComponent = m_core->componentByName(dependencyComponent);
if (!depComponent)
continue;
- if (depComponent->isInstalled() && !m_componentsToUninstall.contains(depComponent)) {
- appendComponentToUninstall(depComponent, reverse);
+ if (depComponent->isInstalled() && !m_componentsToUninstall.contains(depComponent)
+ && !m_core->orderedComponentsToInstall().contains(depComponent)) {
+ appendComponentToUninstall(depComponent);
insertUninstallReason(depComponent, UninstallerCalculator::Dependent, component->name());
- } else if (reverse && depComponent->isVirtual()) {
- // Remove from uninstall only hidden components, user
- // can select other dependencies manually
- appendComponentToUninstall(depComponent, true);
}
}
}
- if (reverse) {
- m_componentsToUninstall.remove(component);
- } else {
- m_componentsToUninstall.insert(component);
- }
+
+ m_componentsToUninstall.insert(component);
}
-void UninstallerCalculator::appendComponentsToUninstall(const QList<Component*> &components, const bool reverse)
+void UninstallerCalculator::appendComponentsToUninstall(const QList<Component*> &components)
{
- if (components.isEmpty())
- return;
foreach (Component *component, components)
- appendComponentToUninstall(component, reverse);
+ appendComponentToUninstall(component);
+
QList<Component*> autoDependOnList;
// All regular dependees are resolved. Now we are looking for auto depend on components.
for (Component *component : components) {
@@ -108,9 +96,7 @@ void UninstallerCalculator::appendComponentsToUninstall(const QList<Component*>
Component *autoDepComponent = m_core->componentByName(autoDependencyComponent);
if (autoDepComponent && autoDepComponent->isInstalled()) {
// A component requested auto uninstallation, keep it to resolve their dependencies as well.
- if (reverse) {
- autoDependOnList.append(autoDepComponent);
- } else if (!m_componentsToUninstall.contains(autoDepComponent)) {
+ if (!m_componentsToUninstall.contains(autoDepComponent)) {
insertUninstallReason(autoDepComponent, UninstallerCalculator::AutoDependent, component->name());
autoDepComponent->setInstallAction(ComponentModelHelper::AutodependUninstallation);
autoDependOnList.append(autoDepComponent);
@@ -118,15 +104,11 @@ void UninstallerCalculator::appendComponentsToUninstall(const QList<Component*>
}
}
}
+
if (!autoDependOnList.isEmpty())
- appendComponentsToUninstall(autoDependOnList, reverse);
+ appendComponentsToUninstall(autoDependOnList);
else
- appendVirtualComponentsToUninstall(reverse);
-}
-
-void UninstallerCalculator::removeComponentsFromUnInstall(const QList<Component*> &components)
-{
- appendComponentsToUninstall(components, true);
+ appendVirtualComponentsToUninstall();
}
void UninstallerCalculator::insertUninstallReason(Component *component, const UninstallReasonType uninstallReason,
@@ -172,38 +154,30 @@ QString UninstallerCalculator::uninstallReasonReferencedComponent(Component *com
return m_toUninstallComponentIdReasonHash.value(component->name()).second;
}
-void UninstallerCalculator::appendVirtualComponentsToUninstall(const bool reverse)
+void UninstallerCalculator::appendVirtualComponentsToUninstall()
{
QList<Component*> unneededVirtualList;
-
// Check for virtual components without dependees
- if (reverse) {
- for (Component *reverseFromUninstall : qAsConst(m_virtualComponentsForReverse)) {
- if (m_componentsToUninstall.contains(reverseFromUninstall) && (isRequiredVirtualPackage(reverseFromUninstall)))
- unneededVirtualList.append(reverseFromUninstall);
- }
- } else {
- for (const QString &componentName : qAsConst(m_localVirtualComponents)) {
- Component *virtualComponent = m_core->componentByName(componentName, m_core->components(PackageManagerCore::ComponentType::All));
- if (!virtualComponent)
- continue;
+ for (const QString &componentName : qAsConst(m_localVirtualComponents)) {
+ Component *virtualComponent = m_core->componentByName(componentName, m_core->components(PackageManagerCore::ComponentType::All));
+ if (!virtualComponent)
+ continue;
- if (virtualComponent->isInstalled() && !m_componentsToUninstall.contains(virtualComponent)) {
- // Components with auto dependencies were handled in the previous step
- if (!virtualComponent->autoDependencies().isEmpty() || virtualComponent->forcedInstallation())
- continue;
+ if (virtualComponent->isInstalled() && !m_componentsToUninstall.contains(virtualComponent)) {
+ // Components with auto dependencies were handled in the previous step
+ if (!virtualComponent->autoDependencies().isEmpty() || virtualComponent->forcedInstallation())
+ continue;
- if (!isRequiredVirtualPackage(virtualComponent)) {
- unneededVirtualList.append(virtualComponent);
- m_virtualComponentsForReverse.append(virtualComponent);
- insertUninstallReason(virtualComponent, UninstallerCalculator::VirtualDependent);
- }
- }
+ if (!isRequiredVirtualPackage(virtualComponent)) {
+ unneededVirtualList.append(virtualComponent);
+ m_virtualComponentsForReverse.append(virtualComponent);
+ insertUninstallReason(virtualComponent, UninstallerCalculator::VirtualDependent);
+ }
}
}
if (!unneededVirtualList.isEmpty())
- appendComponentsToUninstall(unneededVirtualList, reverse);
+ appendComponentsToUninstall(unneededVirtualList);
}
bool UninstallerCalculator::isRequiredVirtualPackage(Component *component)
diff --git a/src/libs/installer/uninstallercalculator.h b/src/libs/installer/uninstallercalculator.h
index 57f2f926a..74207e005 100644
--- a/src/libs/installer/uninstallercalculator.h
+++ b/src/libs/installer/uninstallercalculator.h
@@ -53,28 +53,26 @@ public:
AutoDependent // "Removed as autodependency component is removed"
};
- UninstallerCalculator(const QList<Component *> &installedComponents, PackageManagerCore *core,
+ UninstallerCalculator(PackageManagerCore *core,
const AutoDependencyHash &autoDependencyComponentHash,
const LocalDependencyHash &localDependencyComponentHash,
const QStringList &localVirtualComponents);
QSet<Component*> componentsToUninstall() const;
- void appendComponentsToUninstall(const QList<Component*> &components, const bool reverse = false);
- void removeComponentsFromUnInstall(const QList<Component*> &components);
+ void appendComponentsToUninstall(const QList<Component*> &components);
void insertUninstallReason(Component *component,
const UninstallReasonType uninstallReason,
const QString &referencedComponentName = QString());
QString uninstallReason(Component *component) const;
UninstallerCalculator::UninstallReasonType uninstallReasonType(Component *c) const;
- QString uninstallReasonReferencedComponent(Component *component) const;
- bool isRequiredVirtualPackage(Component *component);
- void appendVirtualComponentsToUninstall(const bool reverse);
private:
- void appendComponentToUninstall(Component *component, const bool reverse);
+ QString uninstallReasonReferencedComponent(Component *component) const;
+ bool isRequiredVirtualPackage(Component *component);
+ void appendComponentToUninstall(Component *component);
+ void appendVirtualComponentsToUninstall();
- QList<Component *> m_installedComponents;
QSet<Component *> m_componentsToUninstall;
PackageManagerCore *m_core;
QHash<QString, QPair<UninstallReasonType, QString> > m_toUninstallComponentIdReasonHash;
diff --git a/src/libs/kdtools/localpackagehub.cpp b/src/libs/kdtools/localpackagehub.cpp
index bd6d879e3..c7b627c51 100644
--- a/src/libs/kdtools/localpackagehub.cpp
+++ b/src/libs/kdtools/localpackagehub.cpp
@@ -313,6 +313,7 @@ void LocalPackageHub::refresh()
\a title,
\a treeName,
\a description,
+ \a sortingPriority,
\a dependencies,
\a autoDependencies,
\a forcedInstallation,
diff --git a/src/libs/kdtools/updateoperation.cpp b/src/libs/kdtools/updateoperation.cpp
index 35629809e..b35751096 100644
--- a/src/libs/kdtools/updateoperation.cpp
+++ b/src/libs/kdtools/updateoperation.cpp
@@ -321,6 +321,39 @@ void UpdateOperation::setRequiresUnreplacedVariables(bool isRequired)
m_requiresUnreplacedVariables = isRequired;
}
+/*!
+ Replaces installer \c value \a variableValue with predefined variable.
+ If \c key is found for the \a variableValue and the \c key ends with string _OLD,
+ the initial \a variableValue is replaced with the \c value having a key
+ without _OLD ending. This way we can replace the hard coded values defined for operations,
+ if the value has for some reason changed. For example if we set following variables
+ in install script:
+ \badcode
+ installer.setValue("MY_OWN_EXECUTABLE", "C:/Qt/NewLocation/Tools.exe")
+ installer.setValue("MY_OWN_EXECUTABLE_OLD", "C:/Qt/OldLocation/Tools.exe")
+ \endcode
+ and we have moved the Tools.exe from OldLocation to NewLocation, the operation
+ continues to work and use the Tools.exe from NewLocation although original
+ installation has been made with Tools.exe in OldLocation.
+ Returns \c true if \a variableValue is replaced.
+*/
+bool UpdateOperation::variableReplacement(QString *variableValue)
+{
+ bool variableValueChanged = false;
+ const QString valueNormalized = QDir::cleanPath(*variableValue);
+ QString key = m_core->key(valueNormalized);
+ if (key.endsWith(QLatin1String("_OLD"))) {
+ key.chop(4);
+ if (m_core->containsValue(key)) {
+ key.prepend(QLatin1String("@"));
+ key.append(QLatin1String("@"));
+ *variableValue = m_core->replaceVariables(key);
+ variableValueChanged = true;
+ }
+ }
+ return variableValueChanged;
+}
+
struct StartsWith
{
explicit StartsWith(const QString &searchTerm)
diff --git a/src/libs/kdtools/updateoperation.h b/src/libs/kdtools/updateoperation.h
index a39c25747..4a431f107 100644
--- a/src/libs/kdtools/updateoperation.h
+++ b/src/libs/kdtools/updateoperation.h
@@ -114,6 +114,7 @@ protected:
QStringList parsePerformOperationArguments();
QStringList parseUndoOperationArguments();
void setRequiresUnreplacedVariables(bool isRequired);
+ bool variableReplacement(QString *variableValue);
private:
QString m_name;
diff --git a/src/sdk/tabcontroller.cpp b/src/sdk/tabcontroller.cpp
index c40ceed5f..089bd8468 100644
--- a/src/sdk/tabcontroller.cpp
+++ b/src/sdk/tabcontroller.cpp
@@ -130,7 +130,7 @@ int TabController::init()
if (page) {
page->setMessage(QString());
page->setErrorMessage(QString());
- page->onCoreNetworkSettingsChanged();
+ page->resetFetchedState();
}
d->m_gui->restart();
diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/Updates.xml b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/Updates.xml
index 9e01f1800..de6e66525 100644
--- a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/Updates.xml
+++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/Updates.xml
@@ -160,4 +160,20 @@
<ForcedUpdate>true</ForcedUpdate>
<DownloadableArchives>content.7z</DownloadableArchives>
</PackageUpdate>
+ <PackageUpdate>
+ <Name>qt.tools.qtcreator</Name>
+ <DisplayName>Component qtcreator. Depends on virtual component</DisplayName>
+ <Version>1.0.0</Version>
+ <ReleaseDate>2014-08-25</ReleaseDate>
+ <Dependencies>qt.tools.qtcreator.enterprise.plugins</Dependencies>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>qt.tools.qtcreator.enterprise.plugins</Name>
+ <DisplayName>enterprise plugin component</DisplayName>
+ <Version>1.0.0</Version>
+ <ReleaseDate>2014-08-25</ReleaseDate>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ <Virtual>true</Virtual>
+ </PackageUpdate>
</Updates>
diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator.enterprise.plugins/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator.enterprise.plugins/1.0.0content.7z
new file mode 100644
index 000000000..5c7c4f37d
--- /dev/null
+++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator.enterprise.plugins/1.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator/1.0.0content.7z
new file mode 100644
index 000000000..e5e4178a4
--- /dev/null
+++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator/1.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/Updates.xml b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/Updates.xml
new file mode 100644
index 000000000..f55998c48
--- /dev/null
+++ b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/Updates.xml
@@ -0,0 +1,32 @@
+<Updates>
+ <ApplicationName>{AnyApplication}</ApplicationName>
+ <ApplicationVersion>1.0.0</ApplicationVersion>
+ <Checksum>false</Checksum>
+ <PackageUpdate>
+ <Name>qt.tools.qtcreator</Name>
+ <DisplayName>Component qtcreator. Dependency removed</DisplayName>
+ <Version>2.0.0</Version>
+ <ReleaseDate>2014-08-25</ReleaseDate>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>qt.tools.qtcreator_gui</Name>
+ <DisplayName>Component K. Autodepends on componentJ</DisplayName>
+ <Description>Component K. Autodepends on componentJ</Description>
+ <Version>2.0.0</Version>
+ <ReleaseDate>2014-08-25</ReleaseDate>
+ <AutoDependOn>qt.tools.qtcreator</AutoDependOn>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>qt.tools.qtcreator_gui.enterprise.plugins</Name>
+ <DisplayName>enterprise plugins, replaces another component</DisplayName>
+ <Version>2.0.0</Version>
+ <ReleaseDate>2018-03-14</ReleaseDate>
+ <Virtual>true</Virtual>
+ <Replaces>qt.tools.qtcreator.enterprise.plugins</Replaces>
+ <AutoDependOn>qt.tools.qtcreator</AutoDependOn>
+ <UpdateFile UncompressedSize="99" OS="Any" CompressedSize="305"/>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ </PackageUpdate>
+</Updates>
diff --git a/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator/2.0.0content.7z
new file mode 100644
index 000000000..f2b69fc13
--- /dev/null
+++ b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator/2.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui.enterprise.plugins/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui.enterprise.plugins/2.0.0content.7z
new file mode 100644
index 000000000..03d191cb5
--- /dev/null
+++ b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui.enterprise.plugins/2.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui/2.0.0content.7z
new file mode 100644
index 000000000..515c3a5cf
--- /dev/null
+++ b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui/2.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/commandlineupdate/settings.qrc b/tests/auto/installer/commandlineupdate/settings.qrc
index d398abe30..c8f328d6b 100644
--- a/tests/auto/installer/commandlineupdate/settings.qrc
+++ b/tests/auto/installer/commandlineupdate/settings.qrc
@@ -17,6 +17,8 @@
<file>data/installPackagesRepository/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z</file>
<file>data/installPackagesRepository/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z</file>
<file>data/installPackagesRepository/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z</file>
+ <file>data/installPackagesRepository/qt.tools.qtcreator/1.0.0content.7z</file>
+ <file>data/installPackagesRepository/qt.tools.qtcreator.enterprise.plugins/1.0.0content.7z</file>
<file>data/installPackagesRepositoryUpdate/Updates.xml</file>
<file>data/installPackagesRepositoryUpdate/componentA/1.0.0content.7z</file>
<file>data/installPackagesRepositoryUpdate/componentB/2.0.0content.7z</file>
@@ -52,5 +54,9 @@
<file>data/repositoryWithDependencyToEssential/Updates.xml</file>
<file>data/repositoryWithDependencyToEssential/componentAutoDependOnA/1.0content.7z</file>
<file>data/repositoryWithDependencyToEssential/componentA/3.0.0content.7z</file>
+ <file>data/repositoryUpdateWithReplacements/Updates.xml</file>
+ <file>data/repositoryUpdateWithReplacements/qt.tools.qtcreator/2.0.0content.7z</file>
+ <file>data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui/2.0.0content.7z</file>
+ <file>data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui.enterprise.plugins/2.0.0content.7z</file>
</qresource>
</RCC>
diff --git a/tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp b/tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp
index 338157cba..0faeecf74 100644
--- a/tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp
+++ b/tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp
@@ -295,7 +295,7 @@ private slots:
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("componentE", "1.0.0content.txt"));//ForcedInstall, not updated without user selection
componentResourcesAfterUpdate.append(ComponentResource("componentG", "1.0.0content.txt"));
deletedComponentResources.clear();
@@ -316,8 +316,38 @@ private slots:
<< componentResourcesAfterUpdate
<< (QStringList() << "components.xml" << "installcontent.txt" << "installcontentA.txt"
<< "installcontentD_update.txt" << "installcontentB_update.txt"
- << "installcontentE_update.txt" << "installcontentG.txt")
+ << "installcontentE.txt" << "installcontentG.txt")
<< deletedComponentResources;
+
+ /*********** Update packages with replacements **********/
+ componentResources.clear();
+ componentResources.append(ComponentResource("qt.tools.qtcreator", "1.0.0content.txt"));
+ componentResources.append(ComponentResource("qt.tools.qtcreator.enterprise.plugins", "1.0.0content.txt"));
+ componentResources.append(ComponentResource("componentE", "1.0.0content.txt"));
+
+ componentResourcesAfterUpdate.clear();
+ componentResourcesAfterUpdate.append(ComponentResource("qt.tools.qtcreator", "2.0.0content.txt"));
+ componentResourcesAfterUpdate.append(ComponentResource("qt.tools.qtcreator_gui", "2.0.0content.txt"));
+ componentResourcesAfterUpdate.append(ComponentResource("qt.tools.qtcreator_gui.enterprise.plugins", "2.0.0content.txt"));
+ componentResourcesAfterUpdate.append(ComponentResource("componentE", "1.0.0content.txt"));
+
+ deletedComponentResources.clear();
+ deletedComponentResources.append(ComponentResource("qt.tools.qtcreator.enterprise.plugins", "1.0.0content.txt"));
+
+ QTest::newRow("Update packages with replacements")
+ << ":///data/installPackagesRepository"
+ << (QStringList()<< "qt.tools.qtcreator")
+ << PackageManagerCore::Success
+ << componentResources
+ << (QStringList() << "components.xml" << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt"
+ << "installcontent.txt" << "qtcreator.txt" << "plugins.txt")
+ << ":///data/repositoryUpdateWithReplacements"
+ << (QStringList() << "qt.tools.qtcreator")
+ << PackageManagerCore::Success
+ << componentResourcesAfterUpdate
+ << (QStringList() << "components.xml" << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt"
+ << "installcontent.txt" << "gui.txt" << "qtcreator2.txt" << "gui_plugins.txt")
+ << deletedComponentResources;
}
void testUpdate()
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 @@
<file>data/xmloperationrepository/A/1.0.0content4.zip</file>
<file>data/xmloperationrepository/A/1.0.0anothercontent.7z</file>
<file>data/xmloperationrepository/A/1.0.0default.7z</file>
+ <file>data/installerbaserepository/Updates.xml</file>
+ <file>data/installerbaserepository/A/1.0.0content.7z</file>
+ <file>data/installerbaserepository/A/1.0.0installerbase.7z</file>
</qresource>
</RCC>
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
--- /dev/null
+++ b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0content.7z
Binary files 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
--- /dev/null
+++ b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0installerbase.7z
Binary files 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 @@
+<Updates>
+ <ApplicationName>{AnyApplication}</ApplicationName>
+ <ApplicationVersion>1.0.0</ApplicationVersion>
+ <PackageUpdate>
+ <Name>A</Name>
+ <DisplayName>InstallerBase</DisplayName>
+ <Description>Example component InstallerBase</Description>
+ <Version>1.0.0</Version>
+ <ReleaseDate>2015-01-01</ReleaseDate>
+ <Default>true</Default>
+ <DownloadableArchives>installerbase.7z,content.7z</DownloadableArchives>
+ </PackageUpdate>
+</Updates>
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<PackageManagerCore> 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;
};
diff --git a/tests/auto/installer/settingsoperation/data/repository/B/1.0.0meta.7z b/tests/auto/installer/settingsoperation/data/repository/B/1.0.0meta.7z
new file mode 100644
index 000000000..211bc0e0a
--- /dev/null
+++ b/tests/auto/installer/settingsoperation/data/repository/B/1.0.0meta.7z
Binary files differ
diff --git a/tests/auto/installer/settingsoperation/data/repository/C/1.0.0meta.7z b/tests/auto/installer/settingsoperation/data/repository/C/1.0.0meta.7z
new file mode 100644
index 000000000..a990fdbf1
--- /dev/null
+++ b/tests/auto/installer/settingsoperation/data/repository/C/1.0.0meta.7z
Binary files differ
diff --git a/tests/auto/installer/settingsoperation/data/repository/Updates.xml b/tests/auto/installer/settingsoperation/data/repository/Updates.xml
index eddb160c0..3e88f849d 100644
--- a/tests/auto/installer/settingsoperation/data/repository/Updates.xml
+++ b/tests/auto/installer/settingsoperation/data/repository/Updates.xml
@@ -8,8 +8,26 @@
<Description>Example component A</Description>
<Version>1.0.2-1</Version>
<ReleaseDate>2015-01-01</ReleaseDate>
- <Default>true</Default>
+ <Default>false</Default>
<Script>script.qs</Script>
<SHA1>5dc8a98f591998de0c555e194e228fa740a15632</SHA1>
</PackageUpdate>
+ <PackageUpdate>
+ <Name>B</Name>
+ <DisplayName>B</DisplayName>
+ <Description>Example component B</Description>
+ <Version>1.0.0</Version>
+ <ReleaseDate>2015-01-01</ReleaseDate>
+ <Default>false</Default>
+ <Script>script.qs</Script>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>C</Name>
+ <DisplayName>C</DisplayName>
+ <Description>Example component C</Description>
+ <Version>1.0.0</Version>
+ <ReleaseDate>2015-01-01</ReleaseDate>
+ <Default>false</Default>
+ <Script>script.qs</Script>
+ </PackageUpdate>
</Updates>
diff --git a/tests/auto/installer/settingsoperation/settings.qrc b/tests/auto/installer/settingsoperation/settings.qrc
index d030220ab..8da639ad6 100644
--- a/tests/auto/installer/settingsoperation/settings.qrc
+++ b/tests/auto/installer/settingsoperation/settings.qrc
@@ -2,5 +2,7 @@
<qresource prefix="/">
<file>data/repository/Updates.xml</file>
<file>data/repository/A/1.0.2-1meta.7z</file>
+ <file>data/repository/B/1.0.0meta.7z</file>
+ <file>data/repository/C/1.0.0meta.7z</file>
</qresource>
</RCC>
diff --git a/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp b/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp
index 9b08d4f6f..2da0870c7 100644
--- a/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp
+++ b/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp
@@ -177,6 +177,7 @@ private slots:
QFile testFile(testFilePath);
QVERIFY2(testFile.open(QIODevice::WriteOnly | QIODevice::Text), contentFile.errorString().toLatin1());
+ m_cleanupFilePaths << testFilePath;
QTextStream out(&testFile);
@@ -244,6 +245,7 @@ private slots:
QFile testFile(testFilePath);
QVERIFY2(testFile.open(QIODevice::WriteOnly | QIODevice::Text), contentFile.errorString()
.toLatin1());
+ m_cleanupFilePaths << testFilePath;
QTextStream out(&testFile);
@@ -293,7 +295,7 @@ private slots:
QCOMPARE(testSettings.value("testcategory/categoryarrayvalue1").toStringList(),
QStringList() << "value1" << "value2" << "value3");
- core->installDefaultComponentsSilently();
+ core->installSelectedComponentsSilently(QStringList() << "A");
QCOMPARE(testSettings.value("testcategory/categoryarrayvalue1").toStringList(),
QStringList() << "value1" << "value2" << "value3" << "valueFromScript");
@@ -309,6 +311,68 @@ private slots:
core->deleteLater();
}
+ void testPerformingFromCLIWithPlaceholders()
+ {
+ QString installDir = QInstaller::generateTemporaryFileName();
+ QVERIFY(QDir().mkpath(installDir));
+ PackageManagerCore *core = PackageManager::getPackageManagerWithInit
+ (installDir, ":///data/repository");
+
+ core->installSelectedComponentsSilently(QStringList() << "B");
+ // Path is set in component constructor in install script
+ const QString settingsFile = core->value("SettingsPathFromVariable");
+ QSettings testSettings(QDir(m_testSettingsDirPath).filePath(settingsFile),
+ QSettings::IniFormat);
+
+ QCOMPARE(testSettings.value("testcategory/categoryarrayvalue1").toStringList(),
+ QStringList() << "ValueFromPlaceholder");
+
+ core->commitSessionOperations();
+ core->setPackageManager();
+ core->uninstallComponentsSilently(QStringList() << "B");
+
+ // Settings file is removed as it is empty
+ QVERIFY(!QFile::exists(settingsFile));
+ QDir dir(installDir);
+ QVERIFY(dir.removeRecursively());
+ core->deleteLater();
+ }
+
+ void testPerformingFromCLIWithSettingsFileMoved()
+ {
+ QString installDir = QInstaller::generateTemporaryFileName();
+ QVERIFY(QDir().mkpath(installDir));
+ PackageManagerCore *core = PackageManager::getPackageManagerWithInit
+ (installDir, ":///data/repository");
+
+
+ core->installSelectedComponentsSilently(QStringList() << "C");
+
+ const QString settingsFileName = qApp->applicationDirPath() + "/oldTestSettings.ini";
+ QSettings testSettings(QDir(m_testSettingsDirPath).filePath(settingsFileName),
+ QSettings::IniFormat);
+
+ QCOMPARE(testSettings.value("testcategory/categoryarrayvalue1").toStringList(),
+ QStringList() << "valueFromScript");
+
+ QFile settingsFile(settingsFileName);
+ // Move the settings path to new location. Script has set values
+ // ComponentCSettingsPath (@InstallerDirPath@/newTestSettings.ini) and
+ // ComponentCSettingsPath_OLD (@InstallerDirPath@/oldTestSettings.ini) so
+ // UNDO operation should delete the moved newTestSettings.ini file instead.
+ QVERIFY2(settingsFile.rename(qApp->applicationDirPath() + "/newTestSettings.ini"), "Could not move settings file.");
+ core->commitSessionOperations();
+ core->setPackageManager();
+ core->uninstallComponentsSilently(QStringList() << "C");
+
+ // Settings file is removed in uninstall as it is empty
+ QVERIFY2(!QFile::exists(qApp->applicationDirPath() + "/newTestSettings.ini"), "Settings file not deleted correctly");
+
+ QDir dir(installDir);
+ QVERIFY(dir.removeRecursively());
+ core->deleteLater();
+ }
+
// called after all tests
void cleanupTestCase()
{
diff --git a/tests/auto/installer/solver/tst_solver.cpp b/tests/auto/installer/solver/tst_solver.cpp
index bdfc4d3df..ee05cc7f4 100644
--- a/tests/auto/installer/solver/tst_solver.cpp
+++ b/tests/auto/installer/solver/tst_solver.cpp
@@ -248,7 +248,6 @@ private slots:
{
QTest::addColumn<PackageManagerCore *>("core");
QTest::addColumn<QList<Component *> >("selectedToUninstall");
- QTest::addColumn<QList<Component *> >("installedComponents");
QTest::addColumn<QSet<Component *> >("expectedResult");
QTest::addColumn<UninstallReasonList >("uninstallReasons");
QTest::addColumn<LocalDependencyHash >("dependencyHash");
@@ -277,7 +276,6 @@ private slots:
uninstallReasonList.append(qMakePair(componentB, UninstallerCalculator::Dependent));
QTest::newRow("Uninstaller resolved") << core
<< (QList<Component *>() << componentAB)
- << (QList<Component *>() << componentA << componentB)
<< (QSet<Component *>() << componentAB << componentB)
<< uninstallReasonList
<< dependencyComponentHash;
@@ -303,7 +301,6 @@ private slots:
uninstallReasonList.append(qMakePair(compB, UninstallerCalculator::Dependent));
QTest::newRow("Cascade dependencies") << core
<< (QList<Component *>() << compA)
- << (QList<Component *>() << compB)
<< (QSet<Component *>() << compA << compB)
<< (uninstallReasonList)
<< dependencyComponentHash;
@@ -313,12 +310,11 @@ private slots:
{
QFETCH(PackageManagerCore *, core);
QFETCH(QList<Component *> , selectedToUninstall);
- QFETCH(QList<Component *> , installedComponents);
QFETCH(QSet<Component *> , expectedResult);
QFETCH(UninstallReasonList, uninstallReasons);
QFETCH(LocalDependencyHash, dependencyHash);
- UninstallerCalculator calc(installedComponents, core, QHash<QString, QStringList>(), dependencyHash, QStringList());
+ UninstallerCalculator calc(core, QHash<QString, QStringList>(), dependencyHash, QStringList());
calc.appendComponentsToUninstall(selectedToUninstall);
QSet<Component *> result = calc.componentsToUninstall();
for (auto pair : uninstallReasons) {