From fc973b4c0b1b4e30ff69564565fd30e5ac18524a Mon Sep 17 00:00:00 2001 From: Katja Marttila Date: Tue, 9 Jun 2020 15:52:07 +0300 Subject: Fix united-metadata creation Creating repositories caused sha mismatch detect if installed with IFW version 3.2 or lower. Also changed the behavior that without any switches both united and component metadata will be created. --unite-metadata will create only one combined metadata and --component-metadata the old style where each component has their own meta 7z file. Change-Id: I60d3b56217917739fb8115771af8c3bcf9e59f43 Reviewed-by: Iikka Eklund --- tools/common/repositorygen.cpp | 122 ++++++++++++++++++++--------------------- tools/common/repositorygen.h | 7 ++- tools/repogen/repogen.cpp | 18 +++--- 3 files changed, 75 insertions(+), 72 deletions(-) diff --git a/tools/common/repositorygen.cpp b/tools/common/repositorygen.cpp index 85d33845a..5341f30a7 100644 --- a/tools/common/repositorygen.cpp +++ b/tools/common/repositorygen.cpp @@ -659,7 +659,7 @@ static void writeSHA1ToNodeWithName(QDomDocument &doc, QDomNodeList &list, const } void QInstallerTools::compressMetaDirectories(const QString &repoDir, const QString &baseDir, - const QHash &versionMapping, bool createUnitedMetadata, bool createOnlyUnitedMetadata) + const QHash &versionMapping, bool createSplitMetadata, bool createUnifiedMetadata) { QDomDocument doc; QDomElement root; @@ -673,69 +673,14 @@ void QInstallerTools::compressMetaDirectories(const QString &repoDir, const QStr existingUpdatesXml.close(); QDir dir(repoDir); - const QStringList sub = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); - QDomNodeList elements = doc.elementsByTagName(QLatin1String("PackageUpdate")); - foreach (const QString &i, sub) { - QDir sd(dir); - sd.cd(i); - const QString path = QString(i).remove(baseDir); - const QString versionPrefix = versionMapping[path]; - if (path.isNull()) - continue; - const QString absPath = sd.absolutePath(); - const QString fn = QLatin1String(versionPrefix.toLatin1() + "meta.7z"); - const QString tmpTarget = repoDir + QLatin1String("/") + fn; - Lib7z::createArchive(tmpTarget, QStringList() << absPath, Lib7z::TmpFile::No); - } + const QStringList entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); QStringList absPaths; - if (createUnitedMetadata || createOnlyUnitedMetadata) { - QStringList finalTargets; - foreach (const QString &i, sub) { - QDir sd(dir); - sd.cd(i); - const QString absPath = sd.absolutePath(); - finalTargets.append(absPath); - absPaths.append(absPath); - } - - // Compress all metadata from repository to one single 7z - const QString fn = QLatin1String("meta.7z"); - const QString tmpTarget = repoDir + QLatin1String("/") +fn; - Lib7z::createArchive(tmpTarget, finalTargets, Lib7z::TmpFile::No); - - QFile tmp(tmpTarget); - tmp.open(QFile::ReadOnly); - const QByteArray sha1Sum = QInstaller::calculateHash(&tmp, QCryptographicHash::Sha1); - elements = doc.elementsByTagName(QLatin1String("Updates")); - writeSHA1ToNodeWithName(doc, elements, sha1Sum, QString()); + if (createUnifiedMetadata) { + absPaths = unifyMetadata(entryList, repoDir, doc); } - - if (!createOnlyUnitedMetadata) { - foreach (const QString &i, sub) { - QDir sd(dir); - sd.cd(i); - const QString absPath = sd.absolutePath(); - const QString path = QString(i).remove(baseDir); - const QString versionPrefix = versionMapping[path]; - if (path.isNull()) - continue; - const QString fn = QLatin1String(versionPrefix.toLatin1() + "meta.7z"); - const QString tmpTarget = repoDir + QLatin1String("/") + fn; - Lib7z::createArchive(tmpTarget, QStringList() << absPath, Lib7z::TmpFile::No); - // remove the files that got compressed - QInstaller::removeFiles(absPath, true); - QFile tmp(tmpTarget); - tmp.open(QFile::ReadOnly); - const QByteArray sha1Sum = QInstaller::calculateHash(&tmp, QCryptographicHash::Sha1); - writeSHA1ToNodeWithName(doc, elements, sha1Sum, path); - const QString finalTarget = absPath + QLatin1String("/") + fn; - if (!tmp.rename(finalTarget)) { - throw QInstaller::Error(QString::fromLatin1("Cannot move file \"%1\" to \"%2\".").arg( - QDir::toNativeSeparators(tmpTarget), QDir::toNativeSeparators(finalTarget))); - } - - } + if (createSplitMetadata) { + splitMetadata(entryList, repoDir, doc, baseDir, versionMapping); } else { // remove the files that got compressed foreach (const QString path, absPaths) @@ -747,6 +692,61 @@ void QInstallerTools::compressMetaDirectories(const QString &repoDir, const QStr existingUpdatesXml.close(); } +QStringList QInstallerTools::unifyMetadata(const QStringList &entryList, const QString &repoDir, QDomDocument doc) +{ + QStringList absPaths; + QDir dir(repoDir); + foreach (const QString &i, entryList) { + dir.cd(i); + const QString absPath = dir.absolutePath(); + absPaths.append(absPath); + dir.cdUp(); + } + + // Compress all metadata from repository to one single 7z + const QString tmpTarget = repoDir + QLatin1String("/meta.7z"); + Lib7z::createArchive(tmpTarget, absPaths, Lib7z::TmpFile::No); + + QFile tmp(tmpTarget); + tmp.open(QFile::ReadOnly); + const QByteArray sha1Sum = QInstaller::calculateHash(&tmp, QCryptographicHash::Sha1); + QDomNodeList elements = doc.elementsByTagName(QLatin1String("Updates")); + writeSHA1ToNodeWithName(doc, elements, sha1Sum, QString()); + return absPaths; +} + +void QInstallerTools::splitMetadata(const QStringList &entryList, const QString &repoDir, + QDomDocument doc, const QString &baseDir, + const QHash &versionMapping) +{ + QStringList absPaths; + QDomNodeList elements = doc.elementsByTagName(QLatin1String("PackageUpdate")); + QDir dir(repoDir); + foreach (const QString &i, entryList) { + dir.cd(i); + const QString absPath = dir.absolutePath(); + const QString path = QString(i).remove(baseDir); + if (path.isNull()) + continue; + const QString versionPrefix = versionMapping[path]; + const QString fn = QLatin1String(versionPrefix.toLatin1() + "meta.7z"); + const QString tmpTarget = repoDir + QLatin1String("/") + fn; + Lib7z::createArchive(tmpTarget, QStringList() << absPath, Lib7z::TmpFile::No); + // remove the files that got compressed + QInstaller::removeFiles(absPath, true); + QFile tmp(tmpTarget); + tmp.open(QFile::ReadOnly); + const QByteArray sha1Sum = QInstaller::calculateHash(&tmp, QCryptographicHash::Sha1); + writeSHA1ToNodeWithName(doc, elements, sha1Sum, path); + const QString finalTarget = absPath + QLatin1String("/") + fn; + if (!tmp.rename(finalTarget)) { + throw QInstaller::Error(QString::fromLatin1("Cannot move file \"%1\" to \"%2\".").arg( + QDir::toNativeSeparators(tmpTarget), QDir::toNativeSeparators(finalTarget))); + } + dir.cdUp(); + } +} + void QInstallerTools::copyComponentData(const QStringList &packageDirs, const QString &repoDir, PackageInfoVector *const infos) { diff --git a/tools/common/repositorygen.h b/tools/common/repositorygen.h index c3ae6869f..b6317e9b7 100644 --- a/tools/common/repositorygen.h +++ b/tools/common/repositorygen.h @@ -33,6 +33,7 @@ #include #include #include +#include namespace QInstallerTools { @@ -67,7 +68,11 @@ PackageInfoVector createListOfRepositoryPackages(const QStringList &repositoryDi QHash buildPathToVersionMapping(const PackageInfoVector &info); void compressMetaDirectories(const QString &repoDir, const QString &baseDir, - const QHash &versionMapping, bool createUnitedMetadata, bool createOnlyUnitedMetadata); + const QHash &versionMapping, bool createSplitMetadata, bool createUnifiedMetadata); + +QStringList unifyMetadata(const QStringList &entryList, const QString &repoDir, QDomDocument doc); +void splitMetadata(const QStringList &entryList, const QString &repoDir, QDomDocument doc, const QString &baseDir, + const QHash &versionMapping); void copyMetaData(const QString &outDir, const QString &dataDir, const PackageInfoVector &packages, const QString &appName, const QString& appVersion); diff --git a/tools/repogen/repogen.cpp b/tools/repogen/repogen.cpp index 2d16fa720..922bdfe30 100644 --- a/tools/repogen/repogen.cpp +++ b/tools/repogen/repogen.cpp @@ -69,12 +69,10 @@ static void printUsage() std::cout << " -v|--verbose Verbose output" << std::endl; std::cout << " --unite-metadata Combine all metadata into one 7z. This speeds up metadata " << std::endl; - std::cout << " download phase. Creates also metadata 7z per component for " << std::endl; - std::cout << " backward compatibility." << std::endl; - - std::cout << " --unite-metadata-only Combine all metadata into one 7z. This speeds up metadata " << std::endl; std::cout << " download phase." << std::endl; + std::cout << " --component-metadata Creates one metadata 7z per component. " << std::endl; + std::cout << std::endl; std::cout << "Example:" << std::endl; std::cout << " " << appName << " -p ../examples/packages repository/" @@ -106,8 +104,8 @@ int main(int argc, char** argv) QInstallerTools::FilterType filterType = QInstallerTools::Exclude; bool remove = false; bool updateExistingRepositoryWithNewComponents = false; - bool createUnitedMetadata = false; - bool createOnlyUnitedMetadata = false; + bool createUnifiedMetadata = true; + bool createComponentMetadata = true; //TODO: use a for loop without removing values from args like it is in binarycreator.cpp //for (QStringList::const_iterator it = args.begin(); it != args.end(); ++it) { @@ -186,10 +184,10 @@ int main(int argc, char** argv) remove = true; args.removeFirst(); } else if (args.first() == QLatin1String("--unite-metadata")) { - createUnitedMetadata = true; + createComponentMetadata = false; args.removeFirst(); - } else if (args.first() == QLatin1String("--unite-metadata-only")) { - createOnlyUnitedMetadata = true; + } else if (args.first() == QLatin1String("--component-metadata")) { + createUnifiedMetadata = false; args.removeFirst(); } else { @@ -298,7 +296,7 @@ int main(int argc, char** argv) QInstallerTools::copyMetaData(tmpMetaDir, repositoryDir, packages, QLatin1String("{AnyApplication}"), QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION))); QInstallerTools::compressMetaDirectories(tmpMetaDir, tmpMetaDir, pathToVersionMapping, - createUnitedMetadata, createOnlyUnitedMetadata); + createComponentMetadata, createUnifiedMetadata); QDirIterator it(repositoryDir, QStringList(QLatin1String("Updates*.xml")), QDir::Files | QDir::CaseSensitive); while (it.hasNext()) { -- cgit v1.2.3