Allow using wildcards in config include paths
Updates `Config::tryExpandPath()` to return a vector of expanded path matches instead of a single path wrapped in an optional, with an empty vector indicating no matches. `Config::resolveConfigIncludes()` iterates over all of these matches, while other instances of path expansion (such as finding the base config path) retain their existing behavior and only use the first match.
This commit is contained in:
@ -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;
|
||||||
|
|
||||||
|
@ -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()) {
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user