diff options
author | Christian Kandeler <christian.kandeler@digia.com> | 2012-11-27 10:52:28 +0100 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@digia.com> | 2012-11-27 15:37:33 +0100 |
commit | 331ddc389f34a0ca089232b1e96e9476f1779062 (patch) | |
tree | f4328ba20d63af64ca034675e5c3e17e9526b7d1 | |
parent | ee7b117b62d220e7ea3f38168ef5e07bd41786d6 (diff) |
Fix directory removal when cleaning up.
We currently fail to delete a lot of directories because we do it non-
recursively and parent directories might be encountered before their
children. Fix this by doing recursive iteration.
Change-Id: I53c23608088548b4a8eb434d6131977918d183db
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
-rw-r--r-- | src/lib/buildgraph/artifactcleaner.cpp | 35 | ||||
-rw-r--r-- | src/lib/buildgraph/artifactcleaner.h | 4 |
2 files changed, 34 insertions, 5 deletions
diff --git a/src/lib/buildgraph/artifactcleaner.cpp b/src/lib/buildgraph/artifactcleaner.cpp index 29d305800..33c56b897 100644 --- a/src/lib/buildgraph/artifactcleaner.cpp +++ b/src/lib/buildgraph/artifactcleaner.cpp @@ -34,11 +34,13 @@ #include "transformer.h" #include <logging/logger.h> +#include <logging/translator.h> #include <tools/error.h> #include <tools/fileinfo.h> #include <QCoreApplication> #include <QDir> +#include <QDirIterator> #include <QFileInfo> #include <QSet> #include <QString> @@ -49,7 +51,7 @@ namespace Internal { static void printRemovalMessage(const QString &path, bool dryRun) { if (dryRun) - qbsInfo() << QCoreApplication::translate("qbs", "Would remove '%1'.").arg(path); + qbsInfo() << Tr::tr("Would remove '%1'.").arg(path); else qbsDebug() << "Removing '" << path << "'."; } @@ -125,7 +127,6 @@ void ArtifactCleaner::cleanup(const QList<BuildProduct::Ptr> &products, bool rem { TimedActivityLogger logger(QLatin1String("Cleaning up")); - // TODO: Parallelize? QSet<QString> directories; foreach (const BuildProduct::ConstPtr &product, products) { CleanupVisitor visitor(!buildOptions.keepGoing, buildOptions.dryRun, removeAll); @@ -136,11 +137,35 @@ void ArtifactCleaner::cleanup(const QList<BuildProduct::Ptr> &products, bool rem // Directories created during the build are not artifacts (TODO: should they be?), // so we have to clean them up manually. foreach (const QString &dir, directories) { - printRemovalMessage(dir, buildOptions.dryRun); - if (!buildOptions.dryRun) - QDir(dir).rmdir(QLatin1String(".")); // Failure non-fatal? + if (FileInfo(dir).exists()) + removeEmptyDirectories(dir, buildOptions); } +} +void ArtifactCleaner::removeEmptyDirectories(const QString &rootDir, const BuildOptions &options, + bool *isEmpty) +{ + bool subTreeIsEmpty = true; + QDirIterator it(rootDir, QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); + while (it.hasNext()) { + it.next(); + if (it.fileInfo().isDir()) + removeEmptyDirectories(it.filePath(), options, &subTreeIsEmpty); + else + subTreeIsEmpty = false; + } + if (subTreeIsEmpty) { + printRemovalMessage(rootDir, options.dryRun); + if (!QDir::root().rmdir(rootDir)) { + Error error(Tr::tr("Failure to remove empty directory '%1'.").arg(rootDir)); + if (options.keepGoing) + qbsWarning() << error.toString(); + else + throw Error(error); + } + } else if (isEmpty) { + *isEmpty = subTreeIsEmpty; + } } } // namespace Internal diff --git a/src/lib/buildgraph/artifactcleaner.h b/src/lib/buildgraph/artifactcleaner.h index 3c9fcaa39..ca9cbe31e 100644 --- a/src/lib/buildgraph/artifactcleaner.h +++ b/src/lib/buildgraph/artifactcleaner.h @@ -44,6 +44,10 @@ class ArtifactCleaner public: void cleanup(const QList<BuildProduct::Ptr> &products, bool removeAll, const BuildOptions &buildOptions); + +private: + void removeEmptyDirectories(const QString &rootDir, const BuildOptions &options, + bool *isEmpty = 0); }; } // namespace Internal |