refactor: use std::filesystem for file copy

Signed-off-by: flow <flowlnlnln@gmail.com>
This commit is contained in:
flow 2022-07-30 19:38:56 -03:00
parent 30abb65368
commit 5932f36285
No known key found for this signature in database
GPG Key ID: 8D0F221F0A59F469

View File

@ -37,6 +37,7 @@
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QDirIterator>
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QSaveFile> #include <QSaveFile>
@ -58,6 +59,8 @@
#include <utime.h> #include <utime.h>
#endif #endif
#include <filesystem>
namespace FS { namespace FS {
void ensureExists(const QDir& dir) void ensureExists(const QDir& dir)
@ -128,6 +131,8 @@ bool ensureFolderPathExists(QString foldernamepath)
bool copy::operator()(const QString& offset) bool copy::operator()(const QString& offset)
{ {
using copy_opts = std::filesystem::copy_options;
// NOTE always deep copy on windows. the alternatives are too messy. // NOTE always deep copy on windows. the alternatives are too messy.
#if defined Q_OS_WIN32 #if defined Q_OS_WIN32
m_followSymlinks = true; m_followSymlinks = true;
@ -136,47 +141,40 @@ bool copy::operator()(const QString& offset)
auto src = PathCombine(m_src.absolutePath(), offset); auto src = PathCombine(m_src.absolutePath(), offset);
auto dst = PathCombine(m_dst.absolutePath(), offset); auto dst = PathCombine(m_dst.absolutePath(), offset);
QFileInfo currentSrc(src); std::error_code err;
if (!currentSrc.exists())
return false;
if (!m_followSymlinks && currentSrc.isSymLink()) { std::filesystem::copy_options opt = copy_opts::none;
qDebug() << "creating symlink" << src << " - " << dst;
if (!ensureFilePathExists(dst)) { // The default behavior is to follow symlinks
qWarning() << "Cannot create path!"; if (!m_followSymlinks)
return false; opt |= copy_opts::copy_symlinks;
}
return QFile::link(currentSrc.symLinkTarget(), dst);
} else if (currentSrc.isFile()) { // We can't use copy_opts::recursive because we need to take into account the
qDebug() << "copying file" << src << " - " << dst; // blacklisted paths, so we iterate over the source directory, and if there's no blacklist
if (!ensureFilePathExists(dst)) { // match, we copy the file.
qWarning() << "Cannot create path!"; QDir src_dir(src);
return false; QDirIterator source_it(src, QDir::Filter::Files, QDirIterator::Subdirectories);
}
return QFile::copy(src, dst); while (source_it.hasNext()) {
} else if (currentSrc.isDir()) { auto src_path = source_it.next();
qDebug() << "recursing" << offset; auto relative_path = src_dir.relativeFilePath(src_path);
if (!ensureFolderPathExists(dst)) {
qWarning() << "Cannot create path!"; if (m_blacklist && m_blacklist->matches(relative_path))
return false;
}
QDir currentDir(src);
for (auto& f : currentDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System)) {
auto inner_offset = PathCombine(offset, f);
// ignore and skip stuff that matches the blacklist.
if (m_blacklist && m_blacklist->matches(inner_offset)) {
continue; continue;
}
if (!operator()(inner_offset)) { auto dst_path = PathCombine(dst, relative_path);
qWarning() << "Failed to copy" << inner_offset; ensureFilePathExists(dst_path);
return false;
std::filesystem::copy(src_path.toStdString(), dst_path.toStdString(), opt, err);
if (err) {
qWarning() << "Failed to copy files:" << QString::fromStdString(err.message());
qDebug() << "Source file:" << src_path;
qDebug() << "Destination file:" << dst_path;
} }
} }
} else {
qCritical() << "Copy ERROR: Unknown filesystem object:" << src; return err.value() == 0;
return false;
}
return true;
} }
bool deletePath(QString path) bool deletePath(QString path)