summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/installerfw.qdoc5
-rw-r--r--src/libs/ifwtools/repositorygen.cpp85
-rw-r--r--src/libs/ifwtools/repositorygen.h16
-rw-r--r--src/libs/installer/component.cpp2
-rw-r--r--src/libs/installer/component_p.cpp1
-rw-r--r--src/libs/installer/constants.h1
-rw-r--r--src/libs/installer/packagemanagercore.cpp10
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp18
-rw-r--r--src/libs/installer/packagemanagercore_p.h1
-rw-r--r--src/libs/installer/performinstallationform.cpp1
-rw-r--r--src/libs/kdtools/filedownloader.cpp2
-rw-r--r--src/libs/kdtools/localpackagehub.cpp8
-rw-r--r--src/libs/kdtools/localpackagehub.h4
-rw-r--r--src/libs/kdtools/selfrestarter.cpp1
-rw-r--r--src/libs/kdtools/updatefinder.cpp1
-rw-r--r--tests/auto/installer/contentshaupdate/contentshaupdate.pro9
-rw-r--r--tests/auto/installer/contentshaupdate/data/repository/Updates.xml48
-rw-r--r--tests/auto/installer/contentshaupdate/data/repository/componentA/1.0.0content.7zbin0 -> 243 bytes
-rw-r--r--tests/auto/installer/contentshaupdate/data/repository/componentB/1.0.0content.7zbin0 -> 243 bytes
-rw-r--r--tests/auto/installer/contentshaupdate/data/repository/componentC/1.0.0content.7zbin0 -> 243 bytes
-rw-r--r--tests/auto/installer/contentshaupdate/data/repository/componentD/1.0.0content.7zbin0 -> 243 bytes
-rw-r--r--tests/auto/installer/contentshaupdate/data/repositoryUpdate/Updates.xml48
-rw-r--r--tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentA/0.1.0content.7zbin0 -> 243 bytes
-rw-r--r--tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentB/0.1.0content.7zbin0 -> 243 bytes
-rw-r--r--tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentC/2.0.0content.7zbin0 -> 243 bytes
-rw-r--r--tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentD/2.0.0content.7zbin0 -> 243 bytes
-rw-r--r--tests/auto/installer/contentshaupdate/settings.qrc14
-rw-r--r--tests/auto/installer/contentshaupdate/tst_contentshaupdate.cpp108
-rw-r--r--tests/auto/installer/installer.pro3
-rw-r--r--tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp2
-rw-r--r--tests/auto/tools/repotest/tst_repotest.cpp169
-rw-r--r--tools/repogen/repogen.cpp92
32 files changed, 469 insertions, 180 deletions
diff --git a/doc/installerfw.qdoc b/doc/installerfw.qdoc
index e9a6463bc..4ae62eff6 100644
--- a/doc/installerfw.qdoc
+++ b/doc/installerfw.qdoc
@@ -1215,6 +1215,11 @@
\row
\li -v or --verbose
\li Display debug output.
+ \row
+ \li -s or --sha-update p1,...,pn
+ \li Comma-separated list of packages to be updated based on the component sha
+ checksum instead of the version number. This parameter adds a new \c <ContentSha1>
+ node to the \c Updates.xml.
\endtable
\note We recommend that you use the \c {--update-new-packages} parameter
to update an existing repository, especially if you have a content delivery
diff --git a/src/libs/ifwtools/repositorygen.cpp b/src/libs/ifwtools/repositorygen.cpp
index fbcf7b9f3..842d4f9cb 100644
--- a/src/libs/ifwtools/repositorygen.cpp
+++ b/src/libs/ifwtools/repositorygen.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2020 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.
@@ -52,6 +52,9 @@
#include <iostream>
+#define QUOTE_(x) #x
+#define QUOTE(x) QUOTE_(x)
+
using namespace QInstaller;
using namespace QInstallerTools;
@@ -69,6 +72,8 @@ void QInstallerTools::printRepositoryGenOptions()
std::cout << " --ignore-translations Do not use any translation" << std::endl;
std::cout << " --ignore-invalid-packages Ignore all invalid packages instead of aborting." << std::endl;
std::cout << " --ignore-invalid-repositories Ignore all invalid repositories instead of aborting." << std::endl;
+ std::cout << " -s|--sha-update p1,...,pn List of packages which are updated using" <<std::endl;
+ std::cout << " content sha1 instead of version number." << std::endl;
}
QString QInstallerTools::makePathAbsolute(const QString &path)
@@ -289,6 +294,11 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
fileElement.setAttribute(QLatin1String("OS"), QLatin1String("Any"));
update.appendChild(fileElement);
+ if (info.createContentSha1Node) {
+ QDomNode contentSha1Element = update.appendChild(doc.createElement(QLatin1String("ContentSha1")));
+ contentSha1Element.appendChild(doc.createTextNode(info.contentSha1));
+ }
+
root.appendChild(update);
// copy script file
@@ -414,7 +424,7 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
}
PackageInfoVector QInstallerTools::createListOfPackages(const QStringList &packagesDirectories,
- QStringList *packagesToFilter, FilterType filterType)
+ QStringList *packagesToFilter, FilterType filterType, QStringList packagesUpdatedWithSha)
{
qDebug() << "Collecting information about available packages...";
@@ -508,6 +518,13 @@ PackageInfoVector QInstallerTools::createListOfPackages(const QStringList &packa
info.dependencies = packageElement.firstChildElement(QLatin1String("Dependencies")).text()
.split(QInstaller::commaRegExp(), QString::SkipEmptyParts);
info.directory = it->filePath();
+ if (packagesUpdatedWithSha.contains(info.name)) {
+ info.createContentSha1Node = true;
+ packagesUpdatedWithSha.removeOne(info.name);
+ } else {
+ info.createContentSha1Node = false;
+ }
+
dict.push_back(info);
qDebug() << "- it provides the package" << info.name << " - " << info.version;
@@ -521,6 +538,11 @@ PackageInfoVector QInstallerTools::createListOfPackages(const QStringList &packa
if (dict.isEmpty())
qDebug() << "No available packages found at the specified location.";
+ if (!packagesUpdatedWithSha.isEmpty()) {
+ throw QInstaller::Error(QString::fromLatin1("The following packages could not be found in "
+ "package directory: %1").arg(packagesUpdatedWithSha.join(QLatin1String(", "))));
+ }
+
return dict;
}
@@ -902,6 +924,8 @@ void QInstallerTools::copyComponentData(const QStringList &packageDirs, const QS
archiveHashFile.write(hashOfArchiveData);
qDebug() << "Generated sha1 hash:" << hashOfArchiveData;
(*infos)[i].copiedFiles.append(archiveHashFile.fileName());
+ if ((*infos)[i].createContentSha1Node)
+ (*infos)[i].contentSha1 = QLatin1String(hashOfArchiveData);
archiveHashFile.close();
} catch (const QInstaller::Error &/*e*/) {
archiveFile.close();
@@ -987,3 +1011,60 @@ QString QInstallerTools::existingUniteMeta7z(const QString &repositoryDir)
}
return uniteMeta7z;
}
+
+PackageInfoVector QInstallerTools::collectPackages(RepositoryInfo info, QStringList *filteredPackages, FilterType filterType, bool updateNewComponents, QStringList packagesUpdatedWithSha)
+{
+ PackageInfoVector packages;
+ PackageInfoVector precompressedPackages = QInstallerTools::createListOfRepositoryPackages(info.repositoryPackages,
+ filteredPackages, filterType);
+ packages.append(precompressedPackages);
+
+ PackageInfoVector preparedPackages = QInstallerTools::createListOfPackages(info.packages,
+ filteredPackages, filterType, packagesUpdatedWithSha);
+ packages.append(preparedPackages);
+ if (updateNewComponents) {
+ filterNewComponents(info.repositoryDir, packages);
+ }
+ foreach (const QInstallerTools::PackageInfo &package, packages) {
+ const QFileInfo fi(info.repositoryDir, package.name);
+ if (fi.exists())
+ removeDirectory(fi.absoluteFilePath());
+ }
+ return packages;
+}
+
+void QInstallerTools::createRepository(RepositoryInfo info, PackageInfoVector *packages,
+ const QString &tmpMetaDir, bool createComponentMetadata, bool createUnifiedMetadata)
+{
+ QHash<QString, QString> pathToVersionMapping = QInstallerTools::buildPathToVersionMapping(*packages);
+
+ QStringList directories;
+ directories.append(info.packages);
+ directories.append(info.repositoryPackages);
+ QStringList unite7zFiles;
+ foreach (const QString &repositoryDirectory, info.repositoryPackages) {
+ QDirIterator it(repositoryDirectory, QStringList(QLatin1String("*_meta.7z"))
+ , QDir::Files | QDir::CaseSensitive);
+ while (it.hasNext()) {
+ it.next();
+ unite7zFiles.append(it.fileInfo().absoluteFilePath());
+ }
+ }
+ QInstallerTools::copyComponentData(directories, info.repositoryDir, packages);
+ QInstallerTools::copyMetaData(tmpMetaDir, info.repositoryDir, *packages, QLatin1String("{AnyApplication}"),
+ QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)), unite7zFiles);
+
+ QString existing7z = QInstallerTools::existingUniteMeta7z(info.repositoryDir);
+ if (!existing7z.isEmpty())
+ existing7z = info.repositoryDir + QDir::separator() + existing7z;
+ QInstallerTools::compressMetaDirectories(tmpMetaDir, existing7z, pathToVersionMapping,
+ createComponentMetadata, createUnifiedMetadata);
+
+ QDirIterator it(info.repositoryDir, QStringList(QLatin1String("Updates*.xml"))
+ << QLatin1String("*_meta.7z"), QDir::Files | QDir::CaseSensitive);
+ while (it.hasNext()) {
+ it.next();
+ QFile::remove(it.fileInfo().absoluteFilePath());
+ }
+ QInstaller::moveDirectoryContents(tmpMetaDir, info.repositoryDir);
+}
diff --git a/src/libs/ifwtools/repositorygen.h b/src/libs/ifwtools/repositorygen.h
index 49d0a51dd..0da81db67 100644
--- a/src/libs/ifwtools/repositorygen.h
+++ b/src/libs/ifwtools/repositorygen.h
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2020 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.
@@ -48,6 +48,8 @@ struct IFWTOOLS_EXPORT PackageInfo
QStringList copiedFiles;
QString metaFile;
QString metaNode;
+ QString contentSha1;
+ bool createContentSha1Node;
};
typedef QVector<PackageInfo> PackageInfoVector;
@@ -56,12 +58,19 @@ enum IFWTOOLS_EXPORT FilterType {
Exclude
};
+struct IFWTOOLS_EXPORT RepositoryInfo
+{
+ QStringList packages;
+ QStringList repositoryPackages;
+ QString repositoryDir;
+};
+
void IFWTOOLS_EXPORT printRepositoryGenOptions();
QString IFWTOOLS_EXPORT makePathAbsolute(const QString &path);
void IFWTOOLS_EXPORT copyWithException(const QString &source, const QString &target, const QString &kind = QString());
PackageInfoVector IFWTOOLS_EXPORT createListOfPackages(const QStringList &packagesDirectories, QStringList *packagesToFilter,
- FilterType ftype);
+ FilterType ftype, QStringList packagesUpdatedWithSha = QStringList());
PackageInfoVector IFWTOOLS_EXPORT createListOfRepositoryPackages(const QStringList &repositoryDirectories, QStringList *packagesToFilter,
FilterType filterType);
@@ -82,7 +91,8 @@ void IFWTOOLS_EXPORT copyComponentData(const QStringList &packageDir, const QStr
void IFWTOOLS_EXPORT filterNewComponents(const QString &repositoryDir, QInstallerTools::PackageInfoVector &packages);
QString IFWTOOLS_EXPORT existingUniteMeta7z(const QString &repositoryDir);
-
+PackageInfoVector IFWTOOLS_EXPORT collectPackages(RepositoryInfo info, QStringList *filteredPackages, FilterType filterType, bool updateNewComponents, QStringList packagesUpdatedWithSha);
+void IFWTOOLS_EXPORT createRepository(RepositoryInfo info, PackageInfoVector *packages, const QString &tmpMetaDir, bool createComponentMetadata, bool createUnifiedMetadata);
} // namespace QInstallerTools
#endif // REPOSITORYGEN_H
diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp
index 66f333377..c5d74cdfa 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -300,6 +300,7 @@ void Component::loadDataFromPackage(const KDUpdater::LocalPackage &package)
setValue(scCurrentState, scInstalled);
setValue(scCheckable, package.checkable ? scTrue : scFalse);
setValue(scExpandedByDefault, package.expandedByDefault ? scTrue : scFalse);
+ setValue(scContentSha1, package.contentSha1);
}
/*!
@@ -341,6 +342,7 @@ void Component::loadDataFromPackage(const Package &package)
if (PackageManagerCore::noForceInstallation())
forced = scFalse;
setValue(scForcedInstallation, forced);
+ setValue(scContentSha1, package.data(scContentSha1).toString());
setLocalTempPath(QInstaller::pathFromUrl(package.packageSource().url));
const QStringList uis = package.data(QLatin1String("UserInterfaces")).toString()
diff --git a/src/libs/installer/component_p.cpp b/src/libs/installer/component_p.cpp
index 8533d8e4c..0f74e423c 100644
--- a/src/libs/installer/component_p.cpp
+++ b/src/libs/installer/component_p.cpp
@@ -54,6 +54,7 @@ ComponentPrivate::ComponentPrivate(PackageManagerCore *core, Component *qq)
, m_autoCreateOperations(true)
, m_operationsCreatedSuccessfully(true)
, m_updateIsAvailable(false)
+ , m_unstable(false)
{
}
diff --git a/src/libs/installer/constants.h b/src/libs/installer/constants.h
index 42b14ce63..f1105941b 100644
--- a/src/libs/installer/constants.h
+++ b/src/libs/installer/constants.h
@@ -67,6 +67,7 @@ static const QLatin1String scUncompressedSizeSum("UncompressedSizeSum");
static const QLatin1String scRequiresAdminRights("RequiresAdminRights");
static const QLatin1String scOfflineBinaryName("OfflineBinaryName");
static const QLatin1String scSHA1("SHA1");
+static const QLatin1String scContentSha1("ContentSha1");
// constants used throughout the components class
static const QLatin1String scVirtual("Virtual");
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index ddfc0f832..5f7412c54 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -1556,9 +1556,8 @@ bool PackageManagerCore::fetchPackagesTree(const PackagesList &packages, const L
continue;
const LocalPackage localPackage = installedPackages.value(name);
- const QString updateVersion = update->data(scVersion).toString();
- if (KDUpdater::compareVersion(updateVersion, localPackage.version) <= 0)
- continue; // remote version equals or is less than the installed maintenance tool
+ if (!d->packageNeedsUpdate(localPackage, update))
+ continue;
const QDate updateDate = update->data(scReleaseDate).toDate();
if (localPackage.lastUpdateDate >= updateDate)
@@ -2330,6 +2329,7 @@ PackageManagerCore::Status PackageManagerCore::updateComponentsSilently(const QS
if (componentList.count() == 0) {
qCDebug(QInstaller::lcInstallerInstallLog) << "No updates available.";
+ setCanceled();
} else {
// Check if essential components are available (essential components are disabled).
// If essential components are found, update first essential updates,
@@ -3777,10 +3777,8 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
continue; // Update for not installed package found, skip it.
const LocalPackage &localPackage = locals.value(name);
- const QString updateVersion = update->data(scVersion).toString();
- if (KDUpdater::compareVersion(updateVersion, localPackage.version) <= 0)
+ if (!d->packageNeedsUpdate(localPackage, update))
continue;
-
// It is quite possible that we may have already installed the update. Lets check the last
// update date of the package and the release date of the update. This way we can compare and
// figure out if the update has been installed or not.
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index f4670c738..e6220ba35 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -2246,7 +2246,8 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr
component->value(scUncompressedSize).toULongLong(),
component->value(scInheritVersion),
component->isCheckable(),
- component->isExpandedByDefault());
+ component->isExpandedByDefault(),
+ component->value(scContentSha1));
m_localPackageHub->writeToDisk();
component->setInstalled();
@@ -2898,4 +2899,19 @@ bool PackageManagerCorePrivate::askUserConfirmCommand() const
}
}
+bool PackageManagerCorePrivate::packageNeedsUpdate(const LocalPackage &localPackage, const Package *update) const
+{
+ bool updateNeeded = true;
+ const QString contentSha1 = update->data(scContentSha1).toString();
+ if (!contentSha1.isEmpty()) {
+ if (contentSha1 == localPackage.contentSha1)
+ updateNeeded = false;
+ } else {
+ const QString updateVersion = update->data(scVersion).toString();
+ if (KDUpdater::compareVersion(updateVersion, localPackage.version) <= 0)
+ updateNeeded = false;
+ }
+ return updateNeeded;
+}
+
} // namespace QInstaller
diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h
index 858baf9eb..4d5021471 100644
--- a/src/libs/installer/packagemanagercore_p.h
+++ b/src/libs/installer/packagemanagercore_p.h
@@ -254,6 +254,7 @@ private:
bool acceptLicenseAgreements() const;
bool askUserAcceptLicense(const QString &name, const QString &content) const;
bool askUserConfirmCommand() const;
+ bool packageNeedsUpdate(const LocalPackage &localPackage, const Package *update) const;
private:
PackageManagerCore *m_core;
diff --git a/src/libs/installer/performinstallationform.cpp b/src/libs/installer/performinstallationform.cpp
index 2fb6026cc..31b61ceeb 100644
--- a/src/libs/installer/performinstallationform.cpp
+++ b/src/libs/installer/performinstallationform.cpp
@@ -80,6 +80,7 @@ PerformInstallationForm::PerformInstallationForm(QObject *parent)
: QObject(parent)
, m_progressBar(nullptr)
, m_progressLabel(nullptr)
+ , m_downloadStatus(nullptr)
, m_productImagesScrollArea(nullptr)
, m_productImagesLabel(nullptr)
, m_detailsButton(nullptr)
diff --git a/src/libs/kdtools/filedownloader.cpp b/src/libs/kdtools/filedownloader.cpp
index 4cccfd9ca..a9f5040f0 100644
--- a/src/libs/kdtools/filedownloader.cpp
+++ b/src/libs/kdtools/filedownloader.cpp
@@ -192,6 +192,7 @@ struct KDUpdater::FileDownloader::Private
: m_hash(QCryptographicHash::Sha1)
, m_assumedSha1Sum("")
, autoRemove(true)
+ , followRedirect(false)
, m_speedTimerInterval(100)
, m_downloadDeadlineTimerInterval(30000)
, m_downloadPaused(false)
@@ -255,7 +256,6 @@ KDUpdater::FileDownloader::FileDownloader(const QString &scheme, QObject *parent
, d(new Private)
{
d->scheme = scheme;
- d->followRedirect = false;
}
/*!
diff --git a/src/libs/kdtools/localpackagehub.cpp b/src/libs/kdtools/localpackagehub.cpp
index 1a754d7d5..2ee880e04 100644
--- a/src/libs/kdtools/localpackagehub.cpp
+++ b/src/libs/kdtools/localpackagehub.cpp
@@ -327,7 +327,8 @@ void LocalPackageHub::addPackage(const QString &name,
quint64 uncompressedSize,
const QString &inheritVersionFrom,
bool checkable,
- bool expandedByDefault)
+ bool expandedByDefault,
+ const QString &contentSha1)
{
// TODO: This somewhat unexpected, remove?
if (d->m_packageInfoMap.contains(name)) {
@@ -350,6 +351,7 @@ void LocalPackageHub::addPackage(const QString &name,
info.uncompressedSize = uncompressedSize;
info.checkable = checkable;
info.expandedByDefault = expandedByDefault;
+ info.contentSha1 = contentSha1;
d->m_packageInfoMap.insert(name, info);
}
d->modified = true;
@@ -426,6 +428,8 @@ void LocalPackageHub::writeToDisk()
addTextChildHelper(&package, QLatin1String("Checkable"), QLatin1String("true"));
if (info.expandedByDefault)
addTextChildHelper(&package, QLatin1String("ExpandedByDefault"), QLatin1String("true"));
+ if (!info.contentSha1.isEmpty())
+ addTextChildHelper(&package, scContentSha1, info.contentSha1);
root.appendChild(package);
}
@@ -498,6 +502,8 @@ void LocalPackageHub::PackagesInfoData::addPackageFrom(const QDomElement &packag
info.checkable = childNodeE.text().toLower() == QLatin1String("true") ? true : false;
else if (childNodeE.tagName() == QLatin1String("ExpandedByDefault"))
info.expandedByDefault = childNodeE.text().toLower() == QLatin1String("true") ? true : false;
+ else if (childNodeE.tagName() == QLatin1String("ContentSha1"))
+ info.contentSha1 = childNodeE.text();
}
m_packageInfoMap.insert(info.name, info);
}
diff --git a/src/libs/kdtools/localpackagehub.h b/src/libs/kdtools/localpackagehub.h
index d43c4a6a5..648d6cf6e 100644
--- a/src/libs/kdtools/localpackagehub.h
+++ b/src/libs/kdtools/localpackagehub.h
@@ -55,6 +55,7 @@ struct KDTOOLS_EXPORT LocalPackage
quint64 uncompressedSize;
bool checkable;
bool expandedByDefault;
+ QString contentSha1;
};
class KDTOOLS_EXPORT LocalPackageHub
@@ -108,7 +109,8 @@ public:
quint64 uncompressedSize,
const QString &inheritVersionFrom,
bool checkable,
- bool expandedByDefault);
+ bool expandedByDefault,
+ const QString &contentSha1);
bool removePackage(const QString &pkgName);
void refresh();
diff --git a/src/libs/kdtools/selfrestarter.cpp b/src/libs/kdtools/selfrestarter.cpp
index e94d0fea7..7326ac070 100644
--- a/src/libs/kdtools/selfrestarter.cpp
+++ b/src/libs/kdtools/selfrestarter.cpp
@@ -45,6 +45,7 @@ public:
}
Private()
+ : restartOnQuit(false)
{
executable = qApp->applicationFilePath();
workingPath = QDir::currentPath();
diff --git a/src/libs/kdtools/updatefinder.cpp b/src/libs/kdtools/updatefinder.cpp
index 535dfde3d..3403430fe 100644
--- a/src/libs/kdtools/updatefinder.cpp
+++ b/src/libs/kdtools/updatefinder.cpp
@@ -81,6 +81,7 @@ public:
Private(UpdateFinder *qq)
: q(qq)
+ , cancel(false)
, downloadCompleteCount(0)
, m_downloadsToComplete(0)
{}
diff --git a/tests/auto/installer/contentshaupdate/contentshaupdate.pro b/tests/auto/installer/contentshaupdate/contentshaupdate.pro
new file mode 100644
index 000000000..84402794f
--- /dev/null
+++ b/tests/auto/installer/contentshaupdate/contentshaupdate.pro
@@ -0,0 +1,9 @@
+include(../../qttest.pri)
+
+QT += qml
+
+SOURCES += tst_contentshaupdate.cpp
+
+RESOURCES += \
+ settings.qrc \
+ ..\shared\config.qrc
diff --git a/tests/auto/installer/contentshaupdate/data/repository/Updates.xml b/tests/auto/installer/contentshaupdate/data/repository/Updates.xml
new file mode 100644
index 000000000..a83d41384
--- /dev/null
+++ b/tests/auto/installer/contentshaupdate/data/repository/Updates.xml
@@ -0,0 +1,48 @@
+<Updates>
+ <ApplicationName>{AnyApplication}</ApplicationName>
+ <ApplicationVersion>1.0.0</ApplicationVersion>
+ <Checksum>false</Checksum>
+ <PackageUpdate>
+ <Name>componentA</Name>
+ <DisplayName>Component A</DisplayName>
+ <Description>This component does not depend on any other component.</Description>
+ <Version>1.0.0</Version>
+ <ReleaseDate>2014-08-25</ReleaseDate>
+ <SortingPriority>100</SortingPriority>
+ <UpdateFile OS="Any" CompressedSize="283" UncompressedSize="101"/>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ <ContentSha1>10</ContentSha1>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentB</Name>
+ <DisplayName>Component B</DisplayName>
+ <Description>This component does not depend on any other component.</Description>
+ <Version>1.0.0</Version>
+ <ReleaseDate>2014-08-25</ReleaseDate>
+ <SortingPriority>90</SortingPriority>
+ <UpdateFile OS="Any" CompressedSize="283" UncompressedSize="101"/>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentC</Name>
+ <DisplayName>Component C</DisplayName>
+ <Description>Component C</Description>
+ <Version>1.0.0</Version>
+ <ReleaseDate>2014-08-25</ReleaseDate>
+ <SortingPriority>80</SortingPriority>
+ <UpdateFile OS="Any" CompressedSize="283" UncompressedSize="101"/>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ <ContentSha1>10</ContentSha1>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentD</Name>
+ <DisplayName>Component D</DisplayName>
+ <Description>Component D</Description>
+ <Version>1.0.0</Version>
+ <ReleaseDate>2014-08-25</ReleaseDate>
+ <SortingPriority>80</SortingPriority>
+ <UpdateFile CompressedSize="283" UncompressedSize="101" OS="Any"/>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ <ContentSha1>10</ContentSha1>
+ </PackageUpdate>
+</Updates>
diff --git a/tests/auto/installer/contentshaupdate/data/repository/componentA/1.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repository/componentA/1.0.0content.7z
new file mode 100644
index 000000000..46a9f1d1e
--- /dev/null
+++ b/tests/auto/installer/contentshaupdate/data/repository/componentA/1.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/contentshaupdate/data/repository/componentB/1.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repository/componentB/1.0.0content.7z
new file mode 100644
index 000000000..5f1fb2e1b
--- /dev/null
+++ b/tests/auto/installer/contentshaupdate/data/repository/componentB/1.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/contentshaupdate/data/repository/componentC/1.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repository/componentC/1.0.0content.7z
new file mode 100644
index 000000000..83e82b5a3
--- /dev/null
+++ b/tests/auto/installer/contentshaupdate/data/repository/componentC/1.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/contentshaupdate/data/repository/componentD/1.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repository/componentD/1.0.0content.7z
new file mode 100644
index 000000000..da50742a4
--- /dev/null
+++ b/tests/auto/installer/contentshaupdate/data/repository/componentD/1.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/contentshaupdate/data/repositoryUpdate/Updates.xml b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/Updates.xml
new file mode 100644
index 000000000..87017cf91
--- /dev/null
+++ b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/Updates.xml
@@ -0,0 +1,48 @@
+<Updates>
+ <ApplicationName>{AnyApplication}</ApplicationName>
+ <ApplicationVersion>1.0.0</ApplicationVersion>
+ <Checksum>false</Checksum>
+ <PackageUpdate>
+ <Name>componentA</Name>
+ <DisplayName>Component A</DisplayName>
+ <Description>Component A.</Description>
+ <Version>0.1.0</Version>
+ <ReleaseDate>2014-08-25</ReleaseDate>
+ <SortingPriority>100</SortingPriority>
+ <UpdateFile CompressedSize="283" UncompressedSize="101" OS="Any"/>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ <ContentSha1>5</ContentSha1>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentB</Name>
+ <DisplayName>Component B</DisplayName>
+ <Description>Component B.</Description>
+ <Version>0.1.0</Version>
+ <ReleaseDate>2014-08-25</ReleaseDate>
+ <SortingPriority>90</SortingPriority>
+ <UpdateFile CompressedSize="283" UncompressedSize="101" OS="Any"/>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ <ContentSha1>10</ContentSha1>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentC</Name>
+ <DisplayName>Component C</DisplayName>
+ <Description>Component C</Description>
+ <Version>2.0.0</Version>
+ <ReleaseDate>2014-08-25</ReleaseDate>
+ <SortingPriority>80</SortingPriority>
+ <UpdateFile CompressedSize="283" UncompressedSize="101" OS="Any"/>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ <ContentSha1>10</ContentSha1>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentD</Name>
+ <DisplayName>Component D</DisplayName>
+ <Description>Component D</Description>
+ <Version>2.0.0</Version>
+ <ReleaseDate>2014-08-25</ReleaseDate>
+ <SortingPriority>80</SortingPriority>
+ <UpdateFile UncompressedSize="101" CompressedSize="283" OS="Any"/>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ </PackageUpdate>
+</Updates>
diff --git a/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentA/0.1.0content.7z b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentA/0.1.0content.7z
new file mode 100644
index 000000000..bdbabc7fd
--- /dev/null
+++ b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentA/0.1.0content.7z
Binary files differ
diff --git a/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentB/0.1.0content.7z b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentB/0.1.0content.7z
new file mode 100644
index 000000000..1c1129b9f
--- /dev/null
+++ b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentB/0.1.0content.7z
Binary files differ
diff --git a/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentC/2.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentC/2.0.0content.7z
new file mode 100644
index 000000000..7f75bf503
--- /dev/null
+++ b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentC/2.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentD/2.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentD/2.0.0content.7z
new file mode 100644
index 000000000..4207dfbf2
--- /dev/null
+++ b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentD/2.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/contentshaupdate/settings.qrc b/tests/auto/installer/contentshaupdate/settings.qrc
new file mode 100644
index 000000000..a5d045f46
--- /dev/null
+++ b/tests/auto/installer/contentshaupdate/settings.qrc
@@ -0,0 +1,14 @@
+<RCC>
+ <qresource prefix="/">
+ <file>data/repository/Updates.xml</file>
+ <file>data/repository/componentA/1.0.0content.7z</file>
+ <file>data/repository/componentB/1.0.0content.7z</file>
+ <file>data/repository/componentC/1.0.0content.7z</file>
+ <file>data/repository/componentD/1.0.0content.7z</file>
+ <file>data/repositoryUpdate/Updates.xml</file>
+ <file>data/repositoryUpdate/componentA/0.1.0content.7z</file>
+ <file>data/repositoryUpdate/componentB/0.1.0content.7z</file>
+ <file>data/repositoryUpdate/componentC/2.0.0content.7z</file>
+ <file>data/repositoryUpdate/componentD/2.0.0content.7z</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/installer/contentshaupdate/tst_contentshaupdate.cpp b/tests/auto/installer/contentshaupdate/tst_contentshaupdate.cpp
new file mode 100644
index 000000000..d8d2f5377
--- /dev/null
+++ b/tests/auto/installer/contentshaupdate/tst_contentshaupdate.cpp
@@ -0,0 +1,108 @@
+/**************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#include "../shared/packagemanager.h"
+#include "../shared/verifyinstaller.h"
+
+#include <QTest>
+
+using namespace QInstaller;
+
+class tst_ContentSha1Update : public QObject
+{
+ Q_OBJECT
+
+private:
+ void setRepository(const QString &repository)
+ {
+ core->reset();
+ core->cancelMetaInfoJob(); //Call cancel to reset metadata so that update repositories are fetched
+
+ QSet<Repository> repoList;
+ Repository repo = Repository::fromUserInput(repository);
+ repoList.insert(repo);
+ core->settings().setDefaultRepositories(repoList);
+ }
+
+private slots:
+ void initTestCase()
+ {
+ m_installDir = QInstaller::generateTemporaryFileName();
+ core = PackageManager::getPackageManagerWithInit(m_installDir);
+ }
+
+ void updateWithContentSha1_data()
+ {
+ QTest::addColumn<QString>("component");
+ QTest::addColumn<QString>("content");
+ QTest::addColumn<QString>("updatedContent");
+ QTest::addColumn<PackageManagerCore::Status>("expectedStatusAfterInstall");
+ QTest::addColumn<PackageManagerCore::Status>("expectedStatusAfterUpdate");
+
+ QTest::newRow("ContentSha1Change") << "componentA" << "1.0.0content.txt" << "0.1.0content.txt" << PackageManagerCore::Success << PackageManagerCore::Success;
+ QTest::newRow("NewContentSha1") << "componentB" << "1.0.0content.txt" << "0.1.0content.txt" << PackageManagerCore::Success << PackageManagerCore::Success;
+ QTest::newRow("SameContentSha1") << "componentC" << "1.0.0content.txt" << "1.0.0content.txt" << PackageManagerCore::Success << PackageManagerCore::Canceled;
+ QTest::newRow("Sha1RemovedFromRepo") << "componentD" << "1.0.0content.txt" << "2.0.0content.txt" << PackageManagerCore::Success << PackageManagerCore::Success;
+ }
+
+ void updateWithContentSha1()
+ {
+ QFETCH(QString, component);
+ QFETCH(QString, content);
+ QFETCH(QString, updatedContent);
+ QFETCH(PackageManagerCore::Status, expectedStatusAfterInstall);
+ QFETCH(PackageManagerCore::Status, expectedStatusAfterUpdate);
+
+ setRepository(":///data/repository");
+ QCOMPARE(expectedStatusAfterInstall, core->installSelectedComponentsSilently(QStringList() << component));
+ QCOMPARE(expectedStatusAfterInstall, core->status());
+ VerifyInstaller::verifyInstallerResources(m_installDir, component, content);
+
+ core->commitSessionOperations();
+ core->setPackageManager();
+ setRepository(":///data/repositoryUpdate");
+ QCOMPARE(expectedStatusAfterUpdate, core->updateComponentsSilently(QStringList()));
+ VerifyInstaller::verifyInstallerResources(m_installDir, component, updatedContent);
+ }
+
+ void cleanupTestCase()
+ {
+ QDir dir(m_installDir);
+ QVERIFY(dir.removeRecursively());
+ delete core;
+ }
+
+private:
+ QString m_installDir;
+ PackageManagerCore *core;
+};
+
+
+QTEST_MAIN(tst_ContentSha1Update)
+
+#include "tst_contentshaupdate.moc"
diff --git a/tests/auto/installer/installer.pro b/tests/auto/installer/installer.pro
index 114c43d7a..cb0438ab3 100644
--- a/tests/auto/installer/installer.pro
+++ b/tests/auto/installer/installer.pro
@@ -39,7 +39,8 @@ SUBDIRS += \
globalsettingsoperation \
elevatedexecuteoperation \
treename \
- createoffline
+ createoffline \
+ contentshaupdate
win32 {
SUBDIRS += registerfiletypeoperation \
diff --git a/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp b/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp
index ae2c3b211..17343e49d 100644
--- a/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp
+++ b/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp
@@ -306,7 +306,7 @@ private slots:
QTest::ignoreMessage(QtWarningMsg, re);
QTest::ignoreMessage(QtDebugMsg, "No updates available.");
- QCOMPARE(PackageManagerCore::Failure, core.updateComponentsSilently(QStringList()));
+ QCOMPARE(PackageManagerCore::Canceled, core.updateComponentsSilently(QStringList()));
QVERIFY(QDir().rmdir(testDirectory));
}
diff --git a/tests/auto/tools/repotest/tst_repotest.cpp b/tests/auto/tools/repotest/tst_repotest.cpp
index 5aa614454..228c13c80 100644
--- a/tests/auto/tools/repotest/tst_repotest.cpp
+++ b/tests/auto/tools/repotest/tst_repotest.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2020 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.
@@ -39,114 +39,63 @@ class tst_repotest : public QObject
{
Q_OBJECT
private:
- // TODO generateRepo() is almost direct copy from repogen.cpp.
- // Move the needed parts of repogen.cpp to a usable function for easier maintenance.
- void generateRepo(bool createSplitMetadata, bool createUnifiedMetadata, bool updateNewComponents)
+ void generateRepo(bool createSplitMetadata, bool createUnifiedMetadata, bool updateNewComponents,
+ QStringList packagesUpdatedWithSha = QStringList())
{
QStringList filteredPackages;
- QInstallerTools::FilterType filterType = QInstallerTools::Exclude;
- QInstallerTools::PackageInfoVector precompressedPackages = QInstallerTools::createListOfRepositoryPackages
- (m_repositoryDirectories, &filteredPackages, filterType);
- m_packages.append(precompressedPackages);
-
- QInstallerTools::PackageInfoVector preparedPackages = QInstallerTools::createListOfPackages(m_packagesDirectories,
- &filteredPackages, filterType);
- m_packages.append(preparedPackages);
-
- if (updateNewComponents)
- QInstallerTools::filterNewComponents(m_repositoryDir, m_packages);
- QHash<QString, QString> pathToVersionMapping = QInstallerTools::buildPathToVersionMapping(m_packages);
-
- foreach (const QInstallerTools::PackageInfo &package, m_packages) {
- const QFileInfo fi(m_repositoryDir, package.name);
- if (fi.exists())
- removeDirectory(fi.absoluteFilePath());
- }
+ QInstallerTools::PackageInfoVector m_packages = QInstallerTools::collectPackages(m_repoInfo,
+ &filteredPackages, QInstallerTools::Exclude, updateNewComponents, packagesUpdatedWithSha);
if (updateNewComponents) { //Verify that component B exists as that is not updated
if (createSplitMetadata) {
- VerifyInstaller::verifyFileExistence(m_repositoryDir + "/B", QStringList() << "1.0.0content.7z"
+ VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/B", QStringList() << "1.0.0content.7z"
<< "1.0.0content.7z.sha1" << "1.0.0meta.7z");
} else {
- VerifyInstaller::verifyFileExistence(m_repositoryDir + "/B", QStringList() << "1.0.0content.7z"
+ VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/B", QStringList() << "1.0.0content.7z"
<< "1.0.0content.7z.sha1");
}
} else {
- QDir dir(m_repositoryDir + "/B");
+ QDir dir(m_repoInfo.repositoryDir + "/B");
QVERIFY(!dir.exists());
}
- QStringList directories;
- directories.append(m_packagesDirectories);
- directories.append(m_repositoryDirectories);
-
- QStringList unite7zFiles;
- foreach (const QString &repositoryDirectory, m_repositoryDirectories) {
- QDirIterator it(repositoryDirectory, QStringList(QLatin1String("*_meta.7z"))
- , QDir::Files | QDir::CaseSensitive);
- while (it.hasNext()) {
- it.next();
- unite7zFiles.append(it.fileInfo().absoluteFilePath());
- }
- }
-
- QInstallerTools::copyComponentData(directories, m_repositoryDir, &m_packages);
- QInstallerTools::copyMetaData(m_tmpMetaDir, m_repositoryDir, m_packages, QLatin1String("{AnyApplication}"),
- QLatin1String("1.0.0"), unite7zFiles);
- QString existing7z = QInstallerTools::existingUniteMeta7z(m_repositoryDir);
- if (!existing7z.isEmpty())
- existing7z = m_repositoryDir + QDir::separator() + existing7z;
- QInstallerTools::compressMetaDirectories(m_tmpMetaDir, existing7z, pathToVersionMapping,
- createSplitMetadata, createUnifiedMetadata);
- QDirIterator it(m_repositoryDir, QStringList(QLatin1String("Updates*.xml"))
- << QLatin1String("*_meta.7z"), QDir::Files | QDir::CaseSensitive);
- while (it.hasNext()) {
- it.next();
- QFile::remove(it.fileInfo().absoluteFilePath());
- }
- QInstaller::moveDirectoryContents(m_tmpMetaDir, m_repositoryDir);
- }
-
- void generateTempMetaDir()
- {
- if (!m_tmpMetaDir.isEmpty())
- m_tempDirDeleter.releaseAndDelete(m_tmpMetaDir);
QTemporaryDir tmp;
tmp.setAutoRemove(false);
- m_tmpMetaDir = tmp.path();
- m_tempDirDeleter.add(m_tmpMetaDir);
+ const QString tmpMetaDir = tmp.path();
+ QInstallerTools::createRepository(m_repoInfo, &m_packages, tmpMetaDir, createSplitMetadata,
+ createUnifiedMetadata);
+ QInstaller::removeDirectory(tmpMetaDir, true);
}
void clearData()
{
- generateTempMetaDir();
- m_packagesDirectories.clear();
- m_repositoryDirectories.clear();
+ m_repoInfo.packages.clear();
+ m_repoInfo.repositoryPackages.clear();
m_packages.clear();
}
void initRepoUpdate()
{
clearData();
- m_packagesDirectories << ":///packages_update";
+ m_repoInfo.packages << ":///packages_update";
}
void initRepoUpdateFromRepository(const QString &repository)
{
clearData();
- m_repositoryDirectories << repository;
+ m_repoInfo.repositoryPackages << repository;
}
void verifyUniteMetadata(const QString &scriptVersion)
{
- QString fileContent = VerifyInstaller::fileContent(m_repositoryDir + QDir::separator()
+ QString fileContent = VerifyInstaller::fileContent(m_repoInfo.repositoryDir + QDir::separator()
+ "Updates.xml");
QRegularExpression re("<MetadataName>(.*)<.MetadataName>");
QStringList matches = re.match(fileContent).capturedTexts();
- QString existingUniteMeta7z = QInstallerTools::existingUniteMeta7z(m_repositoryDir);
+ QString existingUniteMeta7z = QInstallerTools::existingUniteMeta7z(m_repoInfo.repositoryDir);
QCOMPARE(2, matches.count());
QCOMPARE(existingUniteMeta7z, matches.at(1));
- QFile file(m_repositoryDir + QDir::separator() + matches.at(1));
+ QFile file(m_repoInfo.repositoryDir + QDir::separator() + matches.at(1));
QVERIFY(file.open(QIODevice::ReadOnly));
//We have script<version>.qs for package A in the unite metadata
@@ -159,35 +108,35 @@ private:
QCOMPARE(qPrintable(fileName.arg(scriptVersion)), fileIt->path);
}
- VerifyInstaller::verifyFileExistence(m_repositoryDir, QStringList() << "Updates.xml"
+ VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir, QStringList() << "Updates.xml"
<< matches.at(1));
- VerifyInstaller::verifyFileContent(m_repositoryDir + QDir::separator() + "Updates.xml",
+ VerifyInstaller::verifyFileContent(m_repoInfo.repositoryDir + QDir::separator() + "Updates.xml",
"SHA1");
- VerifyInstaller::verifyFileContent(m_repositoryDir + QDir::separator() + "Updates.xml",
+ VerifyInstaller::verifyFileContent(m_repoInfo.repositoryDir + QDir::separator() + "Updates.xml",
"MetadataName");
}
void verifyComponentRepository(const QString &componentAVersion, bool hasComponentMeta)
{
const QString content = "%1content.7z";
- const QString contentSha = "%1content.7z.sha1";
+ const QString contentSha1 = "%1content.7z.sha1";
const QString meta = "%1meta.7z";
QStringList componentA;
QStringList componentB;
- componentA << qPrintable(content.arg(componentAVersion)) << qPrintable(contentSha.arg(componentAVersion));
+ componentA << qPrintable(content.arg(componentAVersion)) << qPrintable(contentSha1.arg(componentAVersion));
componentB << "1.0.0content.7z" << "1.0.0content.7z.sha1";
if (hasComponentMeta) {
componentA << qPrintable(meta.arg(componentAVersion));
componentB << "1.0.0meta.7z";
}
- VerifyInstaller::verifyFileExistence(m_repositoryDir + "/A", componentA);
- VerifyInstaller::verifyFileExistence(m_repositoryDir + "/B", componentB);
+ VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/A", componentA);
+ VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/B", componentB);
}
void verifyComponentMetaUpdatesXml()
{
- VerifyInstaller::verifyFileExistence(m_repositoryDir, QStringList() << "Updates.xml");
- VerifyInstaller::verifyFileHasNoContent(m_repositoryDir + QDir::separator() + "Updates.xml",
+ VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir, QStringList() << "Updates.xml");
+ VerifyInstaller::verifyFileHasNoContent(m_repoInfo.repositoryDir + QDir::separator() + "Updates.xml",
"MetadataName");
}
@@ -216,7 +165,7 @@ private:
foreach (const QString &fileName, contentFiles) {
message = "Copying file from \":///%5/%1/%2%4\" to \"%3/%1/%2%4\"";
QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(component).arg(version)
- .arg(m_repositoryDir).arg(fileName).arg(repository)));
+ .arg(m_repoInfo.repositoryDir).arg(fileName).arg(repository)));
}
}
@@ -303,9 +252,23 @@ private:
void ignoreMessageForUpdateComponent()
{
QString message = "Update component \"A\" in \"%1\" .";
- QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repositoryDir)));
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repoInfo.repositoryDir)));
message = "Update component \"C\" in \"%1\" .";
- QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repositoryDir)));
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repoInfo.repositoryDir)));
+ }
+
+ void verifyComponentShaUpdate(int shaUpdateComponents)
+ {
+ QString updatesXmlFile(m_repoInfo.repositoryDir + QDir::separator() + "Updates.xml");
+ QFile file(updatesXmlFile);
+ QDomDocument dom;
+
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QVERIFY(dom.setContent(&file));
+ file.close();
+ QCOMPARE(dom.elementsByTagName("ContentSha1").count(), shaUpdateComponents);
+ VerifyInstaller::verifyFileContent(updatesXmlFile,
+ "<ContentSha1>059e5ed8cd3a1fbca08cccfa4075265192603e3f</ContentSha1>");
}
private slots:
@@ -313,11 +276,10 @@ private slots:
{
ignoreMessageForCollectingPackages("1.0.0", "1.0.0");
- m_repositoryDir = QInstallerTools::makePathAbsolute(QInstaller::generateTemporaryFileName());
- m_tempDirDeleter.add(m_repositoryDir);
- generateTempMetaDir();
+ m_repoInfo.repositoryDir = QInstallerTools::makePathAbsolute(QInstaller::generateTemporaryFileName());
+ m_tempDirDeleter.add(m_repoInfo.repositoryDir);
- m_packagesDirectories << ":///packages";
+ m_repoInfo.packages << ":///packages";
ignoreMessagesForComponentHash(QStringList() << "A" << "B", false);
ignoreMessagesForCopyMetadata("A", true, false); //Only A has metadata
@@ -357,6 +319,26 @@ private slots:
verifyUniteMetadata("1.0.0");
}
+ void testWithComponentShaUpdate()
+ {
+ ignoreMessagesForComponentSha(QStringList () << "A" << "B", false);
+ generateRepo(true, false, false, QStringList () << "A");
+
+ verifyComponentRepository("1.0.0", true);
+ verifyComponentMetaUpdatesXml();
+ verifyComponentShaUpdate(1);
+ }
+
+ void testWithTwoComponentsShaUpdate()
+ {
+ ignoreMessagesForComponentSha(QStringList () << "A" << "B", false);
+ generateRepo(true, false, false, QStringList () << "A" << "B");
+
+ verifyComponentRepository("1.0.0", true);
+ verifyComponentMetaUpdatesXml();
+ verifyComponentShaUpdate(2);
+ }
+
void testUpdateNewComponents()
{
// Create 'base' repository which will be updated
@@ -371,7 +353,7 @@ private slots:
ignoreMessagesForComponentHash(QStringList() << "A", true);
ignoreMessagesForCopyMetadata("A", true, true);
const QString &message = "Update component \"A\" in \"%1\" .";
- QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repositoryDir)));
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repoInfo.repositoryDir)));
generateRepo(true, false, true);
verifyComponentRepository("2.0.0", true);
verifyComponentMetaUpdatesXml();
@@ -458,7 +440,7 @@ private slots:
generateRepo(true, true, true);
verifyComponentRepository("2.0.0", true);
- VerifyInstaller::verifyFileExistence(m_repositoryDir + "/C", QStringList() << "1.0.0content.7z" << "1.0.0content.7z.sha1" << "1.0.0meta.7z");
+ VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/C", QStringList() << "1.0.0content.7z" << "1.0.0content.7z.sha1" << "1.0.0meta.7z");
verifyUniteMetadata("2.0.0");
}
@@ -478,23 +460,20 @@ private slots:
generateRepo(false, true, true);
verifyComponentRepository("2.0.0", false);
- VerifyInstaller::verifyFileExistence(m_repositoryDir + "/C", QStringList() << "1.0.0content.7z" << "1.0.0content.7z.sha1");
+ VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/C", QStringList() << "1.0.0content.7z" << "1.0.0content.7z.sha1");
verifyUniteMetadata("2.0.0");
}
void cleanup()
{
m_tempDirDeleter.releaseAndDeleteAll();
- m_packagesDirectories.clear();
+ m_repoInfo.packages.clear();
m_packages.clear();
- m_repositoryDirectories.clear();
+ m_repoInfo.repositoryPackages.clear();
}
private:
- QString m_tmpMetaDir;
- QString m_repositoryDir;
- QStringList m_packagesDirectories;
- QStringList m_repositoryDirectories;
+ QInstallerTools::RepositoryInfo m_repoInfo;
QInstallerTools::PackageInfoVector m_packages;
TempDirDeleter m_tempDirDeleter;
};
diff --git a/tools/repogen/repogen.cpp b/tools/repogen/repogen.cpp
index a88867e92..b630f8cd3 100644
--- a/tools/repogen/repogen.cpp
+++ b/tools/repogen/repogen.cpp
@@ -44,8 +44,6 @@
#include <iostream>
-#define QUOTE_(x) #x
-#define QUOTE(x) QUOTE_(x)
using namespace QInstaller;
@@ -100,8 +98,8 @@ int main(int argc, char** argv)
QStringList filteredPackages;
bool updateExistingRepository = false;
- QStringList packagesDirectories;
- QStringList repositoryDirectories;
+ QInstallerTools::RepositoryInfo repoInfo;
+ QStringList packagesUpdatedWithSha;
QInstallerTools::FilterType filterType = QInstallerTools::Exclude;
bool remove = false;
bool updateExistingRepositoryWithNewComponents = false;
@@ -168,7 +166,7 @@ int main(int argc, char** argv)
"Error: Package directory is empty"));
}
- packagesDirectories.append(args.first());
+ repoInfo.packages.append(args.first());
args.removeFirst();
} else if (args.first() == QLatin1String("--repository")) {
args.removeFirst();
@@ -181,7 +179,7 @@ int main(int argc, char** argv)
return printErrorAndUsageAndExit(QCoreApplication::translate("QInstaller",
"Error: Only local filesystem repositories now supported"));
}
- repositoryDirectories.append(args.first());
+ repoInfo.repositoryPackages.append(args.first());
args.removeFirst();
} else if (args.first() == QLatin1String("--ignore-translations")
|| args.first() == QLatin1String("--ignore-invalid-packages")) {
@@ -195,14 +193,17 @@ int main(int argc, char** argv)
} else if (args.first() == QLatin1String("--component-metadata")) {
createUnifiedMetadata = false;
args.removeFirst();
- }
- else {
+ } else if (args.first() == QLatin1String("--sha-update") || args.first() == QLatin1String("-s")) {
+ args.removeFirst();
+ packagesUpdatedWithSha = args.first().split(QLatin1Char(','));
+ args.removeFirst();
+ } else {
printUsage();
return 1;
}
}
- if ((packagesDirectories.isEmpty() && repositoryDirectories.isEmpty()) || (args.count() != 1)) {
+ if ((repoInfo.packages.isEmpty() && repoInfo.repositoryPackages.isEmpty()) || (args.count() != 1)) {
printUsage();
return 1;
}
@@ -213,12 +214,12 @@ int main(int argc, char** argv)
"Argument -r|--remove and --update|--update-new-components are mutually exclusive!"));
}
- const QString repositoryDir = QInstallerTools::makePathAbsolute(args.first());
+ repoInfo.repositoryDir = QInstallerTools::makePathAbsolute(args.first());
if (remove)
- QInstaller::removeDirectory(repositoryDir);
+ QInstaller::removeDirectory(repoInfo.repositoryDir);
if (updateExistingRepositoryWithNewComponents) {
- QStringList meta7z = QDir(repositoryDir).entryList(QStringList()
+ QStringList meta7z = QDir(repoInfo.repositoryDir).entryList(QStringList()
<< QLatin1String("*_meta.7z"), QDir::Files);
if (!meta7z.isEmpty()) {
throw QInstaller::Error(QCoreApplication::translate("QInstaller",
@@ -228,72 +229,27 @@ int main(int argc, char** argv)
}
}
- if (!update && QFile::exists(repositoryDir) && !QDir(repositoryDir).entryList(
+ if (!update && QFile::exists(repoInfo.repositoryDir) && !QDir(repoInfo.repositoryDir).entryList(
QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty()) {
throw QInstaller::Error(QCoreApplication::translate("QInstaller",
- "Repository target directory \"%1\" already exists.").arg(QDir::toNativeSeparators(repositoryDir)));
- }
-
- QInstallerTools::PackageInfoVector packages;
-
- QInstallerTools::PackageInfoVector precompressedPackages = QInstallerTools::createListOfRepositoryPackages(repositoryDirectories,
- &filteredPackages, filterType);
- packages.append(precompressedPackages);
-
- QInstallerTools::PackageInfoVector preparedPackages = QInstallerTools::createListOfPackages(packagesDirectories,
- &filteredPackages, filterType);
- packages.append(preparedPackages);
-
- if (updateExistingRepositoryWithNewComponents) {
- QInstallerTools::filterNewComponents(repositoryDir, packages);
- if (packages.isEmpty()) {
- std::cout << QString::fromLatin1("Cannot find new components to update \"%1\".")
- .arg(repositoryDir) << std::endl;
- return EXIT_SUCCESS;
- }
+ "Repository target directory \"%1\" already exists.").arg(QDir::toNativeSeparators(repoInfo.repositoryDir)));
}
- QHash<QString, QString> pathToVersionMapping = QInstallerTools::buildPathToVersionMapping(packages);
-
- foreach (const QInstallerTools::PackageInfo &package, packages) {
- const QFileInfo fi(repositoryDir, package.name);
- if (fi.exists())
- removeDirectory(fi.absoluteFilePath());
+ QInstallerTools::PackageInfoVector packages = QInstallerTools::collectPackages(repoInfo,
+ &filteredPackages, filterType, updateExistingRepositoryWithNewComponents, packagesUpdatedWithSha);
+ if (packages.isEmpty()) {
+ std::cout << QString::fromLatin1("Cannot find components to update \"%1\".")
+ .arg(repoInfo.repositoryDir) << std::endl;
+ return EXIT_SUCCESS;
}
QTemporaryDir tmp;
tmp.setAutoRemove(false);
tmpMetaDir = tmp.path();
- QStringList directories;
- directories.append(packagesDirectories);
- directories.append(repositoryDirectories);
- QStringList unite7zFiles;
- foreach (const QString &repositoryDirectory, repositoryDirectories) {
- QDirIterator it(repositoryDirectory, QStringList(QLatin1String("*_meta.7z"))
- , QDir::Files | QDir::CaseSensitive);
- while (it.hasNext()) {
- it.next();
- unite7zFiles.append(it.fileInfo().absoluteFilePath());
- }
- }
- QInstallerTools::copyComponentData(directories, repositoryDir, &packages);
- QInstallerTools::copyMetaData(tmpMetaDir, repositoryDir, packages, QLatin1String("{AnyApplication}"),
- QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)), unite7zFiles);
-
- QString existing7z = QInstallerTools::existingUniteMeta7z(repositoryDir);
- if (!existing7z.isEmpty())
- existing7z = repositoryDir + QDir::separator() + existing7z;
- QInstallerTools::compressMetaDirectories(tmpMetaDir, existing7z, pathToVersionMapping,
- createComponentMetadata, createUnifiedMetadata);
-
- QDirIterator it(repositoryDir, QStringList(QLatin1String("Updates*.xml"))
- << QLatin1String("*_meta.7z"), QDir::Files | QDir::CaseSensitive);
- while (it.hasNext()) {
- it.next();
- QFile::remove(it.fileInfo().absoluteFilePath());
- }
- QInstaller::moveDirectoryContents(tmpMetaDir, repositoryDir);
+ QInstallerTools::createRepository(repoInfo, &packages, tmpMetaDir,
+ createComponentMetadata, createUnifiedMetadata);
+
exitCode = EXIT_SUCCESS;
} catch (const Lib7z::SevenZipException &e) {
std::cerr << "Caught 7zip exception: " << e.message() << std::endl;