Live config override directory#4781
Live config override directory#4781tarek-y-ismail wants to merge 14 commits intoadd-config-file-store-adapterfrom
Conversation
|
I did not realize I wrote 1600+ lines of code. Might be wise to split this into a PR for the |
f42e490 to
3bafb8a
Compare
3bafb8a to
88e7411
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds support for loading a base config file plus a companion override directory (<config>.d/*.conf) and applying those overrides as a single “transaction” to the live config store (handlers called once after aggregating all inputs), with reload-on-change support.
Changes:
- Extend
miral::live_config::IniFilewithload_files()and implement multi-stream parsing/override semantics (including explicit array clearing). - Extend
miral::ConfigFilewith anOverrideLoaderconstructor and an inotify-based watcher for override directories and relevant symlink targets. - Add/expand tests for multi-stream INI behavior and override-directory loading/reloading; update demo server example to use the new multi-file loader.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/miral/live_config_ini_file.cpp |
Implements multi-stream parsing, value provenance tracking, array clear semantics, and a load_files() entrypoint. |
include/miral/miral/live_config_ini_file.h |
Exposes IniFile::load_files() in the public API. |
src/miral/config_file.cpp |
Adds multi-file collection, override-directory discovery, and OverrideWatcher for reload-on-change. |
include/miral/miral/config_file.h |
Adds OverrideLoader type + constructor overload to support multi-file loading. |
tests/miral/live_config_ini_file.cpp |
Adds unit tests for override/aggregation semantics across multiple streams. |
tests/miral/config_file.cpp |
Adds a large suite of tests covering override dir loading/reloading and symlink cases. |
examples/mir_demo_server/server_example.cpp |
Switches demo server to load multi-file configs via load_files(). |
| override_loader{load_config}, | ||
| base_config_filename{base_config.filename().string()}, | ||
| override_directory{base_config_filename + ".d"}, | ||
| base_config_directory{config_directory(base_config.filename())}, |
There was a problem hiding this comment.
base_config_directory is derived from config_directory(base_config.filename()), which drops any explicit parent path the caller provided (e.g. /tmp/foo.conf). That causes override watching to monitor $XDG_CONFIG_HOME/$HOME/.config instead of the supplied directory. Use config_directory(base_config) so explicit paths behave correctly.
| base_config_directory{config_directory(base_config.filename())}, | |
| base_config_directory{config_directory(base_config)}, |
| public: | ||
| /// Loader functor is passed both the open stream and the actual path (for use in reporting problems) | ||
| using Loader = std::function<void(std::istream& istream, std::filesystem::path const& path)>; | ||
| using OverrideLoader = | ||
| std::function<void(std::span<std::pair<std::unique_ptr<std::istream>, std::filesystem::path>>)>; | ||
|
|
There was a problem hiding this comment.
This header now uses std::span and std::pair/std::unique_ptr in the public API, but it doesn’t include <span> (and <utility> for std::pair). Relying on transitive includes makes the header non-self-contained and can break compilation for consumers.
| #include <miral/test_server.h> | ||
| #include <miral/config_file.h> | ||
|
|
||
| #include <source_location> |
There was a problem hiding this comment.
#include <source_location> appears unused in this test file (no references found). If the build treats warnings as errors, this can fail CI; please remove it or use it.
| #include <source_location> |
| @@ -54,6 +56,7 @@ class ConfigFile | |||
| }; | |||
|
|
|||
| ConfigFile(MirRunner& runner, std::filesystem::path file, Mode mode, Loader load_config); | |||
| ConfigFile(MirRunner& runner, std::filesystem::path file, Mode mode, OverrideLoader load_config); | |||
| ~ConfigFile(); | |||
There was a problem hiding this comment.
Adding an overload that takes OverrideLoader makes call sites using generic lambdas (e.g. [](auto&... args){...}) ambiguous because such lambdas are callable with both (istream&, path) and (span<...>). Consider making the overload selection unambiguous (e.g. via a tag type, a differently-named constructor/factory, or documenting that callers should wrap lambdas in ConfigFile::Loader{...} / ConfigFile::OverrideLoader{...}).
|
Ok, splitting |
7270cfd to
0009e12
Compare
88e7411 to
3a5de42
Compare
ea3d4b1 to
49f4970
Compare
|
After a quick discussion with @Saviq, we're going to implement this without support for symlinks initially. That can come later. |
49f4970 to
ec5910c
Compare
3a5de42 to
4d8e03b
Compare
6208929 to
db1da86
Compare
18f47be to
2801040
Compare
db1da86 to
f48fb79
Compare
2801040 to
5c5a932
Compare
`reloads_when_override_file_is_added`
- Test reload on override directory deletion at runtime - Test reload when a symlinked override file is added after startup and its target is modified - Test reload when a relative symlinked override file target is modified
base config directory
2c9295a to
a7f2815
Compare
What's new?
TODO
How to test
Checklist