diff --git a/src/util/XDGDirectory.cpp b/src/util/XDGDirectory.cpp index ab401e50..42cf6564 100644 --- a/src/util/XDGDirectory.cpp +++ b/src/util/XDGDirectory.cpp @@ -8,29 +8,8 @@ namespace chatterino { #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> - 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 // Defaults fetched from https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables 2023-08-05 static std::unordered_map> + 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 } // namespace chatterino diff --git a/src/util/XDGDirectory.hpp b/src/util/XDGDirectory.hpp index 9a18ea25..2a4c1a37 100644 --- a/src/util/XDGDirectory.hpp +++ b/src/util/XDGDirectory.hpp @@ -2,15 +2,25 @@ #include +#include + namespace chatterino { #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, + /// The values from XDG_DATA_HOME and XDG_DATA_DIRS 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 /// /// This will attempt to read the relevant environment variable (e.g. XDG_CONFIG_HOME and XDG_CONFIG_DIRS) and merge them, with sane defaults diff --git a/tests/src/XDGDirectory.cpp b/tests/src/XDGDirectory.cpp index 2a780ec5..d546c596 100644 --- a/tests/src/XDGDirectory.cpp +++ b/tests/src/XDGDirectory.cpp @@ -103,6 +103,63 @@ TEST(XDGDirectory, ConfigCustom) 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(XDGDirectory, DataDefault) { @@ -141,4 +198,59 @@ TEST(XDGDirectory, DataCustom) 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