Skip to content

refactor(engine:config): Switch to TOML loader and two-phase registry#33

Open
ollieread wants to merge 11 commits into
mainfrom
refactor/toml-config
Open

refactor(engine:config): Switch to TOML loader and two-phase registry#33
ollieread wants to merge 11 commits into
mainfrom
refactor/toml-config

Conversation

@ollieread
Copy link
Copy Markdown
Member

Summary

  • Adds TomlLoader — reads config.toml + config.d/*.toml + modules-enabled/*.toml, merges deeply, interpolates ${VAR} / ${VAR:-default} against Env
  • Adds ConfigRegistry with a three-phase lifecycle (open → sealCore() → seal()); produces the existing immutable ConfigCatalogue
  • Adds ModulesEnabled as the first core config so the module system can read enabled-module identifiers between the two seal calls
  • Adds InvalidConfigException, ConfigNotRegisteredException, ConfigLifecycleException

Closes #31.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown

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

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 ConfigRegistry with sealCore() → seal() lifecycle plus new config exceptions and a core ModulesEnabled config.
  • Updates config objects/tests to hydrate via ConfigObject::fromArray() and removes the legacy BaseConfigObject/__set_state pattern.

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.

Comment thread src/Database/Config/DatabaseConfig.php
Comment thread src/Database/Config/DatabaseConfig.php
Comment thread src/Config/ConfigRegistry.php
Comment thread src/Config/ConfigRegistry.php
Comment thread src/Config/TomlLoader.php Outdated
Comment thread src/Config/Contracts/ConfigObject.php
Comment thread src/Config/Modules/ModulesEnabled.php
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.
Copy link
Copy Markdown

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 66 out of 90 changed files in this pull request and generated 4 comments.

Comment thread src/Database/ConnectionFactory.php Outdated
Comment thread src/Config/ConfigRegistry.php
Comment thread src/Config/TomlLoader.php Outdated
Comment thread src/Config/Contracts/ConfigObject.php
… 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
Copy link
Copy Markdown

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 66 out of 90 changed files in this pull request and generated 8 comments.

Comment thread src/Config/ConfigRegistry.php
Comment thread src/Config/TomlLoader.php
Comment thread tests/Unit/Config/TomlLoaderTest.php
Comment thread tests/Unit/Config/EndToEndTest.php
Comment thread src/Database/Config/DatabaseConfig.php
Comment thread src/Database/Config/ConnectionConfig.php
Comment thread src/Config/ConfigRegistry.php
Comment thread src/Config/ConfigRegistry.php Outdated
ollieread added 4 commits May 20, 2026 20:09
- 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
Copy link
Copy Markdown

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 71 out of 96 changed files in this pull request and generated no new comments.

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.

Engine - Config - TOML

2 participants