diff --git a/include/config.hpp b/include/config.hpp index 3490c3f1..bf653c2a 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -35,7 +35,8 @@ class Config { void setupConfig(Json::Value &dst, const std::string &config_file, int depth); void resolveConfigIncludes(Json::Value &config, int depth); void mergeConfig(Json::Value &a_config_, Json::Value &b_config_); - static std::optional findIncludePath(const std::string &name); + static std::vector findIncludePath( + const std::string &name, const std::vector &dirs = CONFIG_DIRS); std::string config_file_; diff --git a/src/config.cpp b/src/config.cpp index 2618e679..145056dd 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -106,12 +106,24 @@ void Config::setupConfig(Json::Value &dst, const std::string &config_file, int d mergeConfig(dst, tmp_config); } -std::optional Config::findIncludePath(const std::string &name) { +std::vector Config::findIncludePath(const std::string &name, + const std::vector &dirs) { auto match1 = tryExpandPath(name, ""); if (!match1.empty()) { - return match1.front(); + return match1; } - return findConfigPath({name}); + if (const char *dir = std::getenv(Config::CONFIG_PATH_ENV)) { + if (auto res = tryExpandPath(dir, name); !res.empty()) { + return res; + } + } + for (const auto &dir : dirs) { + if (auto res = tryExpandPath(dir, name); !res.empty()) { + return res; + } + } + + return {}; } void Config::resolveConfigIncludes(Json::Value &config, int depth) { @@ -119,18 +131,22 @@ void Config::resolveConfigIncludes(Json::Value &config, int depth) { if (includes.isArray()) { for (const auto &include : includes) { spdlog::info("Including resource file: {}", include.asString()); - auto match = findIncludePath(include.asString()); - if (match.has_value()) { - setupConfig(config, match.value(), depth + 1); + auto matches = findIncludePath(include.asString()); + if (!matches.empty()) { + for (const auto &match : matches) { + setupConfig(config, match, depth + 1); + } } else { spdlog::warn("Unable to find resource file: {}", include.asString()); } } } else if (includes.isString()) { spdlog::info("Including resource file: {}", includes.asString()); - auto match = findIncludePath(includes.asString()); - if (match.has_value()) { - setupConfig(config, match.value(), depth + 1); + auto matches = findIncludePath(includes.asString()); + if (!matches.empty()) { + for (const auto &match : matches) { + setupConfig(config, match, depth + 1); + } } else { spdlog::warn("Unable to find resource file: {}", includes.asString()); } diff --git a/test/config.cpp b/test/config.cpp index c60519ce..638d9663 100644 --- a/test/config.cpp +++ b/test/config.cpp @@ -84,6 +84,33 @@ TEST_CASE("Load simple config with include", "[config]") { } } +TEST_CASE("Load simple config with wildcard include", "[config]") { + waybar::Config conf; + conf.load("test/config/include-wildcard.json"); + + auto& data = conf.getConfig(); + SECTION("validate cpu include file") { REQUIRE(data["cpu"]["format"].asString() == "goo"); } + SECTION("validate memory include file") { REQUIRE(data["memory"]["format"].asString() == "foo"); } +} + +TEST_CASE("Load config using relative paths and wildcards", "[config]") { + waybar::Config conf; + + const char* old_config_path = std::getenv(waybar::Config::CONFIG_PATH_ENV); + setenv(waybar::Config::CONFIG_PATH_ENV, "test/config", 1); + + conf.load("test/config/include-relative-path.json"); + + auto& data = conf.getConfig(); + SECTION("validate cpu include file") { REQUIRE(data["cpu"]["format"].asString() == "goo"); } + SECTION("validate memory include file") { REQUIRE(data["memory"]["format"].asString() == "foo"); } + + if (old_config_path) + setenv(waybar::Config::CONFIG_PATH_ENV, old_config_path, 1); + else + unsetenv(waybar::Config::CONFIG_PATH_ENV); +} + TEST_CASE("Load multiple bar config with include", "[config]") { waybar::Config conf; conf.load("test/config/include-multi.json"); diff --git a/test/config/include-relative-path.json b/test/config/include-relative-path.json new file mode 100644 index 00000000..82214b37 --- /dev/null +++ b/test/config/include-relative-path.json @@ -0,0 +1,5 @@ +{ + "include": ["modules/*.jsonc"], + "position": "top", + "nullOption": null +} diff --git a/test/config/include-wildcard.json b/test/config/include-wildcard.json new file mode 100644 index 00000000..75c9f3a1 --- /dev/null +++ b/test/config/include-wildcard.json @@ -0,0 +1,5 @@ +{ + "include": ["test/config/modules/*.jsonc"], + "position": "top", + "nullOption": null +} diff --git a/test/config/modules/cpu.jsonc b/test/config/modules/cpu.jsonc new file mode 100644 index 00000000..393fd786 --- /dev/null +++ b/test/config/modules/cpu.jsonc @@ -0,0 +1,6 @@ +{ + "cpu": { + "interval": 2, + "format": "goo" + } +} diff --git a/test/config/modules/memory.jsonc b/test/config/modules/memory.jsonc new file mode 100644 index 00000000..6085d43a --- /dev/null +++ b/test/config/modules/memory.jsonc @@ -0,0 +1,6 @@ +{ + "memory": { + "interval": 2, + "format": "foo", + } +}