Merge pull request #3862 from emar10/config-include-wildcards

Allow using wildcards in config include paths
This commit is contained in:
Alexis Rouillard
2025-01-12 11:29:26 +01:00
committed by GitHub
3 changed files with 24 additions and 18 deletions

View File

@ -20,8 +20,8 @@ class Config {
static std::optional<std::string> findConfigPath( static std::optional<std::string> findConfigPath(
const std::vector<std::string> &names, const std::vector<std::string> &dirs = CONFIG_DIRS); const std::vector<std::string> &names, const std::vector<std::string> &dirs = CONFIG_DIRS);
static std::optional<std::string> tryExpandPath(const std::string &base, static std::vector<std::string> tryExpandPath(const std::string &base,
const std::string &filename); const std::string &filename);
Config() = default; Config() = default;

View File

@ -68,11 +68,11 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
// there might be "~" or "$HOME" in original path, try to expand it. // there might be "~" or "$HOME" in original path, try to expand it.
auto result = Config::tryExpandPath(menuFile, ""); auto result = Config::tryExpandPath(menuFile, "");
if (!result.has_value()) { if (result.empty()) {
throw std::runtime_error("Failed to expand file: " + menuFile); throw std::runtime_error("Failed to expand file: " + menuFile);
} }
menuFile = result.value(); menuFile = result.front();
// Read the menu descriptor file // Read the menu descriptor file
std::ifstream file(menuFile); std::ifstream file(menuFile);
if (!file.is_open()) { if (!file.is_open()) {

View File

@ -21,8 +21,8 @@ const std::vector<std::string> Config::CONFIG_DIRS = {
const char *Config::CONFIG_PATH_ENV = "WAYBAR_CONFIG_DIR"; const char *Config::CONFIG_PATH_ENV = "WAYBAR_CONFIG_DIR";
std::optional<std::string> Config::tryExpandPath(const std::string &base, std::vector<std::string> Config::tryExpandPath(const std::string &base,
const std::string &filename) { const std::string &filename) {
fs::path path; fs::path path;
if (!filename.empty()) { if (!filename.empty()) {
@ -33,33 +33,35 @@ std::optional<std::string> Config::tryExpandPath(const std::string &base,
spdlog::debug("Try expanding: {}", path.string()); spdlog::debug("Try expanding: {}", path.string());
std::vector<std::string> results;
wordexp_t p; wordexp_t p;
if (wordexp(path.c_str(), &p, 0) == 0) { if (wordexp(path.c_str(), &p, 0) == 0) {
if (access(*p.we_wordv, F_OK) == 0) { for (size_t i = 0; i < p.we_wordc; i++) {
std::string result = *p.we_wordv; if (access(p.we_wordv[i], F_OK) == 0) {
wordfree(&p); results.emplace_back(p.we_wordv[i]);
spdlog::debug("Found config file: {}", path.string()); spdlog::debug("Found config file: {}", p.we_wordv[i]);
return result; }
} }
wordfree(&p); wordfree(&p);
} }
return std::nullopt;
return results;
} }
std::optional<std::string> Config::findConfigPath(const std::vector<std::string> &names, std::optional<std::string> Config::findConfigPath(const std::vector<std::string> &names,
const std::vector<std::string> &dirs) { const std::vector<std::string> &dirs) {
if (const char *dir = std::getenv(Config::CONFIG_PATH_ENV)) { if (const char *dir = std::getenv(Config::CONFIG_PATH_ENV)) {
for (const auto &name : names) { for (const auto &name : names) {
if (auto res = tryExpandPath(dir, name); res) { if (auto res = tryExpandPath(dir, name); !res.empty()) {
return res; return res.front();
} }
} }
} }
for (const auto &dir : dirs) { for (const auto &dir : dirs) {
for (const auto &name : names) { for (const auto &name : names) {
if (auto res = tryExpandPath(dir, name); res) { if (auto res = tryExpandPath(dir, name); !res.empty()) {
return res; return res.front();
} }
} }
} }
@ -92,11 +94,15 @@ void Config::resolveConfigIncludes(Json::Value &config, int depth) {
if (includes.isArray()) { if (includes.isArray()) {
for (const auto &include : includes) { for (const auto &include : includes) {
spdlog::info("Including resource file: {}", include.asString()); spdlog::info("Including resource file: {}", include.asString());
setupConfig(config, tryExpandPath(include.asString(), "").value_or(""), ++depth); for (const auto &match : tryExpandPath(include.asString(), "")) {
setupConfig(config, match, depth + 1);
}
} }
} else if (includes.isString()) { } else if (includes.isString()) {
spdlog::info("Including resource file: {}", includes.asString()); spdlog::info("Including resource file: {}", includes.asString());
setupConfig(config, tryExpandPath(includes.asString(), "").value_or(""), ++depth); for (const auto &match : tryExpandPath(includes.asString(), "")) {
setupConfig(config, match, depth + 1);
}
} }
} }