summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArttu Tarkiainen <arttu.tarkiainen@qt.io>2021-09-15 09:34:26 +0300
committerArttu Tarkiainen <arttu.tarkiainen@qt.io>2021-09-15 09:34:26 +0300
commitbd62988a9b0b3d5576210f599d45ba5bdd3243ad (patch)
treebaace2b83380710e23e250c3609bc7d58f89728a
parentfce4d500a0394d4d46235f77a5cbb8fd2b5a5e68 (diff)
parent41865907dae243fc5508ec4df35a98317cfb817c (diff)
Merge "Merge remote-tracking branch 'origin/4.1' into master"
-rw-r--r--doc/messageboxhandler.qdoc14
-rw-r--r--doc/scripting-api/component.qdoc24
-rw-r--r--doc/scripting-api/packagemanagercore.qdoc42
-rw-r--r--doc/scripting-api/qdesktopservices.qdoc4
-rw-r--r--examples/doc/systeminfo.qdoc6
-rw-r--r--src/libs/ifwtools/repositorygen.cpp1
-rw-r--r--src/libs/installer/component.cpp34
-rw-r--r--src/libs/installer/componentselectionpage_p.cpp4
-rw-r--r--src/libs/installer/metadatajob.cpp2
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp9
-rw-r--r--src/libs/installer/packagemanagergui.cpp11
-rw-r--r--src/libs/installer/protocol.cpp8
-rw-r--r--src/libs/installer/proxycredentialsdialog.cpp4
-rw-r--r--src/libs/installer/qtpatch.cpp14
-rw-r--r--src/libs/installer/repository.cpp3
-rw-r--r--tests/auto/tools/repotest/packages_new/C/data/C.txt2
-rw-r--r--tests/auto/tools/repotest/packages_new/C/meta/package.xml8
-rw-r--r--tests/auto/tools/repotest/settings.qrc2
-rw-r--r--tests/auto/tools/repotest/tst_repotest.cpp72
19 files changed, 169 insertions, 95 deletions
diff --git a/doc/messageboxhandler.qdoc b/doc/messageboxhandler.qdoc
index 259dfc490..30f0b2723 100644
--- a/doc/messageboxhandler.qdoc
+++ b/doc/messageboxhandler.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -79,26 +79,30 @@
\qmlmethod Button QMessageBox::critical(string identifier, string title, string text,
Buttons buttons = QMessageBox.Ok, Button button = QMessageBox.NoButton)
- Opens a critical message box with the given \a title and \a text.
+ Opens a critical message box with the parent \a parent, identifier \a identifier,
+ title \a title, and text \a text.
*/
/*!
\qmlmethod Button QMessageBox::information(string identifier, string title, string text,
Buttons buttons = QMessageBox.Ok, Button button = QMessageBox.NoButton)
- Opens an information message box with the given \a title and \a text.
+ Opens an information message box with the parent \a parent, identifier \a identifier,
+ title \a title, and text \a text.
*/
/*!
\qmlmethod Button QMessageBox::question(string identifier, string title, string text,
Buttons buttons = QMessageBox.Yes | QMessageBox.No, Button button = QMessageBox.NoButton)
- Opens a question message box with the given \a title and \a text.
+ Opens a question message box with the parent \a parent, identifier \a identifier,
+ title \a title, and text \a text.
*/
/*!
\qmlmethod Button QMessageBox::warning(string identifier, string title, string text,
Buttons buttons = QMessageBox.Ok, Button button = QMessageBox.NoButton)
- Opens a warning message box with the given \a title and \a text.
+ Opens a warning message box with the parent \a parent, identifier \a identifier,
+ title \a title, and text \a text.
*/
diff --git a/doc/scripting-api/component.qdoc b/doc/scripting-api/component.qdoc
index ffa2988a3..00480cd63 100644
--- a/doc/scripting-api/component.qdoc
+++ b/doc/scripting-api/component.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -172,7 +172,7 @@
*/
/*!
- \qmlmethod string component::value(string key, string value = "")
+ \qmlmethod string component::value(string key, string defaultValue = "")
Returns the value of variable name \a key. If \a key is not known yet, \a defaultValue is returned.
@@ -317,7 +317,7 @@
/*!
\qmlmethod boolean component::addOperation(string operation, stringlist parameters)
- Creates and adds an installation operation for \a operation. Add any number of parameters.
+ Creates and adds an installation operation for \a operation. Add any number of \a parameters.
The contents of the parameters get variables like "@TargetDir@" replaced with their values,
if contained.
@@ -328,18 +328,20 @@
\qmlmethod boolean component::addOperation(string operation, string parameter1 = "", string parameter2 = "", ..., string parameter10 = "")
Convenience method for calling addOperation(string, stringlist) with up to 10 arguments.
+ Creates and adds an installation operation for \a operation.
*/
/*!
\qmlmethod boolean component::addElevatedOperation(string operation, string parameter1 = "", string parameter2 = "", ..., string parameter10 = "")
Convenience method for calling addElevatedOperation(string, stringlist) with up to 10 arguments.
+ Creates and adds an installation operation for \a operation. The operation is executed with elevated rights.
*/
/*!
\qmlmethod boolean component::addElevatedOperation(string operation, stringlist parameters)
- Creates and adds an installation operation for \a operation. Add any number of parameters.
+ Creates and adds an installation operation for \a operation. Add any number of \a parameters.
The contents of the parameters get variables like "@TargetDir@" replaced with their values,
if contained. \a operation is executed with elevated rights.
*/
@@ -347,13 +349,15 @@
/*!
\qmlmethod void component::setAutoCreateOperations(boolean autoCreateOperations)
- Setter for the \l autoCreateOperations property.
+ Sets the value of \l autoCreateOperations property to \a autoCreateOperations.
*/
/*!
\qmlmethod void component::addDependency(string newDependency)
Adds a new component \a newDependency to the list of dependencies.
+ Alternatively, multiple components can be specified by separating each with
+ a comma.
\sa dependencies
*/
@@ -362,6 +366,8 @@
\qmlmethod void component::addAutoDependOn(string newDependOn)
Adds the component specified by \a newDependOn to the automatic depend-on list.
+ Alternatively, multiple components can be specified by separating each with
+ a comma.
\sa autoDependencies
*/
@@ -375,9 +381,9 @@
/*!
\qmlmethod boolean component::isAutoDependOn(QSet<string> componentsToInstall)
- Determines whether the component comes as an auto dependency. Returns \c true if the component needs
- to be installed.
-*/
+ Determines whether the component comes as an auto dependency. Returns \c true if all components
+ in \a componentsToInstall are already installed or selected for installation and this component
+ thus needs to be installed as well.
/*!
\qmlmethod boolean component::isDefault()
@@ -404,7 +410,7 @@
/*!
\qmlmethod void component::setUpdateAvailable(boolean isUpdateAvailable)
- Sets a flag that the core found an update.
+ Sets a flag that the core found an update based on the value of \a isUpdateAvailable.
*/
/*!
diff --git a/doc/scripting-api/packagemanagercore.qdoc b/doc/scripting-api/packagemanagercore.qdoc
index 918aed78d..e51b0ec17 100644
--- a/doc/scripting-api/packagemanagercore.qdoc
+++ b/doc/scripting-api/packagemanagercore.qdoc
@@ -70,7 +70,7 @@
/*!
\qmlsignal installer::componentAdded(Component component)
- Emitted when a new root component is added.
+ Emitted when a new root \a component is added.
\sa rootComponentsAdded(), updaterComponentsAdded()
*/
@@ -78,7 +78,7 @@
/*!
\qmlsignal installer::rootComponentsAdded(list<Component> components)
- Emitted when a new list of root components is added.
+ Emitted when a new list of root \a components is added.
\sa componentAdded(), updaterComponentsAdded()
*/
@@ -86,7 +86,7 @@
/*!
\qmlsignal installer::updaterComponentsAdded(list<Component> components)
- Emitted when a new list of updater components is added.
+ Emitted when a new list of updater \a components is added.
\sa componentAdded(), rootComponentsAdded()
*/
@@ -94,7 +94,7 @@
/*!
\qmlsignal installer::valueChanged(string key, string value)
- Emitted when a value changes.
+ Emitted when a \a value for \a key changes.
\sa setValue()
*/
@@ -102,13 +102,13 @@
/*!
\qmlsignal installer::statusChanged(Status status)
- Emitted when the installer status changes.
+ Emitted when the installer \a status changes.
*/
/*!
\qmlsignal installer::currentPageChanged(int page)
- Emitted when the current page changes.
+ Emitted when the current \a page changes.
*/
/*!
@@ -120,21 +120,21 @@
/*!
\qmlsignal installer::metaJobProgress(int progress)
- Triggered with progress updates of the communication with a remote
+ Triggered with \a progress updates of the communication with a remote
repository. Progress ranges from 0 to 100.
*/
/*!
\qmlsignal installer::metaJobTotalProgress(int progress)
- Triggered when total progress value of the communication with a
+ Triggered when total \a progress value of the communication with a
remote repository changes.
*/
/*!
\qmlsignal installer::metaJobInfoMessage(string message)
- Triggered with informative updates of the communication with a remote repository.
+ Triggered with informative updates, \a message, of the communication with a remote repository.
*/
/*!
@@ -148,7 +148,7 @@
/*!
\qmlsignal installer::finishAllComponentsReset(list<Component> rootComponents)
- Triggered when the list of new root components has been updated.
+ Triggered when the list of new root components \a rootComponents has been updated.
\sa startAllComponentsReset()
*/
@@ -162,7 +162,7 @@
/*!
\qmlsignal installer::finishUpdaterComponentsReset(list<Component> componentsWithUpdates)
- Triggered when the list of available remote updates has been updated.
+ Triggered when the list of available remote updates \a componentsWithUpdates has been updated.
*/
/*!
@@ -272,7 +272,9 @@
\qmlsignal installer::setValidatorForCustomPageRequested(Component component, string name,
string callbackName)
- Triggered when setValidatorForCustomPage is called.
+ Requests that a validator be set for the custom page specified by \a name and
+ \a callbackName for the component \a component. Triggered when
+ setValidatorForCustomPage() is called.
*/
/*!
@@ -406,7 +408,7 @@
/*!
\qmlmethod boolean installer::isFileExtensionRegistered(string extension)
- Returns whether a file extension is already registered in the Windows registry. Returns \c false
+ Returns whether a file \a extension is already registered in the Windows registry. Returns \c false
on all other platforms.
*/
@@ -484,6 +486,9 @@
\qmlmethod void installer::setValidatorForCustomPage(Component component, string name,
string callbackName)
+ Sets a validator for the custom page specified by \a name and \a callbackName
+ for the component \a component.
+
\sa setValidatorForCustomPageRequested()
*/
@@ -521,7 +526,8 @@
/*!
\qmlmethod void installer::setTemporaryRepositories(stringlist repositories, boolean replace)
- Sets additional \a repositories for this instance of the installer or updater.
+ Sets additional \a repositories for this instance of the installer or updater. If \a replace
+ is \c true, existing repositories will be replaced.
Will be removed after invoking it again.
\sa addUserRepositories()
@@ -613,13 +619,13 @@
/*!
\qmlmethod array installer::execute(string program, stringlist arguments = undefined,
- string stdin = "", string stdinCodec = "latin1",
- string stdoutCodec = "latin1")
+ string stdIn = "", string stdInCodec = "latin1",
+ string stdOutCodec = "latin1")
Starts the program \a program with the arguments \a arguments in a
new process and waits for it to finish.
- \a stdin is sent as standard input to the application.
+ \a stdIn is sent as standard input to the application.
\a stdInCodec is the name of the codec to use for converting the input string
into bytes to write to the standard input of the application.
@@ -704,7 +710,7 @@
\qmlmethod void installer::setInstallerBaseBinary(string path)
Sets the \c installerbase binary to use when writing the maintenance tool.
- Set the path if an update to the binary is available.
+ Set the \a path if an update to the binary is available.
If not set, the executable segment of the running installer or uninstaller
will be used.
diff --git a/doc/scripting-api/qdesktopservices.qdoc b/doc/scripting-api/qdesktopservices.qdoc
index 1b639f1e2..126e0b843 100644
--- a/doc/scripting-api/qdesktopservices.qdoc
+++ b/doc/scripting-api/qdesktopservices.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -104,6 +104,6 @@
\qmlmethod array QDesktopServices::findFiles(string path, string pattern)
Returns file names matching \a pattern. Searches the files recursively from \a path.
- \a Pattern understands * and ? wildcards.
+ The \a pattern understands * and ? wildcards.
*/
diff --git a/examples/doc/systeminfo.qdoc b/examples/doc/systeminfo.qdoc
index 32907ddc3..338cb8f77 100644
--- a/examples/doc/systeminfo.qdoc
+++ b/examples/doc/systeminfo.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -43,13 +43,13 @@
architecture.
The logic to detect the operating system features is scripted in the
- \c{root}'s \l{systeminfo/packages/root/meta/installscript.qs}{installscript.qs} file.
+ \c{root}'s \c{installscript.qs} file.
\quotefromfile systeminfo/packages/root/meta/installscript.qs
\section1 Helper Functions
- The \l{systeminfo/packages/root/meta/installscript.qs}{installscript.qs} file first
+ The \c{installscript.qs} file first
declares two helper functions: \c cancelInstaller() and \c majorVersion().
\skipto cancelInstaller
diff --git a/src/libs/ifwtools/repositorygen.cpp b/src/libs/ifwtools/repositorygen.cpp
index 98cd66768..a045c5248 100644
--- a/src/libs/ifwtools/repositorygen.cpp
+++ b/src/libs/ifwtools/repositorygen.cpp
@@ -840,6 +840,7 @@ QStringList QInstallerTools::unifyMetadata(const QString &repoDir, const QString
dir2.cd(existingRepoEntry);
const QString absPath = dir2.absolutePath();
absPaths.append(absPath);
+ dir2.cdUp();
}
}
}
diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp
index 22453833d..1a83291c1 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -45,6 +45,7 @@
#include <QtCore/QDirIterator>
#include <QtCore/QRegExp>
#include <QtCore/QTranslator>
+#include <QtCore/QRegularExpression>
#include <QApplication>
@@ -1310,6 +1311,8 @@ bool Component::validatePage()
/*!
Adds the component specified by \a newDependency to the list of dependencies.
+ Alternatively, multiple components can be specified by separating each with
+ a comma.
\sa {component::addDependency}{component.addDependency}
\sa dependencies
@@ -1331,6 +1334,8 @@ QStringList Component::dependencies() const
/*!
Adds the component specified by \a newDependOn to the automatic depend-on list.
+ Alternatively, multiple components can be specified by separating each with
+ a comma.
\sa {component::addAutoDependOn}{component.addAutoDependOn}
\sa autoDependencies
@@ -1640,26 +1645,23 @@ void Component::updateModelData(const QString &key, const QString &data)
setData(humanReadableSize(size), UncompressedSize);
}
+ QString tooltipText;
const QString &updateInfo = d->m_vars.value(scUpdateText);
if (!d->m_core->isUpdater() || updateInfo.isEmpty()) {
- QString tooltipText
- = QString::fromLatin1("<html><body>%1</body></html>").arg(d->m_vars.value(scDescription));
- if (isUnstable()) {
- tooltipText += QLatin1String("<br>") + tr("There was an error loading the selected component. "
- "This component cannot be installed.");
- }
- setData(tooltipText, Qt::ToolTipRole);
+ tooltipText = QString::fromLatin1("<html><body>%1</body></html>").arg(d->m_vars.value(scDescription));
} else {
- QString tooltipText
- = d->m_vars.value(scDescription) + QLatin1String("<br><br>")
- + tr("Update Info: ") + updateInfo;
- if (isUnstable()) {
- tooltipText += QLatin1String("<br>") + tr("There was an error loading the selected component. "
- "This component cannot be updated.");
- }
-
- setData(tooltipText, Qt::ToolTipRole);
+ tooltipText = d->m_vars.value(scDescription) + QLatin1String("<br><br>")
+ + tr("Update Info: ") + updateInfo;
}
+ if (isUnstable()) {
+ tooltipText += QLatin1String("<br>") + tr("There was an error loading the selected component. "
+ "This component cannot be installed.");
+ }
+ // replace {external-link}='' fields in component description with proper link tags
+ tooltipText.replace(QRegularExpression(QLatin1String("{external-link}='(.*?)'")),
+ QLatin1String("<a href=\"\\1\">\\1</a>"));
+
+ setData(tooltipText, Qt::ToolTipRole);
}
/*!
diff --git a/src/libs/installer/componentselectionpage_p.cpp b/src/libs/installer/componentselectionpage_p.cpp
index b35c93bc4..a180888d1 100644
--- a/src/libs/installer/componentselectionpage_p.cpp
+++ b/src/libs/installer/componentselectionpage_p.cpp
@@ -354,10 +354,6 @@ void ComponentSelectionPagePrivate::currentSelectedChanged(const QModelIndex &cu
QString description = m_currentModel->data(m_currentModel->index(current.row(),
ComponentModelHelper::NameColumn, current.parent()), Qt::ToolTipRole).toString();
- // replace {external-link}='' fields in component description with proper link tags
- description.replace(QRegularExpression(QLatin1String("{external-link}='(.*?)'")),
- QLatin1String("<a href=\"\\1\"><span style=\"color:#17a81a;\">\\1</span></a>"));
-
m_descriptionLabel->setText(description);
Component *component = m_currentModel->componentFromIndex(current);
diff --git a/src/libs/installer/metadatajob.cpp b/src/libs/installer/metadatajob.cpp
index 3408b3dab..68a242ebc 100644
--- a/src/libs/installer/metadatajob.cpp
+++ b/src/libs/installer/metadatajob.cpp
@@ -541,7 +541,9 @@ void MetadataJob::reset()
try {
m_xmlTask.cancel();
+ m_xmlTask.waitForFinished();
m_metadataTask.cancel();
+ m_metadataTask.waitForFinished();
} catch (...) {}
m_tempDirDeleter.releaseAndDeleteAll();
m_metadataResult.clear();
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index f323d676d..51c044356 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -923,8 +923,13 @@ void PackageManagerCorePrivate::readMaintenanceConfigFiles(const QString &target
const QVariantHash v = cfg.value(QLatin1String("Variables")).toHash(); // Do not change to
// QVariantMap! Breaks reading from existing .ini files, cause the variant types do not match.
for (QVariantHash::const_iterator it = v.constBegin(); it != v.constEnd(); ++it) {
- if (!m_data.contains(it.key()) || m_data.value(it.key()).isNull())
- m_data.setValue(it.key(), replacePath(it.value().toString(), QLatin1String(scRelocatable), targetDir));
+ if (m_data.contains(it.key()) && !m_data.value(it.key()).isNull()) {
+ // Exception: StartMenuDir should be permanent after initial installation
+ // and must be read from maintenancetool.ini
+ if (it.key() != scStartMenuDir)
+ continue;
+ }
+ m_data.setValue(it.key(), replacePath(it.value().toString(), QLatin1String(scRelocatable), targetDir));
}
QSet<Repository> repos;
const QVariantList variants = cfg.value(QLatin1String("DefaultRepositories"))
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index 7190795e0..67a2123af 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -2245,7 +2245,16 @@ bool ComponentSelectionPage::isComplete() const
{
if (packageManagerCore()->isInstaller() || packageManagerCore()->isUpdater())
return d->m_currentModel->checked().count();
- return d->m_currentModel->checkedState().testFlag(ComponentModel::DefaultChecked) == false;
+
+ if (d->m_currentModel->checkedState().testFlag(ComponentModel::DefaultChecked) == false)
+ return true;
+
+ const QSet<Component *> uncheckable = d->m_currentModel->uncheckable();
+ for (auto &component : uncheckable) {
+ if (component->forcedInstallation() && !component->isInstalled())
+ return true; // allow installation for new forced components
+ }
+ return false;
}
diff --git a/src/libs/installer/protocol.cpp b/src/libs/installer/protocol.cpp
index 3bafc481e..fb16086e5 100644
--- a/src/libs/installer/protocol.cpp
+++ b/src/libs/installer/protocol.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -35,19 +35,19 @@ typedef qint32 PackageSize;
/*!
\inmodule QtInstallerFramework
- \namespace Protocol
+ \namespace QInstaller::Protocol
\brief Contains values related to the internal client-server connection protocol.
*/
/*!
- \enum Protocol::Mode
+ \enum QInstaller::Protocol::Mode
\value Debug
\value Production
*/
/*!
- \enum Protocol::StartAs
+ \enum QInstaller::Protocol::StartAs
\value User
\value SuperUser
diff --git a/src/libs/installer/proxycredentialsdialog.cpp b/src/libs/installer/proxycredentialsdialog.cpp
index f536a05cd..2ac07b855 100644
--- a/src/libs/installer/proxycredentialsdialog.cpp
+++ b/src/libs/installer/proxycredentialsdialog.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -34,7 +34,7 @@ namespace QInstaller {
/*!
\inmodule QtInstallerFramework
- \namespace Ui
+ \namespace QInstaller::Ui
\brief Groups user interface forms generated with Qt Designer.
*/
diff --git a/src/libs/installer/qtpatch.cpp b/src/libs/installer/qtpatch.cpp
index 89b5dddf6..f72e67867 100644
--- a/src/libs/installer/qtpatch.cpp
+++ b/src/libs/installer/qtpatch.cpp
@@ -82,14 +82,16 @@ QHash<QString, QByteArray> QtPatch::qmakeValues(const QString &qmakePath, QByteA
process.start(qmake.absoluteFilePath(), args, QIODevice::ReadOnly);
if (process.waitForFinished(10000)) {
QByteArray output = process.readAllStandardOutput();
- qmakeOutput->append(output);
- if (process.exitStatus() == QProcess::CrashExit) {
- qCWarning(QInstaller::lcInstallerInstallLog) << qmake.absoluteFilePath() << args
- << "crashed with exit code" << process.exitCode()
- << "standard output:" << output
- << "error output:" << process.readAllStandardError();
+ if ((process.exitStatus() == QProcess::CrashExit) || (process.exitCode() != EXIT_SUCCESS)) {
+ QStringList detailedOutput = { qmake.absoluteFilePath() + QLatin1Char(' ') + args.join(QLatin1Char(' '))
+ + QString::fromLatin1(" returned with exit code: \"%1\".").arg(QString::number(process.exitCode()))
+ , QString::fromLatin1("Standard output: \"%1\".").arg(QLatin1String(output))
+ , QString::fromLatin1("Error output: \"%1\".").arg(QLatin1String(process.readAllStandardError()))
+ };
+ qmakeOutput->append(detailedOutput.join(QLatin1Char('\n')));
return qmakeValueHash;
}
+ qmakeOutput->append(output);
qmakeValueHash = readQmakeOutput(output);
}
if (qmakeValueHash.isEmpty()) {
diff --git a/src/libs/installer/repository.cpp b/src/libs/installer/repository.cpp
index e959d8550..50f3eceb6 100644
--- a/src/libs/installer/repository.cpp
+++ b/src/libs/installer/repository.cpp
@@ -32,6 +32,7 @@
#include <QDataStream>
#include <QFileInfo>
#include <QStringList>
+#include <QDir>
/*!
\fn inline uint QInstaller::qHash(const Repository &repository)
@@ -89,7 +90,7 @@ Repository::Repository(const QUrl &url, bool isDefault, bool compressed)
*/
Repository Repository::fromUserInput(const QString &repositoryUrl, bool compressed)
{
- QUrl url = QUrl::fromUserInput(repositoryUrl);
+ QUrl url = QUrl::fromUserInput(repositoryUrl, QDir::currentPath());
const QStringList supportedSchemes = KDUpdater::FileDownloaderFactory::supportedSchemes();
if (!supportedSchemes.contains(url.scheme()) && QFileInfo(url.toString()).exists())
url = QLatin1String("file:///") + url.toString();
diff --git a/tests/auto/tools/repotest/packages_new/C/data/C.txt b/tests/auto/tools/repotest/packages_new/C/data/C.txt
new file mode 100644
index 000000000..b45c73606
--- /dev/null
+++ b/tests/auto/tools/repotest/packages_new/C/data/C.txt
@@ -0,0 +1,2 @@
+Example content for package C.
+
diff --git a/tests/auto/tools/repotest/packages_new/C/meta/package.xml b/tests/auto/tools/repotest/packages_new/C/meta/package.xml
new file mode 100644
index 000000000..676f088be
--- /dev/null
+++ b/tests/auto/tools/repotest/packages_new/C/meta/package.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Package>
+ <DisplayName>C</DisplayName>
+ <Description>Example component C</Description>
+ <Version>1.0.0</Version>
+ <ReleaseDate>2020-01-01</ReleaseDate>
+ <Default>true</Default>
+</Package>
diff --git a/tests/auto/tools/repotest/settings.qrc b/tests/auto/tools/repotest/settings.qrc
index a0b5743fe..5c0d0055a 100644
--- a/tests/auto/tools/repotest/settings.qrc
+++ b/tests/auto/tools/repotest/settings.qrc
@@ -10,6 +10,8 @@
<file>packages_update/A/meta/script2.0.0.qs</file>
<file>packages_update/B/data/B_update.txt</file>
<file>packages_update/B/meta/package.xml</file>
+ <file>packages_new/C/data/C.txt</file>
+ <file>packages_new/C/meta/package.xml</file>
<file>repository_component/A/2.0.0content.7z</file>
<file>repository_component/A/2.0.0content.7z.sha1</file>
<file>repository_component/A/2.0.0meta.7z</file>
diff --git a/tests/auto/tools/repotest/tst_repotest.cpp b/tests/auto/tools/repotest/tst_repotest.cpp
index 9b8df947a..0868ae57e 100644
--- a/tests/auto/tools/repotest/tst_repotest.cpp
+++ b/tests/auto/tools/repotest/tst_repotest.cpp
@@ -57,9 +57,6 @@ private:
VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/B", QStringList() << "1.0.0content.7z"
<< "1.0.0content.7z.sha1");
}
- } else {
- QDir dir(m_repoInfo.repositoryDir + "/B");
- QVERIFY(!dir.exists());
}
QTemporaryDir tmp;
tmp.setAutoRemove(false);
@@ -144,14 +141,16 @@ private:
void ignoreMessagesForComponentHash(const QStringList &components, bool update)
{
+ QString packageDir = m_repoInfo.packages.first();
+ packageDir.remove("//"); // e.g. :///packages -> :/packages
foreach (const QString component, components) {
QString message = "Copying component data for \"%1\"";
QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(component)));
if (update)
- message = "Compressing files found in data directory: (\":/packages_update/%1/data/%1_update.txt\")";
+ message = "Compressing files found in data directory: (\"%1/%2/data/%2_update.txt\")";
else
- message = "Compressing files found in data directory: (\":/packages/%1/data/%1.txt\")";
- QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(component)));
+ message = "Compressing files found in data directory: (\"%1/%2/data/%2.txt\")";
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(packageDir, component)));
QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Hash is stored in *"));
QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Creating hash of archive *"));
QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Generated sha1 hash: *"));
@@ -183,19 +182,15 @@ private:
void ignoreMessagesForCopyMetadata(const QString &component, bool hasMeta, bool update)
{
- QString message;
- if (update)
- message = "Copy meta data for package \"%1\" using \":///packages_update/%1/meta/package.xml\"";
- else
- message = "Copy meta data for package \"%1\" using \":///packages/%1/meta/package.xml\"";
- QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(component)));
+ QString message = "Copy meta data for package \"%2\" using \"%1/%2/meta/package.xml\"";
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repoInfo.packages.first(), component)));
QTest::ignoreMessage(QtDebugMsg, QRegularExpression("calculate size of directory *"));
if (hasMeta) {
if (update)
- message = "Copying associated \"script\" file \":///packages_update/%1/meta/script2.0.0.qs\"";
+ message = "Copying associated \"script\" file \"%1/%2/meta/script2.0.0.qs\"";
else
- message = "Copying associated \"script\" file \":///packages/%1/meta/script1.0.0.qs\"";
- QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(component)));
+ message = "Copying associated \"script\" file \"%1/%2/meta/script1.0.0.qs\"";
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repoInfo.packages.first(), component)));
QTest::ignoreMessage(QtDebugMsg, "done.");
}
}
@@ -220,16 +215,26 @@ private:
QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Updating the metadata node with name *"));
}
- void ignoreMessageForCollectingPackages(const QString &versionA, const QString &versionB)
+ void ignoreMessageForCollectingPackages(const QString &versionA = QString(),
+ const QString &versionB = QString(), const QString &versionC = QString())
{
QTest::ignoreMessage(QtDebugMsg, "Collecting information about available repository packages...");
QTest::ignoreMessage(QtDebugMsg, "Collecting information about available packages...");
- QTest::ignoreMessage(QtDebugMsg, "Found subdirectory \"A\"");
- QString message = "- it provides the package \"A\" - \"%1\"";
- QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(versionA)));
- QTest::ignoreMessage(QtDebugMsg, "Found subdirectory \"B\"");
- message = "- it provides the package \"B\" - \"%1\"";
- QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(versionB)));
+ if (!versionA.isEmpty()) {
+ QTest::ignoreMessage(QtDebugMsg, "Found subdirectory \"A\"");
+ const QString message = "- it provides the package \"A\" - \"%1\"";
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(versionA)));
+ }
+ if (!versionB.isEmpty()) {
+ QTest::ignoreMessage(QtDebugMsg, "Found subdirectory \"B\"");
+ const QString message = "- it provides the package \"B\" - \"%1\"";
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(versionB)));
+ }
+ if (!versionC.isEmpty()) {
+ QTest::ignoreMessage(QtDebugMsg, "Found subdirectory \"C\"");
+ const QString message = "- it provides the package \"C\" - \"%1\"";
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(versionC)));
+ }
}
void ignoreMessageForCollectingPackagesFromRepository(const QString &versionA, const QString &versionB)
@@ -374,6 +379,29 @@ private slots:
verifyComponentMetaUpdatesXml();
}
+ void testUpdateComponentsFromPartialPackageDir()
+ {
+ ignoreMessagesForComponentSha(QStringList() << "A" << "B", false);
+ ignoreMessagesForUniteMeta(false);
+ generateRepo(true, true, false);
+ verifyComponentRepository("1.0.0", "1.0.0", true);
+
+ clearData();
+ m_repoInfo.packages << ":///packages_new";
+ { // ignore messages
+ ignoreMessagesForUniteMeta(false);
+ ignoreMessageForCollectingPackages(QString(), QString(), "1.0.0");
+ ignoreMessagesForComponentSha(QStringList() << "C", true);
+ ignoreMessagesForCopyMetadata("C", false, false);
+ ignoreMessagesForComponentHash(QStringList() << "C", false);
+ }
+ generateRepo(true, true, false);
+ verifyComponentRepository("1.0.0", "1.0.0", true);
+ VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/C",
+ QStringList() << "1.0.0content.7z" << "1.0.0content.7z.sha1" << "1.0.0meta.7z");
+ verifyUniteMetadata("1.0.0");
+ }
+
void testUpdateComponentsWithUniteMetadata()
{
ignoreMessagesForComponentSha(QStringList() << "A" << "B", false);