feat(xdg): return base or user directories (#6702)

This commit is contained in:
pajlada
2026-01-03 13:08:01 +01:00
committed by GitHub
parent 135d6ef9ae
commit 0f58bc3410
3 changed files with 158 additions and 27 deletions
+35 -26
View File
@@ -8,29 +8,8 @@ namespace chatterino {
#if defined(Q_OS_UNIX) and !defined(Q_OS_DARWIN) #if defined(Q_OS_UNIX) and !defined(Q_OS_DARWIN)
QStringList getXDGDirectories(XDGDirectoryType directory) QStringList getXDGBaseDirectories(XDGDirectoryType directory)
{ {
// User XDG directory environment variables with defaults
// Defaults fetched from https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables 2023-08-05
static std::unordered_map<XDGDirectoryType,
std::pair<const char *, QString>>
userDirectories = {
{
XDGDirectoryType::Config,
{
"XDG_CONFIG_HOME",
combinePath(QDir::homePath(), ".config/"),
},
},
{
XDGDirectoryType::Data,
{
"XDG_DATA_HOME",
combinePath(QDir::homePath(), ".local/share/"),
},
},
};
// Base (or system) XDG directory environment variables with defaults // Base (or system) XDG directory environment variables with defaults
// Defaults fetched from https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables 2023-08-05 // Defaults fetched from https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables 2023-08-05
static std::unordered_map<XDGDirectoryType, static std::unordered_map<XDGDirectoryType,
@@ -54,10 +33,6 @@ QStringList getXDGDirectories(XDGDirectoryType directory)
QStringList paths; QStringList paths;
const auto &[userEnvVar, userDefaultValue] = userDirectories.at(directory);
auto userEnvPath = qEnvironmentVariable(userEnvVar, userDefaultValue);
paths.push_back(userEnvPath);
const auto &[baseEnvVar, baseDefaultValue] = baseDirectories.at(directory); const auto &[baseEnvVar, baseDefaultValue] = baseDirectories.at(directory);
auto baseEnvPaths = auto baseEnvPaths =
qEnvironmentVariable(baseEnvVar).split(':', Qt::SkipEmptyParts); qEnvironmentVariable(baseEnvVar).split(':', Qt::SkipEmptyParts);
@@ -73,6 +48,40 @@ QStringList getXDGDirectories(XDGDirectoryType directory)
return paths; return paths;
} }
QStringList getXDGUserDirectories(XDGDirectoryType directory)
{
// User XDG directory environment variables with defaults
// Defaults fetched from https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables 2023-08-05
static std::unordered_map<XDGDirectoryType,
std::pair<const char *, QString>>
userDirectories = {
{
XDGDirectoryType::Config,
{
"XDG_CONFIG_HOME",
combinePath(QDir::homePath(), ".config/"),
},
},
{
XDGDirectoryType::Data,
{
"XDG_DATA_HOME",
combinePath(QDir::homePath(), ".local/share/"),
},
},
};
const auto &[userEnvVar, userDefaultValue] = userDirectories.at(directory);
return {
qEnvironmentVariable(userEnvVar, userDefaultValue),
};
}
QStringList getXDGDirectories(XDGDirectoryType directory)
{
return getXDGUserDirectories(directory) + getXDGBaseDirectories(directory);
}
#endif #endif
} // namespace chatterino } // namespace chatterino
+11 -1
View File
@@ -2,15 +2,25 @@
#include <QStringList> #include <QStringList>
#include <cstdint>
namespace chatterino { namespace chatterino {
#if defined(Q_OS_UNIX) and !defined(Q_OS_DARWIN) #if defined(Q_OS_UNIX) and !defined(Q_OS_DARWIN)
enum class XDGDirectoryType { enum class XDGDirectoryType : std::uint8_t {
/// The values from XDG_CONFIG_HOME and XDG_CONFIG_DIRS.
Config, Config,
/// The values from XDG_DATA_HOME and XDG_DATA_DIRS
Data, Data,
}; };
/// Return the directories from the base environment variables only (e.g. XDG_CONFIG_DIRS)
QStringList getXDGBaseDirectories(XDGDirectoryType directory);
/// Return the directories from the user environment variables only (e.g. XDG_CONFIG_HOME)
QStringList getXDGUserDirectories(XDGDirectoryType directory);
/// getXDGDirectories returns a list of directories given a directory type /// getXDGDirectories returns a list of directories given a directory type
/// ///
/// This will attempt to read the relevant environment variable (e.g. XDG_CONFIG_HOME and XDG_CONFIG_DIRS) and merge them, with sane defaults /// This will attempt to read the relevant environment variable (e.g. XDG_CONFIG_HOME and XDG_CONFIG_DIRS) and merge them, with sane defaults
+112
View File
@@ -103,6 +103,63 @@ TEST(XDGDirectory, ConfigCustom)
ASSERT_EQ(actual.length(), 3); ASSERT_EQ(actual.length(), 3);
} }
TEST(XDGDirectory, ConfigUserDefault)
{
QTemporaryDir tmp;
auto lock = environmentLock();
TempEnv home("HOME", combinePath(tmp.path(), "home"));
TempEnv dataHome("XDG_CONFIG_HOME", {});
auto actual = getXDGUserDirectories(XDGDirectoryType::Config);
ASSERT_EQ(actual.at(0), combinePath(home.getValue(), ".config/"));
ASSERT_EQ(actual.length(), 1);
}
TEST(XDGDirectory, ConfigUserCustom)
{
auto lock = environmentLock();
TempEnv dataDirs("XDG_CONFIG_HOME", "/tmp/home-data");
auto actual = getXDGUserDirectories(XDGDirectoryType::Config);
ASSERT_EQ(actual.at(0), "/tmp/home-data");
ASSERT_EQ(actual.length(), 1);
}
TEST(XDGDirectory, ConfigBaseDefault)
{
auto lock = environmentLock();
TempEnv dataDirs("XDG_CONFIG_DIRS", {});
auto actual = getXDGBaseDirectories(XDGDirectoryType::Config);
ASSERT_EQ(actual.at(0), "/etc/xdg");
ASSERT_EQ(actual.length(), 1);
}
TEST(XDGDirectory, ConfigBaseCustom)
{
auto lock = environmentLock();
TempEnv dataDirs("XDG_CONFIG_DIRS",
"/tmp/sys-data-1:/tmp/sys-data-2:/tmp/sys-data-3");
auto actual = getXDGBaseDirectories(XDGDirectoryType::Config);
ASSERT_EQ(actual.at(0), "/tmp/sys-data-1");
ASSERT_EQ(actual.at(1), "/tmp/sys-data-2");
ASSERT_EQ(actual.at(2), "/tmp/sys-data-3");
ASSERT_EQ(actual.length(), 3);
}
/// Test the returned directories from XDGDirectoryType::Data when no extra environment variables are set /// Test the returned directories from XDGDirectoryType::Data when no extra environment variables are set
TEST(XDGDirectory, DataDefault) TEST(XDGDirectory, DataDefault)
{ {
@@ -141,4 +198,59 @@ TEST(XDGDirectory, DataCustom)
ASSERT_EQ(actual.length(), 4); ASSERT_EQ(actual.length(), 4);
} }
TEST(XDGDirectory, DataUserDefault)
{
QTemporaryDir tmp;
auto lock = environmentLock();
TempEnv home("HOME", combinePath(tmp.path(), "home"));
TempEnv dataDirs("XDG_DATA_HOME", {});
auto actual = getXDGUserDirectories(XDGDirectoryType::Data);
ASSERT_EQ(actual.at(0), combinePath(home.getValue(), ".local/share/"));
ASSERT_EQ(actual.length(), 1);
}
TEST(XDGDirectory, DataUserCustom)
{
auto lock = environmentLock();
TempEnv dataHome("XDG_DATA_HOME", "/tmp/home-share");
auto actual = getXDGUserDirectories(XDGDirectoryType::Data);
ASSERT_EQ(actual.at(0), "/tmp/home-share");
ASSERT_EQ(actual.length(), 1);
}
TEST(XDGDirectory, DataBaseDefault)
{
auto lock = environmentLock();
TempEnv dataDirs("XDG_DATA_DIRS", {});
auto actual = getXDGBaseDirectories(XDGDirectoryType::Data);
ASSERT_EQ(actual.at(0), "/usr/local/share/");
ASSERT_EQ(actual.at(1), "/usr/share/");
ASSERT_EQ(actual.length(), 2);
}
TEST(XDGDirectory, DataBaseCustom)
{
auto lock = environmentLock();
TempEnv dataDirs("XDG_DATA_DIRS", "/tmp/sys-share-1");
auto actual = getXDGBaseDirectories(XDGDirectoryType::Data);
ASSERT_EQ(actual.at(0), "/tmp/sys-share-1");
ASSERT_EQ(actual.length(), 1);
}
#endif #endif