10#include <QCoreApplication>
13#include <QRegularExpression>
23using namespace swift::config;
24using namespace swift::misc::network;
39 static const bool appBundle = CBuildConfig::isRunningOnMacOSPlatform() &&
51 const QDir dir(rootDir);
61 const QDir directory(dir);
62 if (!directory.exists())
67 const QStringList nameFilter({
filter });
78 return std::ranges::any_of(relSubDirs, [&](
const QString &relSubDir) {
90 const QDir dir(testDir);
112 for (
const QString &dir : directories)
127 if (!canPingUncMachine(machine))
132 return QDir(path).exists();
135 bool CDirectoryUtils::canPingUncMachine(
const QString &machine)
137 static QMap<QString, qint64> good;
138 static QMap<QString, qint64> bad;
144 const QString m = machine.
toLower();
151 const qint64 ts = bad.
value(m);
161 const bool p = canPing(m);
192 if (!d1.exists() || !d2.exists())
196 return d1.absolutePath() == d2.absolutePath();
233 QSet<QString> CDirectoryUtils::fileNamesToQSet(
const QFileInfoList &fileInfoList)
235 CSetBuilder<QString> sl;
236 for (
const QFileInfo &info : fileInfoList)
238 sl.
insert(info.fileName());
243 QSet<QString> CDirectoryUtils::canonicalFileNamesToQSet(
const QFileInfoList &fileInfoList)
245 CSetBuilder<QString> sl;
246 for (
const QFileInfo &info : fileInfoList)
248 sl.
insert(info.canonicalFilePath());
253 QSet<QString> CDirectoryUtils::filesToCanonicalNames(
const QSet<QString> &fileNames,
254 const QSet<QString> &canonicalFileNames)
256 CSetBuilder<QString> found;
257 if (fileNames.
isEmpty())
return {};
258 for (
const QString &canonical : canonicalFileNames)
260 if (canonical.endsWith(
'/'))
continue;
261 const QString c = canonical.mid(1 + canonical.lastIndexOf(
'/'));
280 for (
const QString ©File : fromFiles)
286 if (!replaceOnConflict)
303 for (
const QString ©Dir : subDirs)
323 const QString &dirTarget,
bool nestedDirs)
326 const QDir d1(dirSource);
327 const QDir d2(dirTarget);
329 QFileInfoList dSourceList;
330 QFileInfoList dTargetList;
341 const QSet<QString> sSourceFiles = CDirectoryUtils::fileNamesToQSet(dSourceList);
342 const QSet<QString> sTargetFiles = CDirectoryUtils::fileNamesToQSet(dTargetList);
345 const QSet<QString> sSourceCanonicalFiles = CDirectoryUtils::canonicalFileNamesToQSet(dSourceList);
346 const QSet<QString> sTargetCanonicalFiles = CDirectoryUtils::canonicalFileNamesToQSet(dTargetList);
348 QSet<QString> missingInTarget(sSourceFiles);
349 QSet<QString> missingInSource(sTargetFiles);
350 QSet<QString> sameNames(sSourceFiles);
351 missingInSource.subtract(sSourceFiles);
352 missingInTarget.subtract(sTargetFiles);
353 sameNames.intersect(sTargetFiles);
355 comp.source = sSourceCanonicalFiles;
356 comp.missingInSource = CDirectoryUtils::filesToCanonicalNames(missingInSource, sSourceCanonicalFiles);
357 comp.missingInTarget = CDirectoryUtils::filesToCanonicalNames(missingInTarget, sSourceCanonicalFiles);
358 comp.sameNameInSource = CDirectoryUtils::filesToCanonicalNames(sameNames, sSourceCanonicalFiles);
359 comp.sameNameInTarget = CDirectoryUtils::filesToCanonicalNames(sameNames, sTargetCanonicalFiles);
361 Q_ASSERT_X(comp.sameNameInSource.size() == comp.sameNameInTarget.size(), Q_FUNC_INFO,
362 "Same sets require same size");
363 QSet<QString>::const_iterator targetIt = comp.sameNameInTarget.cbegin();
364 for (
const QString &sourceFile : std::as_const(comp.sameNameInSource))
366 const QFileInfo source(sourceFile);
367 const QFileInfo target(*targetIt);
369 if (source.lastModified() == target.lastModified() && source.size() == target.size())
374 if (source.lastModified() < target.lastModified())
376 comp.newerInTarget.insert(target.canonicalFilePath());
381 comp.newerInSource.insert(source.canonicalFilePath());
388 if (!relativeSubdirs.
isEmpty())
390 for (
const QString &relativeSubdir : relativeSubdirs)
396 comp.insert(subComparison);
static QStringList getRelativeSubDirectories(const QString &rootDir)
All sub directories of given dir.
static bool mkPathIfNotExisting(const QString &dir)
Make directory if not already existing.
static DirComparison compareTwoDirectories(const QString &dirSource, const QString &dirTarget, bool nestedDirs)
Compare 2 directories (only files, but with hierarchy).
static QString decodeNormalizedDirectory(const QString &directory)
Virtually the inverse operation of CDirectoryUtils::normalizedApplicationDirectory.
static bool isMacOSAppBundle()
Is MacOS application bundle?
static bool isSameOrSubDirectoryOf(const QString &testDir, const QString &parentDir)
Is "testDir" a subdirectory (possibly nested) of "parentDir" or the same directory.
static bool isInApplicationDirectory(const QString &path)
Path in application directory.
static bool containsFileInDir(const QString &dir, const QString &filter, bool recursively)
Any file with filter like "*.txt".
static QStringList getExistingUnemptyDirectories(const QStringList &directories)
Get the existing directories.
static bool isSameOrSubDirectoryOfStringBased(const QString &testDir, const QString &parentDir)
Is "testDir" a subdirectory (possibly nested) of "parentDir" or the same directory.
static bool existsUnemptyDirectory(const QString &testDir)
Exists directory and does it contains files.
static int copyDirectoryRecursively(const QString &fromDir, const QString &toDir, bool replaceOnConflict)
Copy directory recursively.
static bool isSameExistingDirectory(const QString &dir1, const QString &dir2)
Same existing directories.
static bool isDirExisting(const QString &path)
Directory existing? Also checking UNC paths upfront.
static Qt::CaseSensitivity osFileNameCaseSensitivity()
Case sensitivity for current OS.
static QString windowsUncMachine(const QString &filePath)
Machine in Windows UNC path.
static QString appendFilePaths(const QString &path1, const QString &path2)
Append file paths.
static QString fixWindowsUncPath(const QString &filePath)
UNC file paths on Qt start with "/", but UNC file paths only work when they start with "//".
static bool isWindowsUncPath(const QString &filePath)
Windows UNC path?
void insert(const T &value)
Add an element to the set. Runs in amortized constant time.
Free functions in swift::misc.
qint64 currentSecsSinceEpoch()
QString absolutePath() const const
QString cleanPath(const QString &path)
QStringList entryList(QDir::Filters filters, QDir::SortFlags sort) const const
bool exists() const const
bool mkpath(const QString &dirPath, std::optional< QFileDevice::Permissions > permissions) const const
bool copy(const QString &fileName, const QString &newName)
bool exists() const const
bool isEmpty() const const
bool contains(const Key &key) const const
QMap< Key, T >::iterator insert(QMap< Key, T >::const_iterator pos, const Key &key, const T &value)
QMap< Key, T >::size_type remove(const Key &key)
T value(const Key &key, const T &defaultValue) const const
bool contains(const QSet< T > &other) const const
bool isEmpty() const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString toLower() const const
QByteArray toUtf8() const const
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)
QString fromPercentEncoding(const QByteArray &input)
Result of directory comparison.
QSet< QString > missingInTarget
files not in target, but in source
QSet< QString > sameNameInTarget
file exists in source and target, target name
QSet< QString > source
all source files
QSet< QString > newerInTarget
file in target is newer
void insert(const DirComparison &otherComparison)
Insert values of another comparison.
QSet< QString > newerInSource
file exists in target, but source is newer
QSet< QString > sameNameInSource
file exists in source and target, source name
QSet< QString > missingInSource
files not in source, but in target