From b93105c9daf45bce31338e54d14e0869f3c5b669 Mon Sep 17 00:00:00 2001 From: Katja Marttila Date: Wed, 7 Oct 2020 14:00:16 +0300 Subject: Repogen: Fix options to work with unite metadata Fixed regogen 'update' and 'repository' options to work with unite metadata. --update-new-components with unify metadata is prevented. Moved --update-new-components functionality from repogen.cpp to QInstallerTools so it can be accessed from tests. Created tests for repogen. Task-number: QTIFW-1943 Change-Id: I12389f4747154a0f6f51b4f34f630103c2cfef04 Reviewed-by: Arttu Tarkiainen --- tests/auto/auto.pro | 3 +- tests/auto/installer/shared/verifyinstaller.h | 22 + tests/auto/tools/repotest/packages/A/data/A.txt | 2 + .../tools/repotest/packages/A/meta/package.xml | 9 + .../tools/repotest/packages/A/meta/script1.0.0.qs | 3 + tests/auto/tools/repotest/packages/B/data/B.txt | 2 + .../tools/repotest/packages/B/meta/package.xml | 8 + .../repotest/packages_update/A/data/A_update.txt | 2 + .../repotest/packages_update/A/meta/package.xml | 9 + .../repotest/packages_update/A/meta/script2.0.0.qs | 3 + .../repotest/packages_update/B/data/B_update.txt | 2 + .../repotest/packages_update/B/meta/package.xml | 8 + .../repository_component/A/2.0.0content.7z | Bin 0 -> 32 bytes .../repository_component/A/2.0.0content.7z.sha1 | 1 + .../repotest/repository_component/A/2.0.0meta.7z | Bin 0 -> 209 bytes .../repository_component/B/1.0.0content.7z | Bin 0 -> 32 bytes .../repository_component/B/1.0.0content.7z.sha1 | 1 + .../repotest/repository_component/B/1.0.0meta.7z | Bin 0 -> 106 bytes .../repotest/repository_component/Updates.xml | 28 ++ .../2020-10-13-0958_meta.7z | Bin 0 -> 217 bytes .../repository_componentAndUnite/A/2.0.0content.7z | Bin 0 -> 32 bytes .../A/2.0.0content.7z.sha1 | 1 + .../repository_componentAndUnite/A/2.0.0meta.7z | Bin 0 -> 210 bytes .../repository_componentAndUnite/B/1.0.0content.7z | Bin 0 -> 32 bytes .../B/1.0.0content.7z.sha1 | 1 + .../repository_componentAndUnite/B/1.0.0meta.7z | Bin 0 -> 106 bytes .../repository_componentAndUnite/Updates.xml | 30 ++ .../repository_unite/2020-10-13-0958_meta.7z | Bin 0 -> 217 bytes .../repotest/repository_unite/A/2.0.0content.7z | Bin 0 -> 32 bytes .../repository_unite/A/2.0.0content.7z.sha1 | 1 + .../repotest/repository_unite/B/1.0.0content.7z | Bin 0 -> 32 bytes .../repository_unite/B/1.0.0content.7z.sha1 | 1 + .../tools/repotest/repository_unite/Updates.xml | 28 ++ tests/auto/tools/repotest/repotest.pro | 10 + tests/auto/tools/repotest/settings.qrc | 35 ++ tests/auto/tools/repotest/tst_repotest.cpp | 477 +++++++++++++++++++++ tests/auto/tools/tools.pro | 4 + tools/binarycreator/binarycreator.cpp | 2 +- tools/common/repositorygen.cpp | 128 ++++-- tools/common/repositorygen.h | 4 +- tools/repogen/repogen.cpp | 79 ++-- tools/repogen/repogen.pri | 1 + tools/repogen/repogen.pro | 3 +- 43 files changed, 827 insertions(+), 81 deletions(-) create mode 100644 tests/auto/tools/repotest/packages/A/data/A.txt create mode 100644 tests/auto/tools/repotest/packages/A/meta/package.xml create mode 100644 tests/auto/tools/repotest/packages/A/meta/script1.0.0.qs create mode 100644 tests/auto/tools/repotest/packages/B/data/B.txt create mode 100644 tests/auto/tools/repotest/packages/B/meta/package.xml create mode 100644 tests/auto/tools/repotest/packages_update/A/data/A_update.txt create mode 100644 tests/auto/tools/repotest/packages_update/A/meta/package.xml create mode 100644 tests/auto/tools/repotest/packages_update/A/meta/script2.0.0.qs create mode 100644 tests/auto/tools/repotest/packages_update/B/data/B_update.txt create mode 100644 tests/auto/tools/repotest/packages_update/B/meta/package.xml create mode 100644 tests/auto/tools/repotest/repository_component/A/2.0.0content.7z create mode 100644 tests/auto/tools/repotest/repository_component/A/2.0.0content.7z.sha1 create mode 100644 tests/auto/tools/repotest/repository_component/A/2.0.0meta.7z create mode 100644 tests/auto/tools/repotest/repository_component/B/1.0.0content.7z create mode 100644 tests/auto/tools/repotest/repository_component/B/1.0.0content.7z.sha1 create mode 100644 tests/auto/tools/repotest/repository_component/B/1.0.0meta.7z create mode 100644 tests/auto/tools/repotest/repository_component/Updates.xml create mode 100644 tests/auto/tools/repotest/repository_componentAndUnite/2020-10-13-0958_meta.7z create mode 100644 tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z create mode 100644 tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z.sha1 create mode 100644 tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0meta.7z create mode 100644 tests/auto/tools/repotest/repository_componentAndUnite/B/1.0.0content.7z create mode 100644 tests/auto/tools/repotest/repository_componentAndUnite/B/1.0.0content.7z.sha1 create mode 100644 tests/auto/tools/repotest/repository_componentAndUnite/B/1.0.0meta.7z create mode 100644 tests/auto/tools/repotest/repository_componentAndUnite/Updates.xml create mode 100644 tests/auto/tools/repotest/repository_unite/2020-10-13-0958_meta.7z create mode 100644 tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z create mode 100644 tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z.sha1 create mode 100644 tests/auto/tools/repotest/repository_unite/B/1.0.0content.7z create mode 100644 tests/auto/tools/repotest/repository_unite/B/1.0.0content.7z.sha1 create mode 100644 tests/auto/tools/repotest/repository_unite/Updates.xml create mode 100644 tests/auto/tools/repotest/repotest.pro create mode 100644 tests/auto/tools/repotest/settings.qrc create mode 100644 tests/auto/tools/repotest/tst_repotest.cpp create mode 100644 tests/auto/tools/tools.pro create mode 100644 tools/repogen/repogen.pri diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index aed5d01af..e79e6a5d7 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -1,4 +1,5 @@ TEMPLATE = subdirs SUBDIRS += \ - installer + installer \ + tools diff --git a/tests/auto/installer/shared/verifyinstaller.h b/tests/auto/installer/shared/verifyinstaller.h index 91ab2f3cd..4445743af 100644 --- a/tests/auto/installer/shared/verifyinstaller.h +++ b/tests/auto/installer/shared/verifyinstaller.h @@ -33,6 +33,8 @@ #include #include #include +#include +#include struct VerifyInstaller { @@ -68,6 +70,26 @@ struct VerifyInstaller QCOMPARE(dir.entryList(QStringList() << "*.*", QDir::Files).count(), fileList.count()); } + static QString fileContent(const QString &fileName) + { + QFile file(fileName); + QTextStream stream(&file); + file.open(QIODevice::ReadOnly); + QString str = stream.readAll(); + file.close(); + return str; + } + + static void verifyFileContent(const QString &fileName, const QString &content) + { + QVERIFY(fileContent(fileName).contains(content)); + } + + static void verifyFileHasNoContent(const QString &fileName, const QString &content) + { + QVERIFY(!fileContent(fileName).contains(content)); + } + static void addToFileMap(const QDir &baseDir, const QFileInfo &fileInfo, QMap &map) { QDir directory(fileInfo.absoluteFilePath()); diff --git a/tests/auto/tools/repotest/packages/A/data/A.txt b/tests/auto/tools/repotest/packages/A/data/A.txt new file mode 100644 index 000000000..98114dd6e --- /dev/null +++ b/tests/auto/tools/repotest/packages/A/data/A.txt @@ -0,0 +1,2 @@ +Example content for package A. + diff --git a/tests/auto/tools/repotest/packages/A/meta/package.xml b/tests/auto/tools/repotest/packages/A/meta/package.xml new file mode 100644 index 000000000..8383b10c7 --- /dev/null +++ b/tests/auto/tools/repotest/packages/A/meta/package.xml @@ -0,0 +1,9 @@ + + + A + Example component A + 1.0.0 + 2020-01-01 + true + + diff --git a/tests/auto/tools/repotest/packages/A/meta/script1.0.0.qs b/tests/auto/tools/repotest/packages/A/meta/script1.0.0.qs new file mode 100644 index 000000000..addf3329a --- /dev/null +++ b/tests/auto/tools/repotest/packages/A/meta/script1.0.0.qs @@ -0,0 +1,3 @@ +function Component() +{ +} diff --git a/tests/auto/tools/repotest/packages/B/data/B.txt b/tests/auto/tools/repotest/packages/B/data/B.txt new file mode 100644 index 000000000..1ee864074 --- /dev/null +++ b/tests/auto/tools/repotest/packages/B/data/B.txt @@ -0,0 +1,2 @@ +Example content for package B. + diff --git a/tests/auto/tools/repotest/packages/B/meta/package.xml b/tests/auto/tools/repotest/packages/B/meta/package.xml new file mode 100644 index 000000000..99b723d50 --- /dev/null +++ b/tests/auto/tools/repotest/packages/B/meta/package.xml @@ -0,0 +1,8 @@ + + + B + Example component B + 1.0.0 + 2020-01-01 + true + diff --git a/tests/auto/tools/repotest/packages_update/A/data/A_update.txt b/tests/auto/tools/repotest/packages_update/A/data/A_update.txt new file mode 100644 index 000000000..98114dd6e --- /dev/null +++ b/tests/auto/tools/repotest/packages_update/A/data/A_update.txt @@ -0,0 +1,2 @@ +Example content for package A. + diff --git a/tests/auto/tools/repotest/packages_update/A/meta/package.xml b/tests/auto/tools/repotest/packages_update/A/meta/package.xml new file mode 100644 index 000000000..1763dc4d8 --- /dev/null +++ b/tests/auto/tools/repotest/packages_update/A/meta/package.xml @@ -0,0 +1,9 @@ + + + A + Example component A + 2.0.0 + 2020-01-01 + true + + diff --git a/tests/auto/tools/repotest/packages_update/A/meta/script2.0.0.qs b/tests/auto/tools/repotest/packages_update/A/meta/script2.0.0.qs new file mode 100644 index 000000000..addf3329a --- /dev/null +++ b/tests/auto/tools/repotest/packages_update/A/meta/script2.0.0.qs @@ -0,0 +1,3 @@ +function Component() +{ +} diff --git a/tests/auto/tools/repotest/packages_update/B/data/B_update.txt b/tests/auto/tools/repotest/packages_update/B/data/B_update.txt new file mode 100644 index 000000000..1ee864074 --- /dev/null +++ b/tests/auto/tools/repotest/packages_update/B/data/B_update.txt @@ -0,0 +1,2 @@ +Example content for package B. + diff --git a/tests/auto/tools/repotest/packages_update/B/meta/package.xml b/tests/auto/tools/repotest/packages_update/B/meta/package.xml new file mode 100644 index 000000000..99b723d50 --- /dev/null +++ b/tests/auto/tools/repotest/packages_update/B/meta/package.xml @@ -0,0 +1,8 @@ + + + B + Example component B + 1.0.0 + 2020-01-01 + true + diff --git a/tests/auto/tools/repotest/repository_component/A/2.0.0content.7z b/tests/auto/tools/repotest/repository_component/A/2.0.0content.7z new file mode 100644 index 000000000..46e2c9124 Binary files /dev/null and b/tests/auto/tools/repotest/repository_component/A/2.0.0content.7z differ diff --git a/tests/auto/tools/repotest/repository_component/A/2.0.0content.7z.sha1 b/tests/auto/tools/repotest/repository_component/A/2.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/repository_component/A/2.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f \ No newline at end of file diff --git a/tests/auto/tools/repotest/repository_component/A/2.0.0meta.7z b/tests/auto/tools/repotest/repository_component/A/2.0.0meta.7z new file mode 100644 index 000000000..af0863696 Binary files /dev/null and b/tests/auto/tools/repotest/repository_component/A/2.0.0meta.7z differ diff --git a/tests/auto/tools/repotest/repository_component/B/1.0.0content.7z b/tests/auto/tools/repotest/repository_component/B/1.0.0content.7z new file mode 100644 index 000000000..46e2c9124 Binary files /dev/null and b/tests/auto/tools/repotest/repository_component/B/1.0.0content.7z differ diff --git a/tests/auto/tools/repotest/repository_component/B/1.0.0content.7z.sha1 b/tests/auto/tools/repotest/repository_component/B/1.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/repository_component/B/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f \ No newline at end of file diff --git a/tests/auto/tools/repotest/repository_component/B/1.0.0meta.7z b/tests/auto/tools/repotest/repository_component/B/1.0.0meta.7z new file mode 100644 index 000000000..e5be1148e Binary files /dev/null and b/tests/auto/tools/repotest/repository_component/B/1.0.0meta.7z differ diff --git a/tests/auto/tools/repotest/repository_component/Updates.xml b/tests/auto/tools/repotest/repository_component/Updates.xml new file mode 100644 index 000000000..dfae8c8bd --- /dev/null +++ b/tests/auto/tools/repotest/repository_component/Updates.xml @@ -0,0 +1,28 @@ + + {AnyApplication} + 1.0.0 + true + + A + A + Example component A + 2.0.0 + 2020-01-01 + true + + + content.7z + da6dae55a8cc3fb9f012e33fa7b9c187a823aa9a + + + B + B + Example component B + 1.0.0 + 2020-01-01 + true + + content.7z + d88b373458b4bbec38132692061bf1e7aa68e7f7 + + diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/2020-10-13-0958_meta.7z b/tests/auto/tools/repotest/repository_componentAndUnite/2020-10-13-0958_meta.7z new file mode 100644 index 000000000..b8e560fed Binary files /dev/null and b/tests/auto/tools/repotest/repository_componentAndUnite/2020-10-13-0958_meta.7z differ diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z b/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z new file mode 100644 index 000000000..46e2c9124 Binary files /dev/null and b/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z differ diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z.sha1 b/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f \ No newline at end of file diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0meta.7z b/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0meta.7z new file mode 100644 index 000000000..3cda3cdc4 Binary files /dev/null and b/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0meta.7z differ diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/B/1.0.0content.7z b/tests/auto/tools/repotest/repository_componentAndUnite/B/1.0.0content.7z new file mode 100644 index 000000000..46e2c9124 Binary files /dev/null and b/tests/auto/tools/repotest/repository_componentAndUnite/B/1.0.0content.7z differ diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/B/1.0.0content.7z.sha1 b/tests/auto/tools/repotest/repository_componentAndUnite/B/1.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/repository_componentAndUnite/B/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f \ No newline at end of file diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/B/1.0.0meta.7z b/tests/auto/tools/repotest/repository_componentAndUnite/B/1.0.0meta.7z new file mode 100644 index 000000000..e2867c1ee Binary files /dev/null and b/tests/auto/tools/repotest/repository_componentAndUnite/B/1.0.0meta.7z differ diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/Updates.xml b/tests/auto/tools/repotest/repository_componentAndUnite/Updates.xml new file mode 100644 index 000000000..653c0e91e --- /dev/null +++ b/tests/auto/tools/repotest/repository_componentAndUnite/Updates.xml @@ -0,0 +1,30 @@ + + {AnyApplication} + 1.0.0 + true + 815dc9afb48774335e468956fa2e1208a239dc06 + 2020-10-13-0958_meta.7z + + A + A + Example component A + 2.0.0 + 2020-01-01 + true + + + content.7z + f02d025098d76673f3a848e5d5f0421ffa5ee82d + + + B + B + Example component B + 1.0.0 + 2020-01-01 + true + + content.7z + c520ba1bbde7eb1adf4b274c869a8df0a5efa5b8 + + diff --git a/tests/auto/tools/repotest/repository_unite/2020-10-13-0958_meta.7z b/tests/auto/tools/repotest/repository_unite/2020-10-13-0958_meta.7z new file mode 100644 index 000000000..4ff34ad9f Binary files /dev/null and b/tests/auto/tools/repotest/repository_unite/2020-10-13-0958_meta.7z differ diff --git a/tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z b/tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z new file mode 100644 index 000000000..46e2c9124 Binary files /dev/null and b/tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z differ diff --git a/tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z.sha1 b/tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f \ No newline at end of file diff --git a/tests/auto/tools/repotest/repository_unite/B/1.0.0content.7z b/tests/auto/tools/repotest/repository_unite/B/1.0.0content.7z new file mode 100644 index 000000000..46e2c9124 Binary files /dev/null and b/tests/auto/tools/repotest/repository_unite/B/1.0.0content.7z differ diff --git a/tests/auto/tools/repotest/repository_unite/B/1.0.0content.7z.sha1 b/tests/auto/tools/repotest/repository_unite/B/1.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/repository_unite/B/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f \ No newline at end of file diff --git a/tests/auto/tools/repotest/repository_unite/Updates.xml b/tests/auto/tools/repotest/repository_unite/Updates.xml new file mode 100644 index 000000000..c9bcc93cd --- /dev/null +++ b/tests/auto/tools/repotest/repository_unite/Updates.xml @@ -0,0 +1,28 @@ + + {AnyApplication} + 1.0.0 + true + 4a494d033d3092b392ba775b17a7e4776ccf4777 + 2020-10-13-0958_meta.7z + + A + A + Example component A + 2.0.0 + 2020-01-01 + true + + + content.7z + + + B + B + Example component B + 1.0.0 + 2020-01-01 + true + + content.7z + + diff --git a/tests/auto/tools/repotest/repotest.pro b/tests/auto/tools/repotest/repotest.pro new file mode 100644 index 000000000..73d482638 --- /dev/null +++ b/tests/auto/tools/repotest/repotest.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) +include(../../../../tools/repogen/repogen.pri) + +QT -= gui + +SOURCES += tst_repotest.cpp + +RESOURCES += \ + settings.qrc + diff --git a/tests/auto/tools/repotest/settings.qrc b/tests/auto/tools/repotest/settings.qrc new file mode 100644 index 000000000..77d250b20 --- /dev/null +++ b/tests/auto/tools/repotest/settings.qrc @@ -0,0 +1,35 @@ + + + packages/A/data/A.txt + packages/A/meta/package.xml + packages/A/meta/script1.0.0.qs + packages/B/data/B.txt + packages/B/meta/package.xml + packages_update/A/data/A_update.txt + packages_update/A/meta/package.xml + packages_update/A/meta/script2.0.0.qs + packages_update/B/data/B_update.txt + packages_update/B/meta/package.xml + repository_component/A/2.0.0content.7z + repository_component/A/2.0.0content.7z.sha1 + repository_component/A/2.0.0meta.7z + repository_component/B/1.0.0content.7z + repository_component/B/1.0.0content.7z.sha1 + repository_component/B/1.0.0meta.7z + repository_component/Updates.xml + repository_componentAndUnite/A/2.0.0content.7z + repository_componentAndUnite/A/2.0.0content.7z.sha1 + repository_componentAndUnite/A/2.0.0meta.7z + repository_componentAndUnite/B/1.0.0content.7z + repository_componentAndUnite/B/1.0.0content.7z.sha1 + repository_componentAndUnite/B/1.0.0meta.7z + repository_componentAndUnite/2020-10-13-0958_meta.7z + repository_componentAndUnite/Updates.xml + repository_unite/A/2.0.0content.7z + repository_unite/A/2.0.0content.7z.sha1 + repository_unite/B/1.0.0content.7z + repository_unite/B/1.0.0content.7z.sha1 + repository_unite/2020-10-13-0958_meta.7z + repository_unite/Updates.xml + + diff --git a/tests/auto/tools/repotest/tst_repotest.cpp b/tests/auto/tools/repotest/tst_repotest.cpp new file mode 100644 index 000000000..2f5ca2cbb --- /dev/null +++ b/tests/auto/tools/repotest/tst_repotest.cpp @@ -0,0 +1,477 @@ +/************************************************************************** +** +** Copyright (C) 2020 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 "../../installer/shared/verifyinstaller.h" + +#include +#include +#include + +#include +#include +#include + +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) + { + 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 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()); + } + + if (updateNewComponents) { //Verify that component B exists as that is not updated + VerifyInstaller::verifyFileExistence(m_repositoryDir + "/B", QStringList() << "1.0.0content.7z" + << "1.0.0content.7z.sha1" << "1.0.0meta.7z"); + } else { + QDir dir(m_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); + QInstallerTools::compressMetaDirectories(m_tmpMetaDir, m_tmpMetaDir, 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); + } + + void clearData() + { + generateTempMetaDir(); + m_packagesDirectories.clear(); + m_repositoryDirectories.clear(); + m_packages.clear(); + } + + void initRepoUpdate() + { + clearData(); + m_packagesDirectories << ":///packages_update"; + } + + void initRepoUpdateFromRepository(const QString &repository) + { + clearData(); + m_repositoryDirectories << repository; + } + + void verifyUniteMetadata(const QString &scriptVersion) + { + QString fileContent = VerifyInstaller::fileContent(m_repositoryDir + QDir::separator() + + "Updates.xml"); + QRegularExpression re("(.*)<.MetadataName>"); + QStringList matches = re.match(fileContent).capturedTexts(); + QCOMPARE(2, matches.count()); + QFile file(m_repositoryDir + QDir::separator() + matches.at(1)); + QVERIFY(file.open(QIODevice::ReadOnly)); + + //We have script.qs for package A in the unite metadata + QVector::const_iterator fileIt; + const QVector files = Lib7z::listArchive(&file); + for (fileIt = files.begin(); fileIt != files.end(); ++fileIt) { + if (fileIt->isDirectory) + continue; + QString fileName = "A/script%1.qs"; + QCOMPARE(qPrintable(fileName.arg(scriptVersion)), fileIt->path); + } + + VerifyInstaller::verifyFileExistence(m_repositoryDir, QStringList() << "Updates.xml" + << matches.at(1)); + VerifyInstaller::verifyFileContent(m_repositoryDir + QDir::separator() + "Updates.xml", + "SHA1"); + VerifyInstaller::verifyFileContent(m_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 meta = "%1meta.7z"; + QStringList componentA; + QStringList componentB; + componentA << qPrintable(content.arg(componentAVersion)) << qPrintable(contentSha.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); + } + + void verifyComponentMetaUpdatesXml() + { + VerifyInstaller::verifyFileExistence(m_repositoryDir, QStringList() << "Updates.xml"); + VerifyInstaller::verifyFileHasNoContent(m_repositoryDir + QDir::separator() + "Updates.xml", + "MetadataName"); + } + + void ignoreMessagesForComponentHash(const QStringList &components, bool update) + { + 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\")"; + else + message = "Compressing files found in data directory: (\":/packages/%1/data/%1.txt\")"; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(component))); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Hash is stored in *")); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Creating hash of archive *")); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Generated sha1 hash: *")); + } + } + + void ignoreMessagesForCopyRepository(const QString &component, const QString &version, const QString &repository) + { + QStringList contentFiles; + contentFiles << "content.7z" << "content.7z.sha1"; + QString message = "Copying component data for \"%1\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(component))); + 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))); + } + } + + void ignoreMessageForCollectingRepository(const QString &repository) + { + const QString message = "Process repository \"%2\""; + QTest::ignoreMessage(QtDebugMsg, "Collecting information about available repository packages..."); + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(repository))); + QTest::ignoreMessage(QtDebugMsg, "Collecting information about available packages..."); + QTest::ignoreMessage(QtDebugMsg, "No available packages found at the specified location."); + QTest::ignoreMessage(QtDebugMsg, "- it provides the package \"B\" - \"1.0.0\""); + QTest::ignoreMessage(QtDebugMsg, "- it provides the package \"A\" - \"2.0.0\""); + } + + 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))); + 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\""; + else + message = "Copying associated \"script\" file \":///packages/%1/meta/script1.0.0.qs\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(component))); + QTest::ignoreMessage(QtDebugMsg, "done."); + } + } + + void ignoreMessagesForComponentSha(const QStringList &components, bool clearOldChecksum) + { + foreach (const QString component, components) { + const QString message = "Searching sha1sum node for \"%1\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(component))); + if (clearOldChecksum) + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("- clearing the old sha1sum *")); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("- writing the sha1sum *")); + } + } + + void ignoreMessagesForUniteMeta(bool update) + { + QTest::ignoreMessage(QtDebugMsg, "Writing sha1sum node."); + if (update) + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("- clearing the old sha1sum *")); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("- writing the sha1sum")); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Updating the metadata node with name *")); + } + + void ignoreMessageForCollectingPackages(const QString &versionA, const QString &versionB) + { + 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))); + } + + void ignoreMessageForCollectingPackagesFromRepository(const QString &versionA, const QString &versionB) + { + QString message = "- it provides the package \"B\" - \"%1\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(versionB))); + message = "- it provides the package \"A\" - \"%1\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(versionA))); + QTest::ignoreMessage(QtDebugMsg, "Collecting information about available packages..."); + QTest::ignoreMessage(QtDebugMsg, "No available packages found at the specified location."); + } + + void ignoreMessagesForUpdateComponents() + { + ignoreMessageForCollectingPackages("2.0.0", "1.0.0"); + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + ignoreMessagesForComponentHash(QStringList() << "A" << "B", true); + ignoreMessagesForCopyMetadata("A", true, true); + ignoreMessagesForCopyMetadata("B", false, true); + } + +private slots: + void init() + { + ignoreMessageForCollectingPackages("1.0.0", "1.0.0"); + + m_repositoryDir = QInstallerTools::makePathAbsolute(QInstaller::generateTemporaryFileName()); + m_tempDirDeleter.add(m_repositoryDir); + generateTempMetaDir(); + + m_packagesDirectories << ":///packages"; + + ignoreMessagesForComponentHash(QStringList() << "A" << "B", false); + ignoreMessagesForCopyMetadata("A", true, false); //Only A has metadata + ignoreMessagesForCopyMetadata("B", false, false); + } + + void initTestCase() + { + Lib7z::initSevenZ(); + } + + void testWithComponentMeta() + { + ignoreMessagesForComponentSha(QStringList () << "A" << "B", false); + generateRepo(true, false, false); + + verifyComponentRepository("1.0.0", true); + verifyComponentMetaUpdatesXml(); + } + + void testWithComponentAndUniteMeta() + { + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + ignoreMessagesForUniteMeta(false); + generateRepo(true, true, false); + + verifyComponentRepository("1.0.0", true); + verifyUniteMetadata("1.0.0"); + } + + void testWithUniteMeta() + { + ignoreMessagesForUniteMeta(false); + generateRepo(false, true, false); + + verifyComponentRepository("1.0.0", false); + verifyUniteMetadata("1.0.0"); + } + + void testUpdateNewComponents() + { + // Create 'base' repository which will be updated + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + generateRepo(true, false, false); + verifyComponentRepository("1.0.0", true); + + // Update the 'base' repository + initRepoUpdate(); + ignoreMessageForCollectingPackages("2.0.0", "1.0.0"); + ignoreMessagesForComponentSha(QStringList() << "A", false); //Only A has update + ignoreMessagesForComponentHash(QStringList() << "A", true); + ignoreMessagesForCopyMetadata("A", true, true); + const QString &message = "Update component \"A\" in \"%1\" ."; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repositoryDir))); + generateRepo(true, false, true); + verifyComponentRepository("2.0.0", true); + verifyComponentMetaUpdatesXml(); + } + + void testUpdateComponents() + { + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + generateRepo(true, false, false); + verifyComponentRepository("1.0.0",true); + + initRepoUpdate(); + ignoreMessagesForUpdateComponents(); + generateRepo(true, false, false); + verifyComponentRepository("2.0.0", true); + verifyComponentMetaUpdatesXml(); + } + + void testUpdateComponentsWithUniteMetadata() + { + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + ignoreMessagesForUniteMeta(false); + generateRepo(true, true, false); + verifyComponentRepository("1.0.0", true); + + initRepoUpdate(); + ignoreMessagesForUpdateComponents(); + ignoreMessagesForUniteMeta(true); + generateRepo(true, true, false); + verifyComponentRepository("2.0.0", true); + verifyUniteMetadata("2.0.0"); + } + + void testUpdateComponentsWithOnlyUniteMetadata() + { + ignoreMessagesForUniteMeta(false); + generateRepo(false, true, false); + verifyComponentRepository("1.0.0", false); + + initRepoUpdate(); + ignoreMessageForCollectingPackages("2.0.0", "1.0.0"); + ignoreMessagesForComponentHash(QStringList() << "A" << "B", true); + ignoreMessagesForCopyMetadata("A", true, true); + ignoreMessagesForCopyMetadata("B", false, true); + ignoreMessagesForUniteMeta(true); + generateRepo(false, true, false); + verifyComponentRepository("2.0.0", false); + verifyUniteMetadata("2.0.0"); + } + + void testUpdateComponentsFromRepository() + { + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + generateRepo(true, false, false); + verifyComponentRepository("1.0.0", true); + + initRepoUpdateFromRepository(":///repository_component"); + ignoreMessageForCollectingRepository("repository_component"); + ignoreMessagesForCopyRepository("B", "1.0.0", "repository_component"); + ignoreMessagesForCopyRepository("A", "2.0.0", "repository_component"); + ignoreMessagesForComponentSha(QStringList() << "A" << "B", true); + generateRepo(true, false, false); + verifyComponentRepository("2.0.0", true); + verifyComponentMetaUpdatesXml(); + } + + void testUpdateComponentsFromRepositoryWithUniteMetadata() + { + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + ignoreMessagesForUniteMeta(false); + generateRepo(true, true, false); + verifyComponentRepository("1.0.0", true); + + initRepoUpdateFromRepository(":///repository_componentAndUnite"); + ignoreMessageForCollectingRepository("repository_componentAndUnite"); + ignoreMessagesForCopyRepository("A", "2.0.0", "repository_componentAndUnite"); + ignoreMessagesForCopyRepository("B", "1.0.0", "repository_componentAndUnite"); + ignoreMessagesForUniteMeta(true); + ignoreMessagesForComponentSha(QStringList() << "A" << "B", true); + generateRepo(true, true, false); + verifyComponentRepository("2.0.0", true); + verifyUniteMetadata("2.0.0"); + } + + void testUpdateComponentsFromRepositoryWithOnlyUniteMetadata() + { + ignoreMessagesForUniteMeta(false); + generateRepo(false, true, false); + verifyComponentRepository("1.0.0", false); + + initRepoUpdateFromRepository(":///repository_unite"); + ignoreMessageForCollectingRepository("repository_unite"); + ignoreMessagesForCopyRepository("A", "2.0.0", "repository_unite"); + ignoreMessagesForCopyRepository("B", "1.0.0", "repository_unite"); + ignoreMessagesForUniteMeta(true); + generateRepo(false, true, false); + verifyComponentRepository("2.0.0", false); + verifyUniteMetadata("2.0.0"); + } + + void cleanup() + { + m_tempDirDeleter.releaseAndDeleteAll(); + m_packagesDirectories.clear(); + m_packages.clear(); + m_repositoryDirectories.clear(); + } + +private: + QString m_tmpMetaDir; + QString m_repositoryDir; + QStringList m_packagesDirectories; + QStringList m_repositoryDirectories; + QInstallerTools::PackageInfoVector m_packages; + TempDirDeleter m_tempDirDeleter; +}; + +QTEST_MAIN(tst_repotest) + +#include "tst_repotest.moc" diff --git a/tests/auto/tools/tools.pro b/tests/auto/tools/tools.pro new file mode 100644 index 000000000..7e881ecee --- /dev/null +++ b/tests/auto/tools/tools.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + repotest diff --git a/tools/binarycreator/binarycreator.cpp b/tools/binarycreator/binarycreator.cpp index 6caf3ff1f..f6662615e 100644 --- a/tools/binarycreator/binarycreator.cpp +++ b/tools/binarycreator/binarycreator.cpp @@ -986,7 +986,7 @@ int main(int argc, char **argv) // 3; copy the meta data of the available packages, generate Updates.xml QInstallerTools::copyMetaData(tmpMetaDir, tmpRepoDir, packages, settings - .applicationName(), settings.version()); + .applicationName(), settings.version(), QStringList()); // 4; copy the configuration file and and icons etc. copyConfigData(configFile, tmpMetaDir + QLatin1String("/installer-config")); diff --git a/tools/common/repositorygen.cpp b/tools/common/repositorygen.cpp index 4215f127d..6f17ad5ac 100644 --- a/tools/common/repositorygen.cpp +++ b/tools/common/repositorygen.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -93,7 +93,7 @@ void QInstallerTools::copyWithException(const QString &source, const QString &ta (targetFileInfo.exists() ? QLatin1String("Target already exist.") : sourceFile.errorString()))); } - qDebug() << "done.\n"; + qDebug() << "done."; } static QStringList copyFilesFromNode(const QString &parentNode, const QString &childNode, const QString &attr, @@ -125,12 +125,14 @@ static QStringList copyFilesFromNode(const QString &parentNode, const QString &c } void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &metaDataDir, - const PackageInfoVector &packages, const QString &appName, const QString &appVersion) + const PackageInfoVector &packages, const QString &appName, const QString &appVersion, + const QStringList &uniteMetadatas) { const QString targetDir = makePathAbsolute(_targetDir); if (!QFile::exists(targetDir)) QInstaller::mkpath(targetDir); + bool componentMetaExtracted = false; QDomDocument doc; QDomElement root; QFile existingUpdatesXml(QFileInfo(metaDataDir, QLatin1String("Updates.xml")).absoluteFilePath()); @@ -377,9 +379,12 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met } } else { // Extract metadata from archive - QFile metaFile(info.metaFile); - QInstaller::openForRead(&metaFile); - Lib7z::extractArchive(&metaFile, targetDir); + if (!info.metaFile.isEmpty()){ + QFile metaFile(info.metaFile); + QInstaller::openForRead(&metaFile); + Lib7z::extractArchive(&metaFile, targetDir); + componentMetaExtracted = true; + } // Restore "PackageUpdate" node; QDomDocument update; @@ -391,6 +396,14 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met } } + if (!componentMetaExtracted) { + foreach (const QString uniteMetadata, uniteMetadatas) { + QFile metaFile(QFileInfo(metaDataDir, uniteMetadata).absoluteFilePath()); + QInstaller::openForRead(&metaFile); + Lib7z::extractArchive(&metaFile, targetDir); + } + } + doc.appendChild(root); QFile targetUpdatesXml(targetDir + QLatin1String("/Updates.xml")); @@ -401,7 +414,7 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met PackageInfoVector QInstallerTools::createListOfPackages(const QStringList &packagesDirectories, QStringList *packagesToFilter, FilterType filterType) { - qDebug() << "\nCollecting information about available packages..."; + qDebug() << "Collecting information about available packages..."; bool ignoreInvalidPackages = qApp->arguments().contains(QString::fromLatin1("--ignore-invalid-packages")); @@ -583,16 +596,20 @@ PackageInfoVector QInstallerTools::createListOfRepositoryPackages(const QStringL continue; info.directory = QString::fromLatin1("%1/%2").arg(it->filePath(), info.name); - info.metaFile = QString::fromLatin1("%1/%3%2").arg(info.directory, - QString::fromLatin1("meta.7z"), info.version); + const QDomElement sha1 = el.firstChildElement(QInstaller::scSHA1); + if (!sha1.isNull()) { + info.metaFile = QString::fromLatin1("%1/%3%2").arg(info.directory, + QString::fromLatin1("meta.7z"), info.version); + } const QDomNodeList c2 = el.childNodes(); for (int j = 0; j < c2.count(); ++j) { - if (c2.at(j).toElement().tagName() == QInstaller::scDependencies) - info.dependencies = c2.at(j).toElement().text() + const QDomElement c2Element = c2.at(j).toElement(); + if (c2Element.tagName() == QInstaller::scDependencies) + info.dependencies = c2Element.text() .split(QInstaller::commaRegExp(), QString::SkipEmptyParts); - else if (c2.at(j).toElement().tagName() == QInstaller::scDownloadableArchives) { - QStringList names = c2.at(j).toElement().text() + else if (c2Element.tagName() == QInstaller::scDownloadableArchives) { + QStringList names = c2Element.text() .split(QInstaller::commaRegExp(), QString::SkipEmptyParts); foreach (const QString &name, names) { info.copiedFiles.append(QString::fromLatin1("%1/%3%2").arg(info.directory, @@ -626,18 +643,21 @@ QHash QInstallerTools::buildPathToVersionMapping(const Package } static void writeSHA1ToNodeWithName(QDomDocument &doc, QDomNodeList &list, const QByteArray &sha1sum, - const QString &nodename = QString(), const QString &metadataName = QString()) + const QString &nodename = QString()) { if (nodename.isEmpty()) - qDebug() << "Searching sha1sum node."; + qDebug() << "Writing sha1sum node."; else - qDebug() << "Searching sha1sum node for " << nodename; + qDebug() << "Searching sha1sum node for" << nodename; QString sha1Value = QString::fromLatin1(sha1sum.toHex().constData()); for (int i = 0; i < list.size(); ++i) { QDomNode curNode = list.at(i); QDomNode nameTag = curNode.firstChildElement(scName); if ((!nameTag.isNull() && nameTag.toElement().text() == nodename) || nodename.isEmpty()) { QDomNode sha1Node = curNode.firstChildElement(scSHA1); + QDomNode newSha1Node = doc.createElement(scSHA1); + newSha1Node.appendChild(doc.createTextNode(sha1Value)); + if (!sha1Node.isNull() && sha1Node.hasChildNodes()) { QDomNode sha1NodeChild = sha1Node.firstChild(); QString sha1OldValue = sha1NodeChild.nodeValue(); @@ -648,19 +668,12 @@ static void writeSHA1ToNodeWithName(QDomDocument &doc, QDomNodeList &list, const qDebug() << "- clearing the old sha1sum" << sha1OldValue; sha1Node.removeChild(sha1NodeChild); } - } else { - sha1Node = doc.createElement(scSHA1); - //Create also unique metadata name - if (!metadataName.isEmpty()) { - qDebug() << "Writing the metadata node with name " << metadataName; - QDomNode metaName = doc.createElement(QLatin1String("MetadataName")); - metaName.appendChild(doc.createTextNode(metadataName)); - curNode.appendChild(metaName); - } } + if (sha1Node.isNull()) + curNode.appendChild(newSha1Node); + else + curNode.replaceChild(newSha1Node, sha1Node); qDebug() << "- writing the sha1sum" << sha1Value; - sha1Node.appendChild(doc.createTextNode(sha1Value)); - curNode.appendChild(sha1Node); } } } @@ -721,7 +734,21 @@ QStringList QInstallerTools::unifyMetadata(const QStringList &entryList, const Q tmp.open(QFile::ReadOnly); const QByteArray sha1Sum = QInstaller::calculateHash(&tmp, QCryptographicHash::Sha1); QDomNodeList elements = doc.elementsByTagName(QLatin1String("Updates")); - writeSHA1ToNodeWithName(doc, elements, sha1Sum, QString(), metadataFilename); + writeSHA1ToNodeWithName(doc, elements, sha1Sum, QString()); + + qDebug() << "Updating the metadata node with name " << metadataFilename; + if (elements.count() > 0) { + QDomNode node = elements.at(0); + QDomNode nameTag = node.firstChildElement(QLatin1String("MetadataName")); + + QDomNode newNodeTag = doc.createElement(QLatin1String("MetadataName")); + newNodeTag.appendChild(doc.createTextNode(metadataFilename)); + + if (nameTag.isNull()) + node.appendChild(newNodeTag); + else + node.replaceChild(newNodeTag, nameTag); + } return absPaths; } @@ -852,3 +879,48 @@ void QInstallerTools::copyComponentData(const QStringList &packageDirs, const QS } } } + +void QInstallerTools::filterNewComponents(const QString &repositoryDir, QInstallerTools::PackageInfoVector &packages) +{ + QDomDocument doc; + QFile file(repositoryDir + QLatin1String("/Updates.xml")); + if (file.open(QFile::ReadOnly) && doc.setContent(&file)) { + const QDomElement root = doc.documentElement(); + if (root.tagName() != QLatin1String("Updates")) { + throw QInstaller::Error(QCoreApplication::translate("QInstaller", + "Invalid content in \"%1\".").arg(QDir::toNativeSeparators(file.fileName()))); + } + file.close(); // close the file, we read the content already + + // read the already existing updates xml content + const QDomNodeList children = root.childNodes(); + QHash hash; + for (int i = 0; i < children.count(); ++i) { + const QDomElement el = children.at(i).toElement(); + if ((!el.isNull()) && (el.tagName() == QLatin1String("PackageUpdate"))) { + QInstallerTools::PackageInfo info; + const QDomNodeList c2 = el.childNodes(); + for (int j = 0; j < c2.count(); ++j) { + const QDomElement c2Element = c2.at(j).toElement(); + if (c2Element.tagName() == scName) + info.name = c2Element.text(); + else if (c2Element.tagName() == scVersion) + info.version = c2Element.text(); + } + hash.insert(info.name, info); + } + } + + // remove all components that have no update (decision based on the version tag) + for (int i = packages.count() - 1; i >= 0; --i) { + const QInstallerTools::PackageInfo info = packages.at(i); + + // check if component already exists & version did not change + if (hash.contains(info.name) && KDUpdater::compareVersion(info.version, hash.value(info.name).version) < 1) { + packages.remove(i); // the version did not change, no need to update the component + continue; + } + qDebug() << "Update component" << info.name << "in"<< repositoryDir << "."; + } + } +} diff --git a/tools/common/repositorygen.h b/tools/common/repositorygen.h index b6317e9b7..eb2d23275 100644 --- a/tools/common/repositorygen.h +++ b/tools/common/repositorygen.h @@ -75,9 +75,11 @@ void splitMetadata(const QStringList &entryList, const QString &repoDir, QDomDoc const QHash &versionMapping); void copyMetaData(const QString &outDir, const QString &dataDir, const PackageInfoVector &packages, - const QString &appName, const QString& appVersion); + const QString &appName, const QString& appVersion, const QStringList &uniteMetadatas); void copyComponentData(const QStringList &packageDir, const QString &repoDir, PackageInfoVector *const infos); +void filterNewComponents(const QString &repositoryDir, QInstallerTools::PackageInfoVector &packages); + } // namespace QInstallerTools diff --git a/tools/repogen/repogen.cpp b/tools/repogen/repogen.cpp index 236b0b901..76d4f676a 100644 --- a/tools/repogen/repogen.cpp +++ b/tools/repogen/repogen.cpp @@ -150,6 +150,7 @@ int main(int argc, char** argv) } else if (args.first() == QLatin1String("--update-new-components")) { args.removeFirst(); updateExistingRepositoryWithNewComponents = true; + createUnifiedMetadata = false; } else if (args.first() == QLatin1String("-p") || args.first() == QLatin1String("--packages")) { args.removeFirst(); if (args.isEmpty()) { @@ -215,6 +216,17 @@ int main(int argc, char** argv) if (remove) QInstaller::removeDirectory(repositoryDir); + if (updateExistingRepositoryWithNewComponents) { + QStringList meta7z = QDir(repositoryDir).entryList(QStringList() + << QLatin1String("*_meta.7z"), QDir::Files); + if (!meta7z.isEmpty()) { + throw QInstaller::Error(QCoreApplication::translate("QInstaller", + "Cannot update \"%1\" with --update-new-components. Use --update instead. " + "Currently it is not possible to update partial components inside one 7z.") + .arg(meta7z.join(QLatin1Char(',')))); + } + } + if (!update && QFile::exists(repositoryDir) && !QDir(repositoryDir).entryList( QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty()) { @@ -233,53 +245,12 @@ int main(int argc, char** argv) packages.append(preparedPackages); if (updateExistingRepositoryWithNewComponents) { - QDomDocument doc; - QFile file(repositoryDir + QLatin1String("/Updates.xml")); - if (file.open(QFile::ReadOnly) && doc.setContent(&file)) { - const QDomElement root = doc.documentElement(); - if (root.tagName() != QLatin1String("Updates")) { - throw QInstaller::Error(QCoreApplication::translate("QInstaller", - "Invalid content in \"%1\".").arg(QDir::toNativeSeparators(file.fileName()))); - } - file.close(); // close the file, we read the content already - - // read the already existing updates xml content - const QDomNodeList children = root.childNodes(); - QHash hash; - for (int i = 0; i < children.count(); ++i) { - const QDomElement el = children.at(i).toElement(); - if ((!el.isNull()) && (el.tagName() == QLatin1String("PackageUpdate"))) { - QInstallerTools::PackageInfo info; - const QDomNodeList c2 = el.childNodes(); - for (int j = 0; j < c2.count(); ++j) { - if (c2.at(j).toElement().tagName() == scName) - info.name = c2.at(j).toElement().text(); - else if (c2.at(j).toElement().tagName() == scVersion) - info.version = c2.at(j).toElement().text(); - } - hash.insert(info.name, info); - } - } - - // remove all components that have no update (decision based on the version tag) - for (int i = packages.count() - 1; i >= 0; --i) { - const QInstallerTools::PackageInfo info = packages.at(i); - - // check if component already exists & version did not change - if (hash.contains(info.name) && KDUpdater::compareVersion(info.version, hash.value(info.name).version) < 1) { - packages.remove(i); // the version did not change, no need to update the component - continue; - } - std::cout << QString::fromLatin1("Update component \"%1\" in \"%2\".") - .arg(info.name, repositoryDir) << std::endl; - } - - if (packages.isEmpty()) { - std::cout << QString::fromLatin1("Cannot find new components to update \"%1\".") - .arg(repositoryDir) << std::endl; - return EXIT_SUCCESS; - } - } + 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; + } } QHash pathToVersionMapping = QInstallerTools::buildPathToVersionMapping(packages); @@ -296,13 +267,23 @@ int main(int argc, char** argv) 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))); + QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)), unite7zFiles); QInstallerTools::compressMetaDirectories(tmpMetaDir, tmpMetaDir, pathToVersionMapping, createComponentMetadata, createUnifiedMetadata); - QDirIterator it(repositoryDir, QStringList(QLatin1String("Updates*.xml")), QDir::Files | QDir::CaseSensitive); + QDirIterator it(repositoryDir, QStringList(QLatin1String("Updates*.xml")) + << QLatin1String("*_meta.7z"), QDir::Files | QDir::CaseSensitive); while (it.hasNext()) { it.next(); QFile::remove(it.fileInfo().absoluteFilePath()); diff --git a/tools/repogen/repogen.pri b/tools/repogen/repogen.pri new file mode 100644 index 000000000..319b137ff --- /dev/null +++ b/tools/repogen/repogen.pri @@ -0,0 +1 @@ +INCLUDEPATH += $$PWD/../common diff --git a/tools/repogen/repogen.pro b/tools/repogen/repogen.pro index f415a5988..016a8fe8e 100644 --- a/tools/repogen/repogen.pro +++ b/tools/repogen/repogen.pro @@ -1,7 +1,8 @@ TEMPLATE = app TARGET = repogen -INCLUDEPATH += . .. ../common +INCLUDEPATH += . .. +include(repogen.pri) include(../../installerfw.pri) QT -= gui -- cgit v1.2.3