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
This commit is contained in:
Tuur Vanhoutte 2024-12-27 15:40:46 +01:00 committed by GitHub
parent e75e2cdac7
commit 43ca66779b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 97 additions and 97 deletions

View file

@ -1,11 +1,10 @@
#include "DataState.hpp"
#include <toml++/toml.hpp>
#include <print>
#include <filesystem>
#include <fstream>
#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<std::filesystem::path> DataState::getPluginStates() {
ensureStateStoreExists();
std::vector<std::filesystem::path> 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<SPluginRepository> DataState::getAllRepositories() {
const auto PATH = getDataStatePath();
std::vector<SPluginRepository> 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;