diff options
author | Kai Koehne <kai.koehne@qt.io> | 2020-07-16 10:54:14 +0200 |
---|---|---|
committer | Topi Reinio <topi.reinio@qt.io> | 2022-09-02 13:09:37 +0200 |
commit | ec1b6437f7e40fcbda45e3b578832887e7836d88 (patch) | |
tree | 5878cdb4ba6103d6ca15b39c429d244c60d7dfbc | |
parent | 723bca3fae97de0b39d6f2d015e68baf36ea649c (diff) |
qtattributionsscanner: Support multiple license files
Accept a new LicenseFiles array that allows to list multiple license
files. This avoids the need to artificially concatenate licenses in
one file.
Change-Id: Ia9db77b3bc0ea7fc6072d0296da5ea3cfce44b59
Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io>
(cherry picked from commit db87f5b27ce02e51b0e38aaa8473a40b0d87094a)
Reviewed-by: Kai Koehne <kai.koehne@qt.io>
12 files changed, 126 insertions, 33 deletions
diff --git a/src/qtattributionsscanner/jsongenerator.cpp b/src/qtattributionsscanner/jsongenerator.cpp index 44bb2a6fe..db5ba3b8e 100644 --- a/src/qtattributionsscanner/jsongenerator.cpp +++ b/src/qtattributionsscanner/jsongenerator.cpp @@ -55,7 +55,13 @@ static QJsonObject generate(Package package) obj.insert(QStringLiteral("License"), package.license); obj.insert(QStringLiteral("LicenseId"), package.licenseId); - obj.insert(QStringLiteral("LicenseFile"), package.licenseFile); + if (package.licenseFiles.isEmpty()) + obj.insert(QStringLiteral("LicenseFile"), QString()); + else if (package.licenseFiles.size() == 1) + obj.insert(QStringLiteral("LicenseFile"), package.licenseFiles.first()); + else + obj.insert(QStringLiteral("LicenseFiles"), + QJsonArray::fromStringList(package.licenseFiles)); obj.insert(QStringLiteral("Copyright"), package.copyright); obj.insert(QStringLiteral("PackageComment"), package.packageComment); diff --git a/src/qtattributionsscanner/package.h b/src/qtattributionsscanner/package.h index 60382fcc1..1595a918a 100644 --- a/src/qtattributionsscanner/package.h +++ b/src/qtattributionsscanner/package.h @@ -50,7 +50,7 @@ struct Package { QString license; // The license under which the package is distributed. Mandatory. QString licenseId; // see https://spdx.org/licenses/. Optional. - QString licenseFile; // path to file containing the license text. Optional. + QStringList licenseFiles; // path to files containing the license text. Optional. QString copyright; // A list of copyright owners. Mandatory. diff --git a/src/qtattributionsscanner/qdocgenerator.cpp b/src/qtattributionsscanner/qdocgenerator.cpp index d1c69bdfb..57da231d3 100644 --- a/src/qtattributionsscanner/qdocgenerator.cpp +++ b/src/qtattributionsscanner/qdocgenerator.cpp @@ -140,20 +140,20 @@ static void generate(QTextStream &out, const Package &package, const QDir &baseD out << package.license << ".\n\n"; } - if (!package.licenseFile.isEmpty()) { - QFile file(package.licenseFile); + foreach (const QString &licenseFile, package.licenseFiles) { + QFile file(licenseFile); if (!file.open(QIODevice::ReadOnly)) { - if (logLevel != SilentLog) - std::cerr << qPrintable( - tr("Path %1 : cannot open license file %2.") - .arg(QDir::toNativeSeparators(package.path)) - .arg(QDir::toNativeSeparators(package.licenseFile)) - ) << "*/\n"; + if (logLevel != SilentLog) { + std::cerr << qPrintable(tr("Path %1 : cannot open license file %2.\n") + .arg(QDir::toNativeSeparators(package.path)) + .arg(QDir::toNativeSeparators(licenseFile))); + out << "*/\n"; + } return; } out << "\\badcode\n"; out << QString::fromUtf8(file.readAll()).trimmed(); - out << "\n\\endcode\n"; + out << "\n\\endcode\n\n"; } out << "*/\n"; } diff --git a/src/qtattributionsscanner/scanner.cpp b/src/qtattributionsscanner/scanner.cpp index 9c1202166..a4e7d1994 100644 --- a/src/qtattributionsscanner/scanner.cpp +++ b/src/qtattributionsscanner/scanner.cpp @@ -81,6 +81,19 @@ static void validatePackage(Package &p, const QString &filePath, LogLevel logLev } } +static QStringList toStringList(const QJsonValue &value) +{ + QStringList result; + for (auto iter : value.toArray()) { + if (iter.type() != QJsonValue::String) { + result.clear(); + return result; + } + result.push_back(iter.toString()); + } + return result; +} + // Transforms a JSON object into a Package object static Package readPackage(const QJsonObject &object, const QString &filePath, LogLevel logLevel) { @@ -91,7 +104,8 @@ static Package readPackage(const QJsonObject &object, const QString &filePath, L for (auto iter = object.constBegin(); iter != object.constEnd(); ++iter) { const QString key = iter.key(); - if (!iter.value().isString() && key != QLatin1String("QtParts")) { + if (!iter.value().isString() && key != QLatin1String("QtParts") + && key != QLatin1String("LicenseFiles")) { if (logLevel != SilentLog) std::cerr << qPrintable(tr("File %1: Expected JSON string as value of %2.").arg( QDir::toNativeSeparators(filePath), key)) << std::endl; @@ -117,7 +131,16 @@ static Package readPackage(const QJsonObject &object, const QString &filePath, L } else if (key == QLatin1String("LicenseId")) { p.licenseId = value; } else if (key == QLatin1String("LicenseFile")) { - p.licenseFile = QDir(directory).absoluteFilePath(value); + p.licenseFiles = QStringList(QDir(directory).absoluteFilePath(value)); + } else if (key == QLatin1String("LicenseFiles")) { + auto strings = toStringList(iter.value()); + if (strings.isEmpty() && (logLevel != SilentLog)) + std::cerr << qPrintable(tr("File %1: Expected JSON array of strings in %2.") + .arg(QDir::toNativeSeparators(filePath), key)) + << std::endl; + const QDir dir(directory); + for (auto iter : strings) + p.licenseFiles.push_back(dir.absoluteFilePath(iter)); } else if (key == QLatin1String("Copyright")) { p.copyright = value; } else if (key == QLatin1String("PackageComment")) { @@ -129,15 +152,12 @@ static Package readPackage(const QJsonObject &object, const QString &filePath, L } else if (key == QLatin1String("QtUsage")) { p.qtUsage = value; } else if (key == QLatin1String("QtParts")) { - const QVariantList variantList = iter.value().toArray().toVariantList(); - for (const QVariant &v: variantList) { - if (v.type() != QVariant::String && logLevel != SilentLog) { - std::cerr << qPrintable(tr("File %1: Expected JSON string in array of %2.").arg( - QDir::toNativeSeparators(filePath), key)) - << std::endl; - } - p.qtParts.append(v.toString()); - } + auto parts = toStringList(iter.value()); + if (parts.isEmpty() && (logLevel != SilentLog)) + std::cerr << qPrintable(tr("File %1: Expected JSON array of strings in %2.") + .arg(QDir::toNativeSeparators(filePath), key)) + << std::endl; + p.qtParts = parts; } else { if (logLevel != SilentLog) std::cerr << qPrintable(tr("File %1: Unknown key %2.").arg( @@ -207,7 +227,7 @@ static Package parseChromiumFile(QFile &file, const QString &filePath, LogLevel QString licenseFile = fields[QStringLiteral("License File")]; if (licenseFile != QString() && licenseFile != QLatin1String("NOT_SHIPPED")) { - p.licenseFile = QDir(directory).absoluteFilePath(licenseFile); + p.licenseFiles = QStringList(QDir(directory).absoluteFilePath(licenseFile)); } else { // Look for a LICENSE or COPYING file as a fallback QDir dir = directory; @@ -217,7 +237,7 @@ static Package parseChromiumFile(QFile &file, const QString &filePath, LogLevel const QFileInfoList entries = dir.entryInfoList(); if (!entries.empty()) - p.licenseFile = entries.at(0).absoluteFilePath(); + p.licenseFiles = QStringList(entries.at(0).absoluteFilePath()); } validatePackage(p, filePath, logLevel); diff --git a/tests/auto/qtattributionsscanner/qtattributionsscanner.pro b/tests/auto/qtattributionsscanner/qtattributionsscanner.pro index aa8442a88..9c17783e1 100644 --- a/tests/auto/qtattributionsscanner/qtattributionsscanner.pro +++ b/tests/auto/qtattributionsscanner/qtattributionsscanner.pro @@ -7,6 +7,9 @@ DISTFILES += \ testdata/good/expected.json \ testdata/good/expected.error \ testdata/warnings/incomplete/qt_attribution.json \ + testdata/good/variants/qt_attribution_test.json \ + testdata/good/variants/expected.json \ + testdata/good/variants/expected.error \ testdata/warnings/incomplete/expected.json \ testdata/warnings/incomplete/expected.error \ testdata/warnings/unknown/qt_attribution.json \ diff --git a/tests/auto/qtattributionsscanner/testdata/good/expected.json b/tests/auto/qtattributionsscanner/testdata/good/expected.json index 1f54c13e6..244687192 100644 --- a/tests/auto/qtattributionsscanner/testdata/good/expected.json +++ b/tests/auto/qtattributionsscanner/testdata/good/expected.json @@ -10,7 +10,7 @@ "LicenseFile": "", "LicenseId": "", "Name": "Test", - "PackageComment":"", + "PackageComment": "", "Path": "%{PWD}/chromium", "QDocModule": "qtwebengine", "QtParts": [ @@ -22,39 +22,64 @@ { "Copyright": "Copyright", "Description": "Multi\nLine\nDescription", + "DownloadLocation": "www.qt.io/1.0", + "Files": "", "Homepage": "www.qt.io", "Id": "complete", "License": "License", "LicenseFile": "%{PWD}/complete/LICENSE", "LicenseId": "xxx", "Name": "Complete", - "PackageComment":"just a test package", + "PackageComment": "just a test package", "Path": "%{PWD}/complete", - "Files": "", "QDocModule": "qtest", - "QtParts": [ "examples" ], + "QtParts": [ + "examples" + ], "QtUsage": "Multi\nLine\nUsage", - "Version": "1.0", - "DownloadLocation": "www.qt.io/1.0" + "Version": "1.0" }, { "Copyright": "Copyright", "Description": "", + "DownloadLocation": "", + "Files": "", "Homepage": "", "Id": "minimal", "License": "License", "LicenseFile": "", "LicenseId": "", "Name": "Minimal", - "PackageComment":"", + "PackageComment": "", "Path": "%{PWD}/minimal", + "QDocModule": "qtest", + "QtParts": [ + "libs" + ], + "QtUsage": "Usage", + "Version": "" + }, + { + "Copyright": "", + "Description": "", + "DownloadLocation": "", "Files": "", + "Homepage": "", + "Id": "variants", + "License": "License", + "LicenseFiles": [ + "%{PWD}/variants/LICENSE1.txt", + "%{PWD}/variants/LICENSE2.txt" + ], + "LicenseId": "", + "Name": "Variants Test", + "PackageComment": "", + "Path": "%{PWD}/variants", "QDocModule": "qtest", "QtParts": [ "libs" ], "QtUsage": "Usage", - "Version": "", - "DownloadLocation": "" + "Version": "" } ] diff --git a/tests/auto/qtattributionsscanner/testdata/good/variants/LICENSE1.txt b/tests/auto/qtattributionsscanner/testdata/good/variants/LICENSE1.txt new file mode 100644 index 000000000..716287c92 --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/good/variants/LICENSE1.txt @@ -0,0 +1 @@ +LICENSE1
\ No newline at end of file diff --git a/tests/auto/qtattributionsscanner/testdata/good/variants/LICENSE2.txt b/tests/auto/qtattributionsscanner/testdata/good/variants/LICENSE2.txt new file mode 100644 index 000000000..3671b8928 --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/good/variants/LICENSE2.txt @@ -0,0 +1 @@ +LICENSE2
\ No newline at end of file diff --git a/tests/auto/qtattributionsscanner/testdata/good/variants/expected.error b/tests/auto/qtattributionsscanner/testdata/good/variants/expected.error new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/good/variants/expected.error diff --git a/tests/auto/qtattributionsscanner/testdata/good/variants/expected.json b/tests/auto/qtattributionsscanner/testdata/good/variants/expected.json new file mode 100644 index 000000000..5300c6297 --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/good/variants/expected.json @@ -0,0 +1,25 @@ +[ + { + "Copyright": "", + "Description": "", + "DownloadLocation": "", + "Files": "", + "Homepage": "", + "Id": "variants", + "License": "License", + "LicenseFiles": [ + "%{PWD}/LICENSE1.txt", + "%{PWD}/LICENSE2.txt" + ], + "LicenseId": "", + "Name": "Variants Test", + "PackageComment": "", + "Path": "%{PWD}", + "QDocModule": "qtest", + "QtParts": [ + "libs" + ], + "QtUsage": "Usage", + "Version": "" + } +] diff --git a/tests/auto/qtattributionsscanner/testdata/good/variants/qt_attribution_test.json b/tests/auto/qtattributionsscanner/testdata/good/variants/qt_attribution_test.json new file mode 100644 index 000000000..072523114 --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/good/variants/qt_attribution_test.json @@ -0,0 +1,9 @@ +{ + "Id": "variants", + "Name": "Variants Test", + + "QDocModule": "qtest", + "QtUsage": "Usage", + "License": "License", + "LicenseFiles": [ "LICENSE1.txt", "LICENSE2.txt" ] +} diff --git a/tests/auto/qtattributionsscanner/tst_qtattributionsscanner.cpp b/tests/auto/qtattributionsscanner/tst_qtattributionsscanner.cpp index e1c5e8f3e..31d7c7847 100644 --- a/tests/auto/qtattributionsscanner/tst_qtattributionsscanner.cpp +++ b/tests/auto/qtattributionsscanner/tst_qtattributionsscanner.cpp @@ -84,6 +84,9 @@ void tst_qtattributionsscanner::test_data() << QStringLiteral("good/minimal/qt_attribution_test.json") << QStringLiteral("good/minimal/expected.json") << QStringLiteral("good/minimal/expected.error"); + QTest::newRow("variants") << QStringLiteral("good/variants/qt_attribution_test.json") + << QStringLiteral("good/variants/expected.json") + << QStringLiteral("good/variants/expected.error"); } void tst_qtattributionsscanner::readExpectedFile(const QString &baseDir, const QString &fileName, QByteArray *content) |