diff --git a/include/config.hpp b/include/config.hpp index 82d5599..6694554 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -14,6 +14,7 @@ namespace waybar { class Config { public: static const std::vector CONFIG_DIRS; + static const char *CONFIG_PATH_ENV; /* Try to find any of provided names in the supported set of config directories */ static std::optional findConfigPath( diff --git a/src/config.cpp b/src/config.cpp index dec3b50..98b38c3 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -4,11 +4,14 @@ #include #include +#include #include #include #include "util/json.hpp" +namespace fs = std::filesystem; + namespace waybar { const std::vector Config::CONFIG_DIRS = { @@ -16,12 +19,25 @@ const std::vector Config::CONFIG_DIRS = { "/etc/xdg/waybar/", SYSCONFDIR "/xdg/waybar/", "./resources/", }; -std::optional tryExpandPath(const std::string &path) { +const char *Config::CONFIG_PATH_ENV = "WAYBAR_CONFIG_DIR"; + +std::optional tryExpandPath(const std::string base, const std::string filename) { + fs::path path; + + if (filename != "") { + path = fs::path(base) / fs::path(filename); + } else { + path = fs::path(base); + } + + spdlog::debug("Try expanding: {}", path); + wordexp_t p; if (wordexp(path.c_str(), &p, 0) == 0) { if (access(*p.we_wordv, F_OK) == 0) { std::string result = *p.we_wordv; wordfree(&p); + spdlog::debug("Found config file: {}", path); return result; } wordfree(&p); @@ -31,10 +47,17 @@ std::optional tryExpandPath(const std::string &path) { std::optional Config::findConfigPath(const std::vector &names, const std::vector &dirs) { - std::vector paths; + if (const char *dir = std::getenv(Config::CONFIG_PATH_ENV)) { + for (const auto &name : names) { + if (auto res = tryExpandPath(dir, name); res) { + return res; + } + } + } + for (const auto &dir : dirs) { for (const auto &name : names) { - if (auto res = tryExpandPath(dir + name); res) { + if (auto res = tryExpandPath(dir, name); res) { return res; } } @@ -68,11 +91,11 @@ void Config::resolveConfigIncludes(Json::Value &config, int depth) { if (includes.isArray()) { for (const auto &include : includes) { spdlog::info("Including resource file: {}", include.asString()); - setupConfig(config, tryExpandPath(include.asString()).value_or(""), ++depth); + setupConfig(config, tryExpandPath(include.asString(), "").value_or(""), ++depth); } } else if (includes.isString()) { spdlog::info("Including resource file: {}", includes.asString()); - setupConfig(config, tryExpandPath(includes.asString()).value_or(""), ++depth); + setupConfig(config, tryExpandPath(includes.asString(), "").value_or(""), ++depth); } }