From 135e59fb4395c1779a52ab113cc70f7baa53fd5d Mon Sep 17 00:00:00 2001 From: Christoph Cullmann Date: Sun, 27 Apr 2025 19:41:56 +0200 Subject: [PATCH] ensure all links survive the generations will lead to some broken links ignore that ATM, better then missing links for some icons --- generate-24px-versions.py | 2 -- src/tools/generate-symbolic-dark.cpp | 26 ++++++++++++------- src/tools/qrcAlias.cpp | 37 ++++++++++++++++++++++++---- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/generate-24px-versions.py b/generate-24px-versions.py index 7723df81..2e3608ab 100755 --- a/generate-24px-versions.py +++ b/generate-24px-versions.py @@ -166,8 +166,6 @@ def make_file_link(input_dir, output_dir, path): # Regenerate symlinks or edit SVGs, don't create dead links for icons we failed to generate symlink_source = os.readlink(path).replace('/22/', '/24/') - if not os.path.exists(symlink_source): - return if os.path.islink(file_destination): os.remove(file_destination) if not os.path.exists(file_destination): diff --git a/src/tools/generate-symbolic-dark.cpp b/src/tools/generate-symbolic-dark.cpp index a22ee3b4..365c5ea0 100644 --- a/src/tools/generate-symbolic-dark.cpp +++ b/src/tools/generate-symbolic-dark.cpp @@ -115,12 +115,27 @@ int main(int argc, char **argv) auto inputFileInfo = dirIt.nextFileInfo(); const auto inputFilePath = inputFileInfo.absoluteFilePath(); - // Skip non-files, symlinks, non-svgs and existing breeze dark icons - if (!inputFileInfo.isFile() || inputFileInfo.isSymLink() || !inputFilePath.endsWith(".svg"_L1) + // Skip non-files, non-svgs and existing breeze dark icons + if (!inputFileInfo.isFile() || !inputFilePath.endsWith(".svg"_L1) || QFileInfo::exists(QString{inputFilePath}.replace("/icons/"_L1, "/icons-dark/"_L1))) { continue; } + // create dir, might be needed for symlink + QDir outputDir = outputDirInfo.absoluteFilePath(); + const auto outputFilePath = outputDir.absoluteFilePath(QString{inputFilePath}.remove(QRE(u".*/icons/"_s))); + QFileInfo outputFileInfo(outputFilePath); + outputDir = outputFileInfo.dir(); + if (!outputDir.exists()) { + QDir::root().mkpath(outputDir.absolutePath()); + } + + // keep symlinks + if (inputFileInfo.isSymLink()) { + QFile::link(inputFileInfo.absoluteDir().relativeFilePath(inputFileInfo.symLinkTarget()), outputFilePath); + continue; + } + QFile inputFile(inputFilePath); if (!inputFile.open(QIODevice::ReadOnly)) { unreadFiles.append("\""_L1 + inputFile.fileName() + "\": "_L1 + inputFile.errorString()); @@ -134,13 +149,6 @@ int main(int argc, char **argv) continue; } - QDir outputDir = outputDirInfo.absoluteFilePath(); - const auto outputFilePath = outputDir.absoluteFilePath(QString{inputFilePath}.remove(QRE(u".*/icons/"_s))); - QFileInfo outputFileInfo(outputFilePath); - outputDir = outputFileInfo.dir(); - if (!outputDir.exists()) { - QDir::root().mkpath(outputDir.absolutePath()); - } QFile outputFile(outputFilePath); if (!outputFile.open(QIODevice::WriteOnly)) { unwrittenFiles.append("\""_L1 + outputFile.fileName() + "\": "_L1 + outputFile.errorString()); diff --git a/src/tools/qrcAlias.cpp b/src/tools/qrcAlias.cpp index b22848cc..09fb43b4 100644 --- a/src/tools/qrcAlias.cpp +++ b/src/tools/qrcAlias.cpp @@ -145,8 +145,8 @@ static void generateQRCAndCheckInputs(const QStringList &indirs, const QString & // loop over the inputs, remember if we do look at generated stuff for checks bool generatedIcons = false; - QSet checkedFiles; - bool themeFileFound = false; + QSet checkedFiles, filesInResource; + bool themeFileFound = false, icons24Seen = false; for (const auto &indir : indirs) { // go to input dir to have proper relative paths if (!QDir::setCurrent(indir)) { @@ -188,7 +188,10 @@ static void generateQRCAndCheckInputs(const QStringList &indirs, const QString & if (isLink) { // empty canonical path means not found if (fullPath.isEmpty()) { - qFatal() << "Broken symlink" << file << "in input directory" << indir; + // qFatal() << "Broken symlink" << file << "in input directory" << indir; + // ATM we allow that as otherwise the generation misses links + // see https://invent.kde.org/frameworks/breeze-icons/-/merge_requests/467 + continue; } // check that we don't link external stuff @@ -216,19 +219,43 @@ static void generateQRCAndCheckInputs(const QStringList &indirs, const QString & // write the one alias to file entry out.write(QStringLiteral(" %2\n").arg(file, fullPath).toUtf8()); + printf("%s\n", qPrintable(file)); + + // remember for checks below + filesInResource.insert(file); + if (!icons24Seen) { + icons24Seen = file.contains(QLatin1String("/24/")); + } } // starting with the second directory we look at generated icons generatedIcons = true; } + out.write("\n"); + out.write("\n"); + if (!themeFileFound) { // without any theme file the icon theme will not work at runtime qFatal() << "No theme file found!"; } - out.write("\n"); - out.write("\n"); + // ensure we have some icons that we know must exist + for (const QString &knownIcon : {QStringLiteral("devices/16/input-keyboard.svg"), QStringLiteral("emblems/22/emblem-symbolic-link.svg")}) { + if (!filesInResource.contains(knownIcon)) { + qFatal() << "Icon" << knownIcon << "missing!"; + } + } + + // ensure some 24 links are there, if any 24 stuff got generated + // see https://invent.kde.org/frameworks/breeze-icons/-/merge_requests/467 + if (icons24Seen) { + for (const QString &knownIcon : {QStringLiteral("actions/24/list-remove-symbolic.svg")}) { + if (!filesInResource.contains(knownIcon)) { + qFatal() << "Generated 24px icon link" << knownIcon << "missing!"; + } + } + } } int main(int argc, char *argv[])