diff --git a/include/utils/file.hpp b/include/utils/file.hpp index 80436a8e..61a35137 100644 --- a/include/utils/file.hpp +++ b/include/utils/file.hpp @@ -106,6 +106,7 @@ namespace file_util { string contents(const string& filename); bool is_fifo(const string& filename); vector glob(string pattern); + const string expand(const string& path); template decltype(auto) make_file_descriptor(Args&&... args) { diff --git a/src/components/config.cpp b/src/components/config.cpp index f913d7ae..616eba1c 100644 --- a/src/components/config.cpp +++ b/src/components/config.cpp @@ -100,15 +100,16 @@ void config::parse_file() { } if (key == "include-file") { - if (value.empty() || !file_util::exists(value)) { - throw value_error("Invalid include file \"" + value + "\" defined on line " + to_string(lineno)); + auto file_path = file_util::expand(value); + if (file_path.empty() || !file_util::exists(file_path)) { + throw value_error("Invalid include file \"" + file_path + "\" defined on line " + to_string(lineno)); } - if (std::find(files.begin(), files.end(), value) != files.end()) { - throw value_error("Recursive include file \"" + value + "\""); + if (std::find(files.begin(), files.end(), file_path) != files.end()) { + throw value_error("Recursive include file \"" + file_path + "\""); } - files.push_back(value); - m_log.trace("config: Including file \"%s\"", value); - for (auto&& l : string_util::split(file_util::contents(value), '\n')) { + files.push_back(file_util::expand(file_path)); + m_log.trace("config: Including file \"%s\"", file_path); + for (auto&& l : string_util::split(file_util::contents(file_path), '\n')) { pushline(lineno, forward(l)); } files.pop_back(); diff --git a/src/utils/file.cpp b/src/utils/file.cpp index 5e6e58e0..d73c0fff 100644 --- a/src/utils/file.cpp +++ b/src/utils/file.cpp @@ -231,6 +231,17 @@ namespace file_util { return ret; } + + /** + * Path expansion + */ + const string expand(const string& path) { + string p{path}; + if (p[0] == '~') { + p.replace(0, 1, env_util::get("HOME")); + } + return p; + } } POLYBAR_NS_END diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bad4595e..ce47a897 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -18,6 +18,7 @@ unit_test(utils/color) unit_test(utils/math) unit_test(utils/memory) unit_test(utils/string) +unit_test(utils/file) unit_test(components/command_line) # XXX: Requires mocked xcb connection diff --git a/tests/unit_tests/utils/file.cpp b/tests/unit_tests/utils/file.cpp new file mode 100644 index 00000000..4aacd80d --- /dev/null +++ b/tests/unit_tests/utils/file.cpp @@ -0,0 +1,21 @@ +#include +#include + +#include "components/logger.cpp" +#include "utils/command.cpp" +#include "utils/concurrency.cpp" +#include "utils/env.cpp" +#include "utils/file.cpp" +#include "utils/io.cpp" +#include "utils/process.cpp" +#include "utils/string.cpp" + +int main() { + using namespace polybar; + + "expand"_test = [] { + auto cmd = command_util::make_command("echo $HOME"); + cmd->exec(); + cmd->tail([](string home) { expect(file_util::expand("~/test") == home + "/test"); }); + }; +}