Module path changed from forge.lthn.ai/core/go-config to forge.lthn.ai/core/config. Package name remains "config" — only the module path changed. Co-Authored-By: Virgil <virgil@lethean.io>
3.4 KiB
3.4 KiB
| title | description |
|---|---|
| Development | How to build, test, and contribute to config. |
Development
Prerequisites
- Go 1.26+
- Core CLI (
corebinary) for running tests and quality checks - The Go workspace at
~/Code/go.workshould include this module
Running Tests
cd /path/to/config
# All tests
core go test
# Single test
core go test --run TestConfig_Get_Good
# With coverage
core go cov
core go cov --open # opens HTML report in browser
Test Naming Convention
Tests follow the _Good / _Bad / _Ugly suffix pattern:
| Suffix | Meaning |
|---|---|
_Good |
Happy path -- expected success |
_Bad |
Expected error conditions |
_Ugly |
Panics, edge cases, corruption |
Mock Medium
Tests use io.NewMockMedium() to avoid touching the real filesystem. Pre-populate it by writing directly to the Files map:
m := io.NewMockMedium()
m.Files["/tmp/test/config.yaml"] = "app:\n name: existing\n"
cfg, err := config.New(config.WithMedium(m), config.WithPath("/tmp/test/config.yaml"))
This pattern keeps tests fast, deterministic, and parallelisable.
Quality Checks
# Format, vet, lint, test in one pass
core go qa
# Full suite (adds race detector, vulnerability scan, security audit)
core go qa full
# Individual commands
core go fmt
core go vet
core go lint
Code Style
- UK English in comments and documentation (colour, organisation, centre)
declare(strict_types=1)equivalent: all functions have explicit parameter and return types- Error wrapping: use
coreerr.E(caller, message, underlying)fromgo-log - Formatting: standard
gofmt/goimports
Project Structure
config/
.core/
build.yaml # Build configuration (targets, flags)
release.yaml # Release configuration (changelog rules)
config.go # Config struct, New(), Get/Set/Commit, Load/Save
config_test.go # Tests
env.go # Env() iterator, LoadEnv() (deprecated)
service.go # Framework service wrapper (Startable)
go.mod
go.sum
docs/
index.md # This documentation
architecture.md # Internal design
development.md # Build and contribution guide
Adding a New Feature
- Write the test first -- add a
TestFeatureName_Good(and_Badif error paths exist) toconfig_test.go. - Implement -- keep the dual-viper invariant: writes go to both
vandf; reads come fromv; persistence comes fromf. - Run QA --
core go qamust pass before committing. - Update docs -- if the change affects public API, update
docs/index.mdanddocs/architecture.md.
Interface Compliance
Config and Service both satisfy core.Config. Service additionally satisfies core.Startable. These are enforced at compile time:
var _ core.Config = (*Config)(nil)
var _ core.Config = (*Service)(nil)
var _ core.Startable = (*Service)(nil)
If you add a new interface method upstream in core/go, the compiler will tell you what to implement here.
Commit Guidelines
- Use conventional commits:
type(scope): description - Include
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>when pair-programming with Claude - Push via SSH:
ssh://git@forge.lthn.ai:2223/core/config.git
Licence
EUPL-1.2