1
mirror of https://invent.kde.org/network/falkon.git synced 2024-11-11 01:22:10 +01:00

QzTools: Add copyRecursively and removeRecursively

This commit is contained in:
David Rosca 2018-03-31 15:08:06 +02:00
parent 93af3896ee
commit 3dae3edff5
No known key found for this signature in database
GPG Key ID: EBC3FC294452C6D8
8 changed files with 170 additions and 29 deletions

View File

@ -23,7 +23,7 @@
#define FALKONTEST_MAIN(Test) \ #define FALKONTEST_MAIN(Test) \
int main(int argc, char **argv) \ int main(int argc, char **argv) \
{ \ { \
QzTools::removeDir(QDir::tempPath() + QSL("/Falkon-test")); \ QzTools::removeRecursively(QDir::tempPath() + QSL("/Falkon-test")); \
MainApplication::setTestModeEnabled(true); \ MainApplication::setTestModeEnabled(true); \
MainApplication app(argc, argv); \ MainApplication app(argc, argv); \
QTEST_DISABLE_KEYPAD_NAVIGATION; \ QTEST_DISABLE_KEYPAD_NAVIGATION; \

View File

@ -271,6 +271,110 @@ void QzToolsTest::ensureUniqueFilename()
} }
} }
static void createTestDirectoryStructure(const QString &path)
{
QDir().mkdir(path);
QDir dir(path);
dir.mkdir("dir1");
dir.mkdir("dir2");
dir.mkdir("dir3");
dir.cd("dir1");
dir.mkdir("dir1_1");
dir.mkdir("dir1_2");
dir.mkdir("dir1_3");
dir.cdUp();
dir.cd("dir3");
dir.mkdir("dir3_1");
QFile file(path + "/dir1/dir1_2/file1.txt");
file.open(QFile::WriteOnly);
file.write("test");
file.close();
}
void QzToolsTest::copyRecursivelyTest()
{
const QString testDir = createPath("copyRecursivelyTest");
createTestDirectoryStructure(testDir);
QVERIFY(!QFileInfo(testDir + "-copy").exists());
// Copy to non-existant target
QCOMPARE(QzTools::copyRecursively(testDir, testDir + "-copy"), true);
QCOMPARE(QFileInfo(testDir + "-copy").isDir(), true);
QCOMPARE(QFileInfo(testDir + "-copy/dir1").isDir(), true);
QCOMPARE(QFileInfo(testDir + "-copy/dir2").isDir(), true);
QCOMPARE(QFileInfo(testDir + "-copy/dir3").isDir(), true);
QCOMPARE(QFileInfo(testDir + "-copy/dir1/dir1_1").isDir(), true);
QCOMPARE(QFileInfo(testDir + "-copy/dir1/dir1_2").isDir(), true);
QCOMPARE(QFileInfo(testDir + "-copy/dir1/dir1_3").isDir(), true);
QCOMPARE(QFileInfo(testDir + "-copy/dir3/dir3_1").isDir(), true);
QCOMPARE(QFileInfo(testDir + "-copy/dir1/dir1_2/file1.txt").isFile(), true);
QFile file(testDir + "-copy/dir1/dir1_2/file1.txt");
file.open(QFile::ReadOnly);
QCOMPARE(file.readAll(), QByteArray("test"));
// Copy to target that already exists
QCOMPARE(QzTools::copyRecursively(testDir, testDir + "-copy"), false);
// Cleanup
QCOMPARE(QzTools::removeRecursively(testDir), true);
QCOMPARE(QzTools::removeRecursively(testDir + "-copy"), true);
}
void QzToolsTest::removeRecursivelyTest()
{
const QString testDir = createPath("removeRecursivelyTest");
createTestDirectoryStructure(testDir);
QCOMPARE(QzTools::copyRecursively(testDir, testDir + "-copy"), true);
QCOMPARE(QzTools::removeRecursively(testDir + "-copy"), true);
QCOMPARE(QFileInfo(testDir + "-copy").exists(), false);
// Remove non-existant path returns success
QCOMPARE(QzTools::removeRecursively(testDir + "-copy"), true);
QCOMPARE(QzTools::copyRecursively(testDir, testDir + "-copy2"), true);
QFile dir(testDir + "-copy2");
dir.setPermissions(dir.permissions() & ~(QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther));
QCOMPARE(QzTools::removeRecursively(testDir + "-copy2"), false);
dir.setPermissions(dir.permissions() | QFile::WriteOwner);
QCOMPARE(QzTools::removeRecursively(testDir + "-copy2"), true);
// Cleanup
QCOMPARE(QzTools::removeRecursively(testDir), true);
}
void QzToolsTest::dontFollowSymlinksTest()
{
const QString testDir = createPath("removeRecursivelyTest");
createTestDirectoryStructure(testDir);
QDir().mkpath(testDir + "/subdir");
QFile::link(testDir, testDir + "/subdir/link");
QVERIFY(QzTools::removeRecursively(testDir + "/subdir"));
QVERIFY(!QFile::exists(testDir + "/subdir"));
QVERIFY(QFile::exists(testDir));
QDir().mkpath(testDir + "/subdir/normalfolder");
QFile::link("..", testDir + "/subdir/link");
QVERIFY(QzTools::copyRecursively(testDir + "/subdir", testDir + "/subdir2"));
QCOMPARE(QFile::exists(testDir + "/subdir2/link"), true);
QCOMPARE(QFile::exists(testDir + "/subdir2/normalfolder"), true);
// Cleanup
QCOMPARE(QzTools::removeRecursively(testDir), true);
}
QString QzToolsTest::createPath(const char *file) const QString QzToolsTest::createPath(const char *file) const
{ {
return m_tmpPath + QL1S("/") + file; return m_tmpPath + QL1S("/") + file;

View File

@ -41,6 +41,9 @@ private Q_SLOTS:
void escapeSqlGlobString(); void escapeSqlGlobString();
void ensureUniqueFilename(); void ensureUniqueFilename();
void copyRecursivelyTest();
void removeRecursivelyTest();
void dontFollowSymlinksTest();
private: private:
QString createPath(const char *file) const; QString createPath(const char *file) const;

View File

@ -787,7 +787,7 @@ void MainApplication::saveSettings()
m_cookieJar->deleteAllCookies(); m_cookieJar->deleteAllCookies();
} }
if (deleteCache) { if (deleteCache) {
QzTools::removeDir(mApp->webProfile()->cachePath()); QzTools::removeRecursively(mApp->webProfile()->cachePath());
} }
m_searchEnginesManager->saveSettings(); m_searchEnginesManager->saveSettings();

View File

@ -115,7 +115,7 @@ bool ProfileManager::removeProfile(const QString &profileName)
return false; return false;
} }
QzTools::removeDir(dir.absolutePath()); QzTools::removeRecursively(dir.absolutePath());
return true; return true;
} }

View File

@ -67,22 +67,22 @@ void ClearPrivateData::clearLocalStorage()
{ {
const QString profile = DataPaths::currentProfilePath(); const QString profile = DataPaths::currentProfilePath();
QzTools::removeDir(profile + "/Local Storage"); QzTools::removeRecursively(profile + "/Local Storage");
} }
void ClearPrivateData::clearWebDatabases() void ClearPrivateData::clearWebDatabases()
{ {
const QString profile = DataPaths::currentProfilePath(); const QString profile = DataPaths::currentProfilePath();
QzTools::removeDir(profile + "/IndexedDB"); QzTools::removeRecursively(profile + "/IndexedDB");
QzTools::removeDir(profile + "/databases"); QzTools::removeRecursively(profile + "/databases");
} }
void ClearPrivateData::clearCache() void ClearPrivateData::clearCache()
{ {
const QString profile = DataPaths::currentProfilePath(); const QString profile = DataPaths::currentProfilePath();
QzTools::removeDir(profile + "/GPUCache"); QzTools::removeRecursively(profile + "/GPUCache");
mApp->webProfile()->clearHttpCache(); mApp->webProfile()->clearHttpCache();
} }

View File

@ -48,6 +48,8 @@
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <windows.h> #include <windows.h>
#else
#include <unistd.h>
#endif #endif
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
@ -131,35 +133,67 @@ void QzTools::centerWidgetToParent(QWidget* w, QWidget* parent)
w->move(p); w->move(p);
} }
bool QzTools::removeFile(const QString &fullFileName) bool QzTools::removeRecursively(const QString &filePath)
{ {
QFile f(fullFileName); const QFileInfo fileInfo(filePath);
if (f.exists()) { if (!fileInfo.exists() && !fileInfo.isSymLink()) {
return f.remove(); return true;
} }
else { if (fileInfo.isDir() && !fileInfo.isSymLink()) {
QDir dir(filePath);
dir = dir.canonicalPath();
if (dir.isRoot() || dir.path() == QDir::home().canonicalPath()) {
qCritical() << "Attempt to remove root/home directory" << dir;
return false; return false;
} }
const QStringList fileNames = dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System);
for (const QString &fileName : fileNames) {
if (!removeRecursively(filePath + QLatin1Char('/') + fileName)) {
return false;
}
}
if (!QDir::root().rmdir(dir.path())) {
return false;
}
} else if (!QFile::remove(filePath)) {
return false;
}
return true;
} }
void QzTools::removeDir(const QString &d) bool QzTools::copyRecursively(const QString &sourcePath, const QString &targetPath)
{ {
QDir dir(d); const QFileInfo srcFileInfo(sourcePath);
if (dir.exists()) { if (srcFileInfo.isDir() && !srcFileInfo.isSymLink()) {
const QFileInfoList list = dir.entryInfoList(); QDir targetDir(targetPath);
QFileInfo fi; targetDir.cdUp();
for (int l = 0; l < list.size(); l++) { if (!targetDir.mkdir(QFileInfo(targetPath).fileName())) {
fi = list.at(l); return false;
if (fi.isDir() && fi.fileName() != QLatin1String(".") && fi.fileName() != QLatin1String("..")) {
QzTools::removeDir(fi.absoluteFilePath());
} }
else if (fi.isFile()) { const QStringList fileNames = QDir(sourcePath).entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System);
QzTools::removeFile(fi.absoluteFilePath()); for (const QString &fileName : fileNames) {
const QString newSourcePath = sourcePath + QL1C('/') + fileName;
const QString newTargetPath = targetPath + QL1C('/') + fileName;
if (!copyRecursively(newSourcePath, newTargetPath)) {
return false;
} }
} }
dir.rmdir(d); #ifndef Q_OS_WIN
} else if (srcFileInfo.isSymLink()) {
const QByteArray pathData = sourcePath.toLocal8Bit();
char buf[1024];
ssize_t len = readlink(pathData.constData(), buf, sizeof(buf) - 1);
if (len < 0) {
qWarning() << "Error getting symlink path" << pathData;
return false;
} }
buf[len] = '\0';
return QFile::link(QString::fromLocal8Bit(buf), targetPath);
#endif
} else if (!QFile::copy(sourcePath, targetPath)) {
return false;
}
return true;
} }
/* Finds same part of @one in @other from the beginning */ /* Finds same part of @one in @other from the beginning */

View File

@ -43,8 +43,8 @@ public:
static void centerWidgetOnScreen(QWidget* w); static void centerWidgetOnScreen(QWidget* w);
static void centerWidgetToParent(QWidget* w, QWidget* parent); static void centerWidgetToParent(QWidget* w, QWidget* parent);
static bool removeFile(const QString &fullFileName); static bool removeRecursively(const QString &filePath);
static void removeDir(const QString &d); static bool copyRecursively(const QString &sourcePath, const QString &targetPath);
static QString samePartOfStrings(const QString &one, const QString &other); static QString samePartOfStrings(const QString &one, const QString &other);
static QString urlEncodeQueryString(const QUrl &url); static QString urlEncodeQueryString(const QUrl &url);