mirror of
https://github.com/hyprwm/hypridle.git
synced 2025-05-12 21:20:39 +01:00
config: add support for source
option for additional config files (#144)
Some checks failed
Build / nix (push) Has been cancelled
Some checks failed
Build / nix (push) Has been cancelled
* feat: support `source` option for additional config files * fix: prevent circular dependency
This commit is contained in:
parent
b18d830276
commit
a0037ac40c
4 changed files with 105 additions and 1 deletions
|
@ -1,6 +1,10 @@
|
|||
#include "ConfigManager.hpp"
|
||||
#include "../helpers/Log.hpp"
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
#include <hyprutils/path/Path.hpp>
|
||||
#include <filesystem>
|
||||
#include <glob.h>
|
||||
#include <cstring>
|
||||
|
||||
static std::string getMainConfigPath() {
|
||||
static const auto paths = Hyprutils::Path::findConfig("hypridle");
|
||||
|
@ -13,6 +17,19 @@ static std::string getMainConfigPath() {
|
|||
CConfigManager::CConfigManager(std::string configPath) :
|
||||
m_config(configPath.empty() ? getMainConfigPath().c_str() : configPath.c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = false}) {
|
||||
;
|
||||
configCurrentPath = configPath.empty() ? getMainConfigPath() : configPath;
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult handleSource(const char* c, const char* v) {
|
||||
const std::string VALUE = v;
|
||||
const std::string COMMAND = c;
|
||||
|
||||
const auto RESULT = g_pConfigManager->handleSource(COMMAND, VALUE);
|
||||
|
||||
Hyprlang::CParseResult result;
|
||||
if (RESULT.has_value())
|
||||
result.setError(RESULT.value().c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
void CConfigManager::init() {
|
||||
|
@ -31,6 +48,12 @@ void CConfigManager::init() {
|
|||
m_config.addConfigValue("general:ignore_systemd_inhibit", Hyprlang::INT{0});
|
||||
m_config.addConfigValue("general:inhibit_sleep", Hyprlang::INT{2});
|
||||
|
||||
// track the file in the circular dependency chain
|
||||
const auto mainConfigPath = getMainConfigPath();
|
||||
alreadyIncludedSourceFiles.insert(std::filesystem::canonical(mainConfigPath));
|
||||
|
||||
m_config.registerHandler(&::handleSource, "source", {.allowFlags = false});
|
||||
|
||||
m_config.commence();
|
||||
|
||||
auto result = m_config.parse();
|
||||
|
@ -80,3 +103,56 @@ Hyprlang::CParseResult CConfigManager::postParse() {
|
|||
std::vector<CConfigManager::STimeoutRule> CConfigManager::getRules() {
|
||||
return m_vRules;
|
||||
}
|
||||
|
||||
std::optional<std::string> CConfigManager::handleSource(const std::string& command, const std::string& rawpath) {
|
||||
if (rawpath.length() < 2) {
|
||||
return "source path " + rawpath + " bogus!";
|
||||
}
|
||||
std::unique_ptr<glob_t, void (*)(glob_t*)> glob_buf{new glob_t, [](glob_t* g) { globfree(g); }};
|
||||
memset(glob_buf.get(), 0, sizeof(glob_t));
|
||||
|
||||
const auto CURRENTDIR = std::filesystem::path(configCurrentPath).parent_path().string();
|
||||
|
||||
if (auto r = glob(absolutePath(rawpath, CURRENTDIR).c_str(), GLOB_TILDE, nullptr, glob_buf.get()); r != 0) {
|
||||
std::string err = std::format("source= globbing error: {}", r == GLOB_NOMATCH ? "found no match" : GLOB_ABORTED ? "read error" : "out of memory");
|
||||
Debug::log(ERR, "{}", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < glob_buf->gl_pathc; i++) {
|
||||
const auto PATH = absolutePath(glob_buf->gl_pathv[i], CURRENTDIR);
|
||||
|
||||
if (PATH.empty() || PATH == configCurrentPath) {
|
||||
Debug::log(WARN, "source= skipping invalid path");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (std::find(alreadyIncludedSourceFiles.begin(), alreadyIncludedSourceFiles.end(), PATH) != alreadyIncludedSourceFiles.end()) {
|
||||
Debug::log(WARN, "source= skipping already included source file {} to prevent circular dependency", PATH);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!std::filesystem::is_regular_file(PATH)) {
|
||||
if (std::filesystem::exists(PATH)) {
|
||||
Debug::log(WARN, "source= skipping non-file {}", PATH);
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug::log(ERR, "source= file doesnt exist");
|
||||
return "source file " + PATH + " doesn't exist!";
|
||||
}
|
||||
|
||||
// track the file in the circular dependency chain
|
||||
alreadyIncludedSourceFiles.insert(PATH);
|
||||
|
||||
// allow for nested config parsing
|
||||
auto backupConfigPath = configCurrentPath;
|
||||
configCurrentPath = PATH;
|
||||
|
||||
m_config.parseFile(PATH.c_str());
|
||||
|
||||
configCurrentPath = backupConfigPath;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <hyprlang.hpp>
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
|
@ -18,7 +19,10 @@ class CConfigManager {
|
|||
std::string onResume = "";
|
||||
};
|
||||
|
||||
std::vector<STimeoutRule> getRules();
|
||||
std::vector<STimeoutRule> getRules();
|
||||
std::optional<std::string> handleSource(const std::string&, const std::string&);
|
||||
std::string configCurrentPath;
|
||||
std::set<std::string> alreadyIncludedSourceFiles;
|
||||
|
||||
template <typename T>
|
||||
Hyprlang::CSimpleConfigValue<T> getValue(const std::string& name) {
|
||||
|
|
19
src/helpers/MiscFunctions.cpp
Normal file
19
src/helpers/MiscFunctions.cpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#include <filesystem>
|
||||
|
||||
#include "MiscFunctions.hpp"
|
||||
|
||||
std::string absolutePath(const std::string& rawpath, const std::string& currentDir) {
|
||||
std::filesystem::path path(rawpath);
|
||||
|
||||
// Handling where rawpath starts with '~'
|
||||
if (!rawpath.empty() && rawpath[0] == '~') {
|
||||
static const char* const ENVHOME = getenv("HOME");
|
||||
path = std::filesystem::path(ENVHOME) / path.relative_path().string().substr(2);
|
||||
}
|
||||
|
||||
// Handling e.g. ./, ../
|
||||
if (path.is_relative())
|
||||
return std::filesystem::weakly_canonical(std::filesystem::path(currentDir) / path);
|
||||
else
|
||||
return std::filesystem::weakly_canonical(path);
|
||||
}
|
5
src/helpers/MiscFunctions.hpp
Normal file
5
src/helpers/MiscFunctions.hpp
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string absolutePath(const std::string&, const std::string&);
|
Loading…
Reference in a new issue