From 43ca66779b7d267cc6c52bdea75d3ff8eb60132f Mon Sep 17 00:00:00 2001 From: Tuur Vanhoutte <4633209+zjeffer@users.noreply.github.com> Date: Fri, 27 Dec 2024 15:40:46 +0100 Subject: hyprpm: use glaze to parse hyprctl plugin list (#8812) * Use std::filesystem::path in hyprpm DataState to avoid concatenating strings with (folder + "/" + file) * Added getPluginStates helper method in DataState * Small clang-tidy improvements --- hyprpm/src/core/DataState.cpp | 107 +++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 58 deletions(-) (limited to 'hyprpm/src/core/DataState.cpp') diff --git a/hyprpm/src/core/DataState.cpp b/hyprpm/src/core/DataState.cpp index fb8679d6..55f148a4 100644 --- a/hyprpm/src/core/DataState.cpp +++ b/hyprpm/src/core/DataState.cpp @@ -1,11 +1,10 @@ #include "DataState.hpp" #include #include -#include #include #include "PluginManager.hpp" -std::string DataState::getDataStatePath() { +std::filesystem::path DataState::getDataStatePath() { const auto HOME = getenv("HOME"); if (!HOME) { std::println(stderr, "DataState: no $HOME"); @@ -16,12 +15,29 @@ std::string DataState::getDataStatePath() { const auto XDG_DATA_HOME = getenv("XDG_DATA_HOME"); if (XDG_DATA_HOME) - return std::string{XDG_DATA_HOME} + "/hyprpm"; - return std::string{HOME} + "/.local/share/hyprpm"; + return std::filesystem::path{XDG_DATA_HOME} / "hyprpm"; + return std::filesystem::path{HOME} / ".local/share/hyprpm"; } std::string DataState::getHeadersPath() { - return getDataStatePath() + "/headersRoot"; + return getDataStatePath() / "headersRoot"; +} + +std::vector DataState::getPluginStates() { + ensureStateStoreExists(); + + std::vector states; + for (const auto& entry : std::filesystem::directory_iterator(getDataStatePath())) { + if (!entry.is_directory() || entry.path().stem() == "headersRoot") + continue; + + const auto stateFile = entry.path() / "state.toml"; + if (!std::filesystem::exists(stateFile)) + continue; + + states.emplace_back(stateFile); + } + return states; } void DataState::ensureStateStoreExists() { @@ -37,7 +53,7 @@ void DataState::ensureStateStoreExists() { void DataState::addNewPluginRepo(const SPluginRepository& repo) { ensureStateStoreExists(); - const auto PATH = getDataStatePath() + "/" + repo.name; + const auto PATH = getDataStatePath() / repo.name; std::filesystem::create_directories(PATH); // clang-format off @@ -50,19 +66,21 @@ void DataState::addNewPluginRepo(const SPluginRepository& repo) { }} }; for (auto const& p : repo.plugins) { + const auto filename = p.name + ".so"; + // copy .so to the good place if (std::filesystem::exists(p.filename)) - std::filesystem::copy_file(p.filename, PATH + "/" + p.name + ".so"); + std::filesystem::copy_file(p.filename, PATH / filename); DATA.emplace(p.name, toml::table{ - {"filename", p.name + ".so"}, + {"filename", filename}, {"enabled", p.enabled}, {"failed", p.failed} }); } // clang-format on - std::ofstream ofs(PATH + "/state.toml", std::ios::trunc); + std::ofstream ofs(PATH / "state.toml", std::ios::trunc); ofs << DATA; ofs.close(); } @@ -72,17 +90,10 @@ bool DataState::pluginRepoExists(const std::string& urlOrName) { const auto PATH = getDataStatePath(); - for (const auto& entry : std::filesystem::directory_iterator(PATH)) { - if (!entry.is_directory() || entry.path().stem() == "headersRoot") - continue; - - if (!std::filesystem::exists(entry.path().string() + "/state.toml")) - continue; - - auto STATE = toml::parse_file(entry.path().string() + "/state.toml"); - - const auto NAME = STATE["repository"]["name"].value_or(""); - const auto URL = STATE["repository"]["url"].value_or(""); + for (const auto& stateFile : getPluginStates()) { + const auto STATE = toml::parse_file(stateFile.c_str()); + const auto NAME = STATE["repository"]["name"].value_or(""); + const auto URL = STATE["repository"]["url"].value_or(""); if (URL == urlOrName || NAME == urlOrName) return true; @@ -96,29 +107,22 @@ void DataState::removePluginRepo(const std::string& urlOrName) { const auto PATH = getDataStatePath(); - for (const auto& entry : std::filesystem::directory_iterator(PATH)) { - if (!entry.is_directory() || entry.path().stem() == "headersRoot") - continue; - - if (!std::filesystem::exists(entry.path().string() + "/state.toml")) - continue; - - auto STATE = toml::parse_file(entry.path().string() + "/state.toml"); - - const auto NAME = STATE["repository"]["name"].value_or(""); - const auto URL = STATE["repository"]["url"].value_or(""); + for (const auto& stateFile : getPluginStates()) { + const auto STATE = toml::parse_file(stateFile.c_str()); + const auto NAME = STATE["repository"]["name"].value_or(""); + const auto URL = STATE["repository"]["url"].value_or(""); if (URL == urlOrName || NAME == urlOrName) { // unload the plugins!! - for (const auto& file : std::filesystem::directory_iterator(entry.path())) { + for (const auto& file : std::filesystem::directory_iterator(stateFile.parent_path())) { if (!file.path().string().ends_with(".so")) continue; g_pPluginManager->loadUnloadPlugin(std::filesystem::absolute(file.path()), false); } - std::filesystem::remove_all(entry.path()); + std::filesystem::remove_all(stateFile.parent_path()); return; } } @@ -139,7 +143,7 @@ void DataState::updateGlobalState(const SGlobalState& state) { }; // clang-format on - std::ofstream ofs(PATH + "/state.toml", std::ios::trunc); + std::ofstream ofs(PATH / "state.toml", std::ios::trunc); ofs << DATA; ofs.close(); } @@ -147,12 +151,12 @@ void DataState::updateGlobalState(const SGlobalState& state) { SGlobalState DataState::getGlobalState() { ensureStateStoreExists(); - const auto PATH = getDataStatePath(); + const auto stateFile = getDataStatePath() / "state.toml"; - if (!std::filesystem::exists(PATH + "/state.toml")) + if (!std::filesystem::exists(stateFile)) return SGlobalState{}; - auto DATA = toml::parse_file(PATH + "/state.toml"); + auto DATA = toml::parse_file(stateFile.c_str()); SGlobalState state; state.headersHashCompiled = DATA["state"]["hash"].value_or(""); @@ -167,15 +171,8 @@ std::vector DataState::getAllRepositories() { const auto PATH = getDataStatePath(); std::vector repos; - - for (const auto& entry : std::filesystem::directory_iterator(PATH)) { - if (!entry.is_directory() || entry.path().stem() == "headersRoot") - continue; - - if (!std::filesystem::exists(entry.path().string() + "/state.toml")) - continue; - - auto STATE = toml::parse_file(entry.path().string() + "/state.toml"); + for (const auto& stateFile : getPluginStates()) { + const auto STATE = toml::parse_file(stateFile.c_str()); const auto NAME = STATE["repository"]["name"].value_or(""); const auto URL = STATE["repository"]["url"].value_or(""); @@ -210,15 +207,8 @@ bool DataState::setPluginEnabled(const std::string& name, bool enabled) { const auto PATH = getDataStatePath(); - for (const auto& entry : std::filesystem::directory_iterator(PATH)) { - if (!entry.is_directory() || entry.path().stem() == "headersRoot") - continue; - - if (!std::filesystem::exists(entry.path().string() + "/state.toml")) - continue; - - auto STATE = toml::parse_file(entry.path().string() + "/state.toml"); - + for (const auto& stateFile : getPluginStates()) { + const auto STATE = toml::parse_file(stateFile.c_str()); for (const auto& [key, val] : STATE) { if (key == "repository") continue; @@ -231,10 +221,11 @@ bool DataState::setPluginEnabled(const std::string& name, bool enabled) { if (FAILED) return false; - (*STATE[key].as_table()).insert_or_assign("enabled", enabled); + auto modifiedState = STATE; + (*modifiedState[key].as_table()).insert_or_assign("enabled", enabled); - std::ofstream state(entry.path().string() + "/state.toml", std::ios::trunc); - state << STATE; + std::ofstream state(stateFile, std::ios::trunc); + state << modifiedState; state.close(); return true; -- cgit v1.2.3