refactor(engine:config): Switch to TOML loader and two-phase registry#33
Open
ollieread wants to merge 11 commits into
Open
refactor(engine:config): Switch to TOML loader and two-phase registry#33ollieread wants to merge 11 commits into
ollieread wants to merge 11 commits into
Conversation
TomlLoader reads config.toml/config.d/modules-enabled; ConfigRegistry hydrates it into the existing ConfigCatalogue. Closes #31.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
Refactors the engine’s configuration system to load and merge TOML files (including drop-ins and module-specific configs), perform env-var interpolation, and build an immutable ConfigCatalogue via a new two-phase ConfigRegistry lifecycle so modules can discover enabled modules before registering their own config objects.
Changes:
- Introduces
TomlLoader,ConfigPaths, and TOML fixture/test coverage for merge order, reserved keys, module namespacing, and env interpolation. - Adds
ConfigRegistrywithsealCore() → seal()lifecycle plus new config exceptions and a coreModulesEnabledconfig. - Updates config objects/tests to hydrate via
ConfigObject::fromArray()and removes the legacyBaseConfigObject/__set_statepattern.
Reviewed changes
Copilot reviewed 63 out of 87 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Unit/Database/Config/DatabaseConfigTest.php | Adds DatabaseConfig::fromArray() hydration/validation tests. |
| tests/Unit/Database/Config/ConnectionConfigTest.php | Migrates tests from __set_state() to fromArray() and adds validation coverage. |
| tests/Unit/Config/TomlLoaderTest.php | Comprehensive unit tests for TOML loading, deep merge, reserved keys, modules-enabled, and env interpolation. |
| tests/Unit/Config/Modules/ModulesEnabledTest.php | Unit tests for the new ModulesEnabled core config. |
| tests/Unit/Config/Fixtures/toml/sort-test/modules-enabled/zeta.toml | Fixture module file for ordering/sort tests. |
| tests/Unit/Config/Fixtures/toml/sort-test/modules-enabled/aardvark.toml | Fixture module file for ordering/sort tests. |
| tests/Unit/Config/Fixtures/toml/sort-test/config.toml | Base fixture for ordering/sort tests. |
| tests/Unit/Config/Fixtures/toml/sort-test/config.d/zzz-last.toml | Drop-in fixture to verify deterministic ordering. |
| tests/Unit/Config/Fixtures/toml/sort-test/config.d/aaa-first.toml | Drop-in fixture to verify deterministic ordering. |
| tests/Unit/Config/Fixtures/toml/reserved-via-dropin/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/reserved-via-dropin/config.toml | Base fixture for reserved-key-via-drop-in test. |
| tests/Unit/Config/Fixtures/toml/reserved-via-dropin/config.d/01-bad.toml | Drop-in fixture that attempts to declare a reserved key. |
| tests/Unit/Config/Fixtures/toml/reserved-modules/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/reserved-modules/config.toml | Fixture that declares a reserved [modules] key. |
| tests/Unit/Config/Fixtures/toml/reserved-modules/config.d/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/reserved-enabled/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/reserved-enabled/config.toml | Fixture that declares reserved __enabled_modules. |
| tests/Unit/Config/Fixtures/toml/reserved-enabled/config.d/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/modules/modules-enabled/billing.toml | Fixture module config content (billing). |
| tests/Unit/Config/Fixtures/toml/modules/modules-enabled/admin.toml | Fixture module config content (admin). |
| tests/Unit/Config/Fixtures/toml/modules/config.toml | Base fixture for module namespacing tests. |
| tests/Unit/Config/Fixtures/toml/modules/config.d/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/missing-modules-dir/config.toml | Fixture for missing modules-enabled directory behavior. |
| tests/Unit/Config/Fixtures/toml/missing-modules-dir/config.d/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/missing-main/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/missing-main/config.d/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/missing-dropins-dir/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/missing-dropins-dir/config.toml | Fixture for missing config.d directory behavior. |
| tests/Unit/Config/Fixtures/toml/malformed/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/malformed/config.toml | Fixture for TOML parse error wrapping. |
| tests/Unit/Config/Fixtures/toml/malformed/config.d/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/env-missing/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/env-missing/config.toml | Fixture for missing env var interpolation error. |
| tests/Unit/Config/Fixtures/toml/env-missing/config.d/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/env-missing-list/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/env-missing-list/config.toml | Fixture for missing env var in array element path reporting. |
| tests/Unit/Config/Fixtures/toml/env-missing-list/config.d/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/env-interp/modules-enabled/admin.toml | Fixture for env interpolation inside module file content. |
| tests/Unit/Config/Fixtures/toml/env-interp/config.toml | Fixture for env interpolation behaviors and defaults. |
| tests/Unit/Config/Fixtures/toml/env-interp/config.d/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/empty-dropin/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/empty-dropin/config.toml | Fixture for empty drop-in merge no-op behavior. |
| tests/Unit/Config/Fixtures/toml/empty-dropin/config.d/01-empty.toml | Empty drop-in fixture for deep merge edge case. |
| tests/Unit/Config/Fixtures/toml/e2e/modules-enabled/admin.toml | E2E fixture module file content. |
| tests/Unit/Config/Fixtures/toml/e2e/config.toml | E2E fixture base config with env interpolation. |
| tests/Unit/Config/Fixtures/toml/e2e/config.d/01-secrets.toml | E2E drop-in fixture to verify merge + interpolation. |
| tests/Unit/Config/Fixtures/toml/dropin-scalar-over-table/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/dropin-scalar-over-table/config.toml | Fixture where base has table and drop-in replaces with scalar. |
| tests/Unit/Config/Fixtures/toml/dropin-scalar-over-table/config.d/01-disable.toml | Drop-in fixture to replace a table with a scalar. |
| tests/Unit/Config/Fixtures/toml/dropin-one-side-indexed/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/dropin-one-side-indexed/config.toml | Fixture where base is table and drop-in is indexed array. |
| tests/Unit/Config/Fixtures/toml/dropin-one-side-indexed/config.d/01-replace.toml | Drop-in fixture replacing assoc with list wholesale. |
| tests/Unit/Config/Fixtures/toml/dropin-multi-key/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/dropin-multi-key/config.toml | Fixture base config for multi-top-level-key drop-in merge. |
| tests/Unit/Config/Fixtures/toml/dropin-multi-key/config.d/01-override.toml | Drop-in fixture containing multiple top-level keys. |
| tests/Unit/Config/Fixtures/toml/drop-ins/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/drop-ins/config.toml | Base fixture for drop-in merge tests. |
| tests/Unit/Config/Fixtures/toml/drop-ins/config.d/02-secrets.toml | Drop-in fixture to verify last-wins on scalars. |
| tests/Unit/Config/Fixtures/toml/drop-ins/config.d/01-override.toml | Drop-in fixture to verify deep merge + array replacement. |
| tests/Unit/Config/Fixtures/toml/basic/modules-enabled/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/toml/basic/config.toml | Basic fixture for main-file parsing tests. |
| tests/Unit/Config/Fixtures/toml/basic/config.d/.gitkeep | Keeps fixture directory in VCS. |
| tests/Unit/Config/Fixtures/ThrowingConfigObject.php | Test-only config object that throws to exercise exception wrapping. |
| tests/Unit/Config/Fixtures/TestConfigObject.php | Updates test config object to fromArray() and readonly construction. |
| tests/Unit/Config/Fixtures/MultiKeyConfigObject.php | Test config object used to verify multi-key subtree hydration. |
| tests/Unit/Config/Fixtures/AnotherTestConfigObject.php | Updates another test config object to fromArray() and readonly construction. |
| tests/Unit/Config/Exceptions/ExceptionsTest.php | Adds unit tests for new config exception types and messages. |
| tests/Unit/Config/EndToEndTest.php | End-to-end test covering loader → registry → catalogue flow. |
| tests/Unit/Config/ConfigRegistryTest.php | Unit tests for registry lifecycle, hydration, and error paths. |
| tests/Unit/Config/ConfigPathsTest.php | Unit tests for ConfigPaths value object. |
| src/Database/Config/DatabaseConfig.php | Switches to ConfigObject::fromArray() hydration with Webmozart assertions. |
| src/Database/Config/ConnectionConfig.php | Switches to ConfigObject::fromArray() hydration with validation. |
| src/Container/ReflectionHelper.php | Tightens callable array phpdoc typing. |
| src/Container/Container.php | Corrects phpdoc for qualified instance storage structure. |
| src/Config/TomlLoader.php | Implements TOML read/merge, modules-enabled namespacing, and env interpolation. |
| src/Config/Modules/ModulesEnabled.php | Adds new core config object for enabled module identifiers. |
| src/Config/Exceptions/InvalidConfigException.php | Adds exception for loader/hydration failures with contextual helpers. |
| src/Config/Exceptions/ConfigNotRegisteredException.php | Adds exception for registry lookups of unregistered config classes. |
| src/Config/Exceptions/ConfigLifecycleException.php | Adds exception for invalid registry lifecycle operations. |
| src/Config/CoreConfig.php | Adds core mapping for pre-module-discovery configs. |
| src/Config/Contracts/ConfigObject.php | Changes config object contract from __set_state() to fromArray(). |
| src/Config/ConfigRegistry.php | Adds two-phase registry to hydrate core configs then module configs into ConfigCatalogue. |
| src/Config/ConfigPaths.php | Adds value object to carry config file/directory paths. |
| src/Config/BaseConfigObject.php | Removes legacy base class used for __set_state() restoration. |
| infection.json5 | Updates Infection config (phpstan integration + ignore list adjustments). |
| composer.json | Adds TOML/assert dependencies and updates scripts (analyse, suite). |
| .github/workflows/static-analysis.yml | Updates CI to call composer analyse. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Value-rule assertions (non-empty strings, host-vs-socket invariants, primary-in-connections, ConnectionConfig instances) move from fromArray() into ConnectionConfig and DatabaseConfig constructors so make() and direct construction cannot produce invalid instances.
… PHPDoc - seal() now throws when called before sealCore() - sealCore() rejects non-array tree sections with InvalidConfigException - TomlLoader checks reserved keys per file, naming the actual offender - pluck() reports the module file path in errors - ConfigObject/ModulesEnabled fromArray() PHPDoc widened to array-key - ConnectionFactory asserts host/port non-null before sprintf
- ConfigRegistry and TomlLoader reject dotted module/name identifiers (would otherwise break pluck's dot-split lookup) - TomlLoaderTest and EndToEndTest setUp() reset Env first for isolation - isIndexed() empty-array carve-out documented as intentional - PHPDoc widened to array<array-key, mixed> on fromArray impls, hydrate(), and pluck() to match the interface
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
TomlLoader— readsconfig.toml+config.d/*.toml+modules-enabled/*.toml, merges deeply, interpolates${VAR}/${VAR:-default}againstEnvConfigRegistrywith a three-phase lifecycle (open → sealCore() → seal()); produces the existing immutableConfigCatalogueModulesEnabledas the first core config so the module system can read enabled-module identifiers between the two seal callsInvalidConfigException,ConfigNotRegisteredException,ConfigLifecycleExceptionCloses #31.