Skip to content

Simpler config override#4926

Merged
Saviq merged 5 commits into
mainfrom
simpler-config-override
May 8, 2026
Merged

Simpler config override#4926
Saviq merged 5 commits into
mainfrom
simpler-config-override

Conversation

@tarek-y-ismail
Copy link
Copy Markdown
Contributor

Related #4781, #4858, #4830

What's new?

  • Merges ConfigAggregator and IniFile, producing a simpler implementation.

How to test

  • <path/to/build>/bin/miral-test/miral-test --gtest_filter=IniFileWithOverridesTest*

Checklist

  • Tests added and pass
  • Adequate documentation added

@tarek-y-ismail tarek-y-ismail self-assigned this May 4, 2026
@tarek-y-ismail tarek-y-ismail marked this pull request as ready for review May 4, 2026 11:53
Copilot AI review requested due to automatic review settings May 4, 2026 11:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new MirAL live-config store that can load and merge configuration from multiple ini streams (base + override layers) in a single transaction, aligning with the goal of simplifying layered config overrides.

Changes:

  • Added miral::live_config::IniFileWithOverrides as a public MirAL Store implementation that loads multiple ini streams with last-writer-wins scalars and accumulative arrays.
  • Added a focused gtest suite validating override precedence, array accumulation/clearing, presets, reload behavior, and handler/done callback semantics.
  • Wired the new API into build/packaging and exported the ABI symbols for MirAL 5.8.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/miral/ini_file_with_overrides.cpp Adds unit tests covering multi-file override semantics and handler behavior.
tests/miral/CMakeLists.txt Includes the new test file in miral-test.
src/miral/ini_file_with_overrides.cpp Implements parsing/loading of ordered ini streams into a single BasicStore transaction.
include/miral/miral/ini_file_with_overrides.h Adds the new public MirAL API for layered ini loading.
src/miral/CMakeLists.txt Builds/installs the new MirAL implementation + header.
src/miral/symbols.map Exports the new symbols under MIRAL_5.8.
debian/libmiral7.symbols Updates Debian symbol tracking for the new ABI additions.

Comment thread include/miral/miral/ini_file_with_overrides.h Outdated
Comment on lines +32 to +46
namespace
{
auto trim_start_and_end(std::string_view string) -> std::string_view
{
constexpr auto whitespace = " \t\n\r\f\v";

auto const first_non_space = string.find_first_not_of(whitespace);
if (first_non_space == std::string::npos)
{
return string.substr(0, 0);
}

auto const last_non_space = string.find_last_not_of(whitespace);
return string.substr(first_non_space, last_non_space - first_non_space + 1);
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, can be moved to a shared header/source. Will do that if this comes to pass.

Copy link
Copy Markdown
Contributor

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what the right load signature is, but shared an idea

Comment thread include/miral/miral/ini_file_with_overrides.h Outdated
Comment thread src/miral/ini_file_with_overrides.cpp
Comment thread include/miral/miral/ini_file_with_overrides.h Outdated
Comment thread include/miral/miral/live_config.h Outdated
Comment thread include/miral/miral/live_config.h Outdated
Comment thread include/miral/miral/live_config.h Outdated
Copy link
Copy Markdown
Contributor

@RAOF RAOF left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also reasonable, once Alan's comments are addressed.

Comment thread include/miral/miral/live_config.h Outdated
@AlanGriffiths
Copy link
Copy Markdown
Contributor

Passing a span<> affords a lot of usage patterns we don't want or need to support. A input/forward iterator would be a clearer expression of the semantics.

@RAOF
Copy link
Copy Markdown
Contributor

RAOF commented May 5, 2026

Passing a span<> affords a lot of usage patterns we don't want or need to support. A input/forward iterator would be a clearer expression of the semantics.

For what it's worth, I agree with this, but don't have as strong an opinion as Alan; I'm fine with span<>, though I do think the iterator would be better.

@AlanGriffiths
Copy link
Copy Markdown
Contributor

Let me offer another approach that avoids abusing unique_ptr<> to make span compile and to pretend that istream is copyable:

using FileLoader = std::movable_function<void(path, istream&)>;
using FileDropped= std::movable_function<void(path)>;

class FileChanges
{
public:

     virtual void for_each(FileLoader unchanged, FileLoader moved_or_new, FileLoader modified, FileDropped dropped) const = 0;
};

void load(FileChanges const& changes);

@RAOF
Copy link
Copy Markdown
Contributor

RAOF commented May 5, 2026

I continue to prefer #4926 (comment) (although possibly with OverrideElement as a concrete pimpl rather than interface), but I don't think any of the options are fundamentally critically flawed — we need to be careful about vtables vs ABI and ownership, but otherwise I don't block any of them.

@tarek-y-ismail
Copy link
Copy Markdown
Contributor Author

I've explored the two suggestions and some others. Both should work, but I really couldn't choose between either so I just picked one randomly and massaged it into the code. Tell me what you think.

Comment thread include/miral/miral/live_config.h Outdated
Comment thread include/miral/miral/live_config.h Outdated
Comment thread include/miral/miral/live_config.h Outdated
Comment thread include/miral/miral/live_config.h Outdated
Comment thread include/miral/miral/live_config.h Outdated
Comment thread src/miral/CMakeLists.txt Outdated
@tarek-y-ismail tarek-y-ismail force-pushed the simpler-config-override branch from d6ceab2 to 5fa2180 Compare May 5, 2026 14:33
Comment thread src/miral/file_changes_builder.h Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 8 comments.

Comment thread tests/miral/CMakeLists.txt
Comment thread include/miral/miral/live_config_overrides_list.h
Comment thread src/miral/live_config_file_changes_builder.h Outdated
Comment thread include/miral/miral/live_config_file_changes.h Outdated
Comment thread debian/libmiral7.symbols Outdated
Comment thread src/miral/CMakeLists.txt
Comment thread src/miral/live_config_overrides_list.cpp
Comment thread src/miral/live_config_overrides_list_builder.cpp
Copy link
Copy Markdown
Contributor

@RAOF RAOF left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, looks fine; some nits.

Comment thread include/miral/miral/live_config_file_changes.h Outdated
Comment thread include/miral/miral/live_config_file_changes.h Outdated
Comment thread src/miral/live_config_file_changes_builder.h Outdated
@tarek-y-ismail tarek-y-ismail requested a review from RAOF May 6, 2026 09:00
Comment thread src/miral/live_config_file_changes_builder.h Outdated
Comment thread src/miral/live_config_file_changes_builder.h Outdated
Comment thread src/miral/live_config_file_changes.cpp Outdated
@tarek-y-ismail tarek-y-ismail force-pushed the simpler-config-override branch from 70e03ca to 4695d95 Compare May 6, 2026 10:35
Copy link
Copy Markdown
Contributor

@RAOF RAOF left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The interface looks fine to me; a couple more nits in the implementation though.

Comment thread src/miral/live_config_file_changes.cpp Outdated
Comment thread src/miral/live_config_file_changes.cpp Outdated
Comment thread src/miral/live_config_file_changes.cpp Outdated
Comment thread src/miral/live_config_file_changes.cpp Outdated
Comment thread src/miral/live_config_file_changes.cpp Outdated
Copy link
Copy Markdown
Contributor

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a little polish needed

Comment thread src/miral/live_config_file_changes.cpp Outdated
Comment thread src/miral/live_config_file_changes_builder.h Outdated
Copy link
Copy Markdown
Contributor

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The blocking problem is publishing the FileChanges constructor. It is public, the symbol should be available.

At some point in the future we have the option of providing a way to supply a std::unique_ptr<Context> through a public builder. There's no need to cause confusion by having a public ctor with no corresponding symbol

Comment thread src/miral/live_config_file_changes_builder.cpp Outdated
Comment thread src/miral/live_config_file_changes_builder.h Outdated
Comment thread src/miral/live_config_file_changes_builder.h Outdated
Comment thread include/miral/miral/live_config_file_changes.h Outdated
Comment thread include/miral/miral/live_config_file_changes.h Outdated
Comment thread include/miral/miral/live_config_ini_file_with_overrides.h Outdated
Comment thread include/miral/miral/live_config_ini_file_with_overrides.h Outdated
Copy link
Copy Markdown
Contributor

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fine. (A few optional nits)

BUT we should sort out the git history before landing

Comment thread include/miral/miral/live_config_overrides_list.h Outdated
Comment thread include/miral/miral/live_config_overrides_list.h Outdated
Comment thread include/miral/miral/live_config_overrides_list.h Outdated
Comment thread src/miral/live_config_ini_file_with_overrides.cpp Outdated
OverridesList is an ordered, immutable list of file-change events (unchanged,
new, modified, or dropped) that can be iterated to drive config reloads.

An OverridesListBuilder is provided (in miral-internal) so that callers can
push events and then call build() to obtain a ready-to-iterate OverridesList.

Each event stores a file_opener callback that opens the file on demand and
calls the supplied Loader; if opening fails the event is treated as a drop.
Renamed-file events are no longer modelled; callers should emit a drop
followed by a fresh event instead.
The trim-whitespace helper and per-line parser loop that lived inside
IniFile::Self::load_file() are pulled out into parse_ini() in
live_config_ini_file_common.{h,cpp} (a miral-internal translation unit).

IniFileWithOverrides will reuse the same helper in a subsequent commit,
avoiding code duplication.
IniFileWithOverrides extends the existing IniFile concept to support
multiple layered configuration files.  Its load(OverridesList const&) method
iterates all file-change events in the OverridesList in push order, merging
the results before dispatching attribute handlers.

Merge semantics:
  - Scalar keys use last-writer-wins: a later (higher-priority) file's value
    replaces any earlier value.
  - Array keys accumulate across files; an empty assignment (key=) in a
    later file clears all values accumulated from earlier files.
  - on_done fires exactly once per load() call.
Covers:
  - Later files override earlier scalar values (last-writer-wins)
  - Array values accumulate across files
  - An empty assignment in a later file clears prior array entries
  - Mixed scalar + array keys across multiple files
  - on_done fires exactly once per load(), even with multiple files
  - Preset values are returned when no file provides the key
  - Keys absent from all files invoke handlers with std::nullopt
  - IniFile (single-file) still works after the parse_ini() refactor
Add MIRAL_5.8 entries to both symbols.map (the linker version script) and
debian/libmiral7.symbols for all public and vtable/typeinfo symbols introduced
by OverridesList and IniFileWithOverrides.
@tarek-y-ismail tarek-y-ismail force-pushed the simpler-config-override branch from da0b587 to f0370f6 Compare May 7, 2026 13:05
@AlanGriffiths AlanGriffiths enabled auto-merge May 7, 2026 13:21
@AlanGriffiths AlanGriffiths added this pull request to the merge queue May 7, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks May 7, 2026
@tarek-y-ismail tarek-y-ismail added this pull request to the merge queue May 8, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks May 8, 2026
@Saviq Saviq added this pull request to the merge queue May 8, 2026
Merged via the queue into main with commit 914a17f May 8, 2026
61 of 67 checks passed
@Saviq Saviq deleted the simpler-config-override branch May 8, 2026 09:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants