Files
pilotclient/src/misc/swiftdirectories.cpp
2024-12-08 13:41:42 +01:00

380 lines
12 KiB
C++

// SPDX-FileCopyrightText: Copyright (C) 2020 swift Project Community / Contributors
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
//! \cond PRIVATE
#include "misc/swiftdirectories.h"
#include <QCoreApplication>
#include <QDir>
#include <QRegularExpression>
#include <QSet>
#include <QStandardPaths>
#include <QUrl>
#include "config/buildconfig.h"
#include "misc/directoryutils.h"
#include "misc/fileutils.h"
#include "misc/range.h"
#include "misc/stringutils.h"
using namespace swift::config;
namespace swift::misc
{
QString binDirectoryImpl()
{
QString appDirectoryString(qApp->applicationDirPath());
if (appDirectoryString.endsWith("Contents/MacOS")) { appDirectoryString += "/../../.."; }
QDir appDirectory(appDirectoryString);
return appDirectory.absolutePath();
}
const QString &CSwiftDirectories::binDirectory()
{
static const QString binDir(binDirectoryImpl());
return binDir;
}
const QString &CSwiftDirectories::pluginsDirectory()
{
static const QString pDir(CFileUtils::appendFilePaths(binDirectory(), "plugins"));
return pDir;
}
const QString &CSwiftDirectories::audioPluginDirectory()
{
static const QString pDir(CFileUtils::appendFilePaths(binDirectory(), "audio"));
return pDir;
}
const QString &CSwiftDirectories::getXSwiftBusBuildDirectory()
{
if (!CBuildConfig::isLocalDeveloperDebugBuild())
{
static const QString e;
return e;
}
// the xswiftbus directory in out, not in dist
static const QString bd = [] {
QDir dir(binDirectory());
if (!dir.cdUp()) { return QString(); }
if (!dir.cd("xswiftbus")) { return QString(); }
return dir.absolutePath();
}();
return bd;
}
QString CSwiftDirectories::executableFilePath(const QString &executable)
{
Q_ASSERT_X(!executable.isEmpty(), Q_FUNC_INFO, "Missing executable file path");
QString s = CFileUtils::appendFilePaths(binDirectory(), executable);
if (CBuildConfig::isRunningOnMacOSPlatform())
{
// MacOS bundle may or may not be a bundle
const QDir dir(s + QLatin1String(".app/Contents/MacOS"));
if (dir.exists()) { s += QLatin1String(".app/Contents/MacOS/") + executable; }
}
else if (CBuildConfig::isRunningOnWindowsNtPlatform()) { s += QLatin1String(".exe"); }
return s;
}
QString normalizedApplicationDirectoryImpl()
{
QString appDir = CSwiftDirectories::binDirectory();
Q_ASSERT(appDir.size() > 0);
// Remove leading '/' on Unix
if (appDir.at(0) == '/') { appDir.remove(0, 1); }
return QUrl::toPercentEncoding(appDir);
}
const QString &CSwiftDirectories::normalizedApplicationDirectory()
{
static const QString appDir(normalizedApplicationDirectoryImpl());
return appDir;
}
const QString &CSwiftDirectories::applicationDataDirectory()
{
static const QString p = CFileUtils::appendFilePaths(
QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), "/org.swift-project/");
return p;
}
const QFileInfoList &CSwiftDirectories::applicationDataDirectories()
{
static QFileInfoList fileInfoList = currentApplicationDataDirectories();
return fileInfoList;
}
QFileInfoList CSwiftDirectories::currentApplicationDataDirectories()
{
const QDir swiftAppData(applicationDataDirectory()); // contains 1..n subdirs
if (!swiftAppData.isReadable()) { return QFileInfoList(); }
return swiftAppData.entryInfoList({}, QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time);
}
int CSwiftDirectories::applicationDataDirectoriesCount() { return applicationDataDirectories().size(); }
QStringList CSwiftDirectories::applicationDataDirectoryList(bool withoutCurrent, bool decodedDirName)
{
QStringList dirs;
for (const QFileInfo &info : applicationDataDirectories())
{
if (withoutCurrent && info.filePath().contains(normalizedApplicationDirectory(), Qt::CaseInsensitive))
continue;
dirs.append(decodedDirName ? CDirectoryUtils::decodeNormalizedDirectory(info.filePath()) : info.filePath());
}
return dirs;
}
const QString &CSwiftDirectories::normalizedApplicationDataDirectory()
{
static const QString p =
CFileUtils::appendFilePaths(applicationDataDirectory(), normalizedApplicationDirectory());
return p;
}
const QString &CSwiftDirectories::logDirectory()
{
static const QString p = CFileUtils::appendFilePaths(normalizedApplicationDataDirectory(), "/logs");
return p;
}
QString getSwiftShareDirImpl()
{
QDir dir(CSwiftDirectories::binDirectory());
const bool success = dir.cd("../share");
if (success)
{
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
Q_ASSERT_X(false, Q_FUNC_INFO, "missing dir");
return {};
}
const QString &CSwiftDirectories::shareDirectory()
{
static const QString s(getSwiftShareDirImpl());
return s;
}
const QString &CSwiftDirectories::shareTestDirectory()
{
static const QString test(CFileUtils::appendFilePaths(shareDirectory(), "test"));
return test;
}
const QString &CSwiftDirectories::shareTerrainProbeDirectory()
{
static const QString tpd(CFileUtils::appendFilePaths(shareDirectory(), "simulator/swiftTerrainProbe"));
return tpd;
}
const QString &CSwiftDirectories::shareMatchingScriptDirectory()
{
static const QString ms(CFileUtils::appendFilePaths(shareDirectory(), "matchingscript"));
return ms;
}
const QString &CSwiftDirectories::bootstrapFileName()
{
static const QString n("bootstrap.json");
return n;
}
QString getBootstrapResourceFileImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
if (d.isEmpty()) { return {}; }
const QFile file(
QDir::cleanPath(d + QDir::separator() + "shared/bootstrap/" + CSwiftDirectories::bootstrapFileName()));
Q_ASSERT_X(file.exists(), Q_FUNC_INFO, "missing bootstrap file");
return QFileInfo(file).absoluteFilePath();
}
const QString &CSwiftDirectories::bootstrapResourceFilePath()
{
static const QString s(getBootstrapResourceFileImpl());
return s;
}
QString getSwiftStaticDbFilesDirImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
if (d.isEmpty()) { return {}; }
const QDir dir(QDir::cleanPath(d + QDir::separator() + "shared/dbdata"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CSwiftDirectories::staticDbFilesDirectory()
{
static const QString s(getSwiftStaticDbFilesDirImpl());
return s;
}
QString getSoundFilesDirImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
if (d.isEmpty()) { return {}; }
const QDir dir(QDir::cleanPath(d + QDir::separator() + "sounds"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CSwiftDirectories::soundFilesDirectory()
{
static const QString s(getSoundFilesDirImpl());
return s;
}
QString getStylesheetsDirImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
if (d.isEmpty()) { return {}; }
const QDir dir(QDir::cleanPath(d + QDir::separator() + "qss"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CSwiftDirectories::stylesheetsDirectory()
{
static const QString s(getStylesheetsDirImpl());
return s;
}
QString getHtmlDirImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
const QDir dir(QDir::cleanPath(d + QDir::separator() + "html"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CSwiftDirectories::htmlDirectory()
{
static const QString s(getHtmlDirImpl());
return s;
}
QString getLegalDirImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
const QDir dir(QDir::cleanPath(d + QDir::separator() + "legal"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CSwiftDirectories::legalDirectory()
{
static const QString s(getLegalDirImpl());
return s;
}
const QString &CSwiftDirectories::aboutFilePath()
{
static const QString about = QDir::cleanPath(legalDirectory() + QDir::separator() + "about.html");
return about;
}
QString testFilesDirImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
if (d.isEmpty()) { return {}; }
const QDir dir(QDir::cleanPath(d + QDir::separator() + "test"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CSwiftDirectories::testFilesDirectory()
{
static QString s(testFilesDirImpl());
return s;
}
const QString &CSwiftDirectories::htmlTemplateFilePath()
{
static const QString s(htmlDirectory() + QDir::separator() + "swifttemplate.html");
return s;
}
QString getDocumentationDirectoryImpl()
{
const QStringList pathes(QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation));
QString d = pathes.first();
d = QDir::cleanPath(CFileUtils::appendFilePaths(d, "swift"));
QDir dir(d);
if (dir.exists()) { return dir.absolutePath(); }
return pathes.first();
}
const QString &CSwiftDirectories::documentationDirectory()
{
static const QString d(getDocumentationDirectoryImpl());
return d;
}
const QString &CSwiftDirectories::crashpadDirectory()
{
static const QString p = CFileUtils::appendFilePaths(normalizedApplicationDataDirectory(), "/crashpad");
return p;
}
const QString &CSwiftDirectories::crashpadDatabaseDirectory()
{
static const QString p = CFileUtils::appendFilePaths(crashpadDirectory(), "/database");
return p;
}
const QString &CSwiftDirectories::crashpadMetricsDirectory()
{
static const QString p = CFileUtils::appendFilePaths(crashpadDirectory(), "/metrics");
return p;
}
QStringList CSwiftDirectories::verifyRuntimeDirectoriesAndFiles()
{
QStringList failed;
QDir d(binDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
d = QDir(stylesheetsDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
d = QDir(applicationDataDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
// check if the executables are avialable
QString fn = executableFilePath(CBuildConfig::swiftCoreExecutableName());
if (!QFile::exists(fn)) { failed.append(fn); }
fn = executableFilePath(CBuildConfig::swiftDataExecutableName());
if (!QFile::exists(fn)) { failed.append(fn); }
fn = executableFilePath(CBuildConfig::swiftGuiExecutableName());
if (!QFile::exists(fn)) { failed.append(fn); }
return failed;
}
QString CSwiftDirectories::soundFilePathOrDefaultPath(const QString &directory, const QString &fileName)
{
if (!directory.isEmpty())
{
const QString fp = CFileUtils::appendFilePathsAndFixUnc(directory, fileName);
const QFileInfo fi(fp);
if (fi.exists()) { return fi.absoluteFilePath(); }
}
const QString fp = CFileUtils::appendFilePathsAndFixUnc(CSwiftDirectories::soundFilesDirectory(), fileName);
const QFileInfo fi(fp);
return (fi.exists()) ? fi.absoluteFilePath() : QString();
}
} // namespace swift::misc
//! \endcond