aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@digia.com>2012-11-27 10:52:28 +0100
committerJoerg Bornemann <joerg.bornemann@digia.com>2012-11-27 15:37:33 +0100
commit331ddc389f34a0ca089232b1e96e9476f1779062 (patch)
treef4328ba20d63af64ca034675e5c3e17e9526b7d1
parentee7b117b62d220e7ea3f38168ef5e07bd41786d6 (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.cpp35
-rw-r--r--src/lib/buildgraph/artifactcleaner.h4
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