2026-03-18 00:14:44 +00:00
|
|
|
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
|
|
|
|
|
|
// Settings, feature flags, and typed configuration for the Core framework.
|
|
|
|
|
|
|
|
|
|
package core
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"sync"
|
|
|
|
|
)
|
|
|
|
|
|
feat: complete DTO pattern — struct literals, no constructors
- All New* constructors removed (NewApp, NewIO, NewCoreCli, NewBus, NewService, NewCoreI18n, NewConfig)
- New() uses pure struct literals: &App{}, &Fs{}, &Config{ConfigOpts:}, &Cli{opts:}, &Service{}, &Ipc{}, &I18n{}
- Ipc methods moved to func (c *Core) — Ipc is now a DTO
- LockApply only called from WithServiceLock, not on every New()
- Service map lazy-inits on first write
- CliOpts DTO with Version/Name/Description
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 10:53:13 +00:00
|
|
|
// ConfigVar is a variable that can be set, unset, and queried for its state.
|
feat: restructure Core as unified struct with DTO pattern
Complete architectural overhaul of pkg/core:
- All subsystem types renamed to idiomatic Go (no stutter)
- Core struct: App, Embed, Fs, Config, ErrPan, ErrLog, Cli, Service, Lock, Ipc, I18n
- Exports consolidated in core.go, contracts/options in contract.go
- Service() unified get/register: c.Service(), c.Service("name"), c.Service("name", svc)
- Lock() named mutex map: c.Lock("srv"), c.Lock("ipc")
- Error system: Err/ErrLog/ErrPan + Log/LogErr/LogPan (shared ErrSink interface)
- CoreCommand with optional description (i18n resolves from command path)
- Tests moved to tests/ directory (black-box package core_test)
- Removed: ServiceFor/MustServiceFor, global instance, Display/Workspace/Crypt interfaces
- New files: app.go, fs.go, ipc.go, lock.go, i18n.go, task.go, runtime.go, contract.go
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 09:12:29 +00:00
|
|
|
type ConfigVar[T any] struct {
|
2026-03-18 00:14:44 +00:00
|
|
|
val T
|
|
|
|
|
set bool
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 18:07:42 +00:00
|
|
|
// Get returns the current value.
|
|
|
|
|
//
|
|
|
|
|
// val := v.Get()
|
|
|
|
|
func (v *ConfigVar[T]) Get() T { return v.val }
|
|
|
|
|
|
|
|
|
|
// Set sets the value and marks it as explicitly set.
|
|
|
|
|
//
|
|
|
|
|
// v.Set(true)
|
|
|
|
|
func (v *ConfigVar[T]) Set(val T) { v.val = val; v.set = true }
|
|
|
|
|
|
|
|
|
|
// IsSet returns true if the value was explicitly set (distinguishes "set to false" from "never set").
|
|
|
|
|
//
|
|
|
|
|
// if v.IsSet() { /* explicitly configured */ }
|
feat: restructure Core as unified struct with DTO pattern
Complete architectural overhaul of pkg/core:
- All subsystem types renamed to idiomatic Go (no stutter)
- Core struct: App, Embed, Fs, Config, ErrPan, ErrLog, Cli, Service, Lock, Ipc, I18n
- Exports consolidated in core.go, contracts/options in contract.go
- Service() unified get/register: c.Service(), c.Service("name"), c.Service("name", svc)
- Lock() named mutex map: c.Lock("srv"), c.Lock("ipc")
- Error system: Err/ErrLog/ErrPan + Log/LogErr/LogPan (shared ErrSink interface)
- CoreCommand with optional description (i18n resolves from command path)
- Tests moved to tests/ directory (black-box package core_test)
- Removed: ServiceFor/MustServiceFor, global instance, Display/Workspace/Crypt interfaces
- New files: app.go, fs.go, ipc.go, lock.go, i18n.go, task.go, runtime.go, contract.go
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 09:12:29 +00:00
|
|
|
func (v *ConfigVar[T]) IsSet() bool { return v.set }
|
2026-03-25 18:07:42 +00:00
|
|
|
|
|
|
|
|
// Unset resets to zero value and marks as not set.
|
|
|
|
|
//
|
|
|
|
|
// v.Unset()
|
|
|
|
|
// v.IsSet() // false
|
feat: restructure Core as unified struct with DTO pattern
Complete architectural overhaul of pkg/core:
- All subsystem types renamed to idiomatic Go (no stutter)
- Core struct: App, Embed, Fs, Config, ErrPan, ErrLog, Cli, Service, Lock, Ipc, I18n
- Exports consolidated in core.go, contracts/options in contract.go
- Service() unified get/register: c.Service(), c.Service("name"), c.Service("name", svc)
- Lock() named mutex map: c.Lock("srv"), c.Lock("ipc")
- Error system: Err/ErrLog/ErrPan + Log/LogErr/LogPan (shared ErrSink interface)
- CoreCommand with optional description (i18n resolves from command path)
- Tests moved to tests/ directory (black-box package core_test)
- Removed: ServiceFor/MustServiceFor, global instance, Display/Workspace/Crypt interfaces
- New files: app.go, fs.go, ipc.go, lock.go, i18n.go, task.go, runtime.go, contract.go
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 09:12:29 +00:00
|
|
|
func (v *ConfigVar[T]) Unset() {
|
2026-03-18 00:14:44 +00:00
|
|
|
v.set = false
|
|
|
|
|
var zero T
|
|
|
|
|
v.val = zero
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 18:07:42 +00:00
|
|
|
// NewConfigVar creates a ConfigVar with an initial value marked as set.
|
|
|
|
|
//
|
|
|
|
|
// debug := core.NewConfigVar(true)
|
feat: restructure Core as unified struct with DTO pattern
Complete architectural overhaul of pkg/core:
- All subsystem types renamed to idiomatic Go (no stutter)
- Core struct: App, Embed, Fs, Config, ErrPan, ErrLog, Cli, Service, Lock, Ipc, I18n
- Exports consolidated in core.go, contracts/options in contract.go
- Service() unified get/register: c.Service(), c.Service("name"), c.Service("name", svc)
- Lock() named mutex map: c.Lock("srv"), c.Lock("ipc")
- Error system: Err/ErrLog/ErrPan + Log/LogErr/LogPan (shared ErrSink interface)
- CoreCommand with optional description (i18n resolves from command path)
- Tests moved to tests/ directory (black-box package core_test)
- Removed: ServiceFor/MustServiceFor, global instance, Display/Workspace/Crypt interfaces
- New files: app.go, fs.go, ipc.go, lock.go, i18n.go, task.go, runtime.go, contract.go
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 09:12:29 +00:00
|
|
|
func NewConfigVar[T any](val T) ConfigVar[T] {
|
|
|
|
|
return ConfigVar[T]{val: val, set: true}
|
2026-03-18 00:14:44 +00:00
|
|
|
}
|
|
|
|
|
|
refactor: AX audit fixes — no direct strings/fmt, full type names
Direct strings import removed from: data.go, error.go, fs.go
→ uses Split, SplitN, TrimPrefix, TrimSuffix, HasPrefix, Replace, Contains, Join
Direct fmt import removed from: fs.go
→ uses Print() from utils.go
fmt.Errorf in panic recovery → NewError(fmt.Sprint("panic: ", r))
Abbreviated type names renamed:
ConfigOpts → ConfigOptions
LogOpts → LogOptions
RotationLogOpts → RotationLogOptions
embed.go keeps strings import (strings.NewReader, strings.Builder).
error.go keeps fmt import (fmt.Sprint for panic values).
232 tests, 77.8% coverage.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 13:47:23 +00:00
|
|
|
// ConfigOptions holds configuration data.
|
|
|
|
|
type ConfigOptions struct {
|
feat: complete DTO pattern — struct literals, no constructors
- All New* constructors removed (NewApp, NewIO, NewCoreCli, NewBus, NewService, NewCoreI18n, NewConfig)
- New() uses pure struct literals: &App{}, &Fs{}, &Config{ConfigOpts:}, &Cli{opts:}, &Service{}, &Ipc{}, &I18n{}
- Ipc methods moved to func (c *Core) — Ipc is now a DTO
- LockApply only called from WithServiceLock, not on every New()
- Service map lazy-inits on first write
- CliOpts DTO with Version/Name/Description
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 10:53:13 +00:00
|
|
|
Settings map[string]any
|
|
|
|
|
Features map[string]bool
|
2026-03-18 00:14:44 +00:00
|
|
|
}
|
|
|
|
|
|
refactor: AX audit fixes — no direct strings/fmt, full type names
Direct strings import removed from: data.go, error.go, fs.go
→ uses Split, SplitN, TrimPrefix, TrimSuffix, HasPrefix, Replace, Contains, Join
Direct fmt import removed from: fs.go
→ uses Print() from utils.go
fmt.Errorf in panic recovery → NewError(fmt.Sprint("panic: ", r))
Abbreviated type names renamed:
ConfigOpts → ConfigOptions
LogOpts → LogOptions
RotationLogOpts → RotationLogOptions
embed.go keeps strings import (strings.NewReader, strings.Builder).
error.go keeps fmt import (fmt.Sprint for panic values).
232 tests, 77.8% coverage.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 13:47:23 +00:00
|
|
|
func (o *ConfigOptions) init() {
|
feat: complete DTO pattern — struct literals, no constructors
- All New* constructors removed (NewApp, NewIO, NewCoreCli, NewBus, NewService, NewCoreI18n, NewConfig)
- New() uses pure struct literals: &App{}, &Fs{}, &Config{ConfigOpts:}, &Cli{opts:}, &Service{}, &Ipc{}, &I18n{}
- Ipc methods moved to func (c *Core) — Ipc is now a DTO
- LockApply only called from WithServiceLock, not on every New()
- Service map lazy-inits on first write
- CliOpts DTO with Version/Name/Description
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 10:53:13 +00:00
|
|
|
if o.Settings == nil {
|
|
|
|
|
o.Settings = make(map[string]any)
|
|
|
|
|
}
|
|
|
|
|
if o.Features == nil {
|
|
|
|
|
o.Features = make(map[string]bool)
|
2026-03-18 00:14:44 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
feat: complete DTO pattern — struct literals, no constructors
- All New* constructors removed (NewApp, NewIO, NewCoreCli, NewBus, NewService, NewCoreI18n, NewConfig)
- New() uses pure struct literals: &App{}, &Fs{}, &Config{ConfigOpts:}, &Cli{opts:}, &Service{}, &Ipc{}, &I18n{}
- Ipc methods moved to func (c *Core) — Ipc is now a DTO
- LockApply only called from WithServiceLock, not on every New()
- Service map lazy-inits on first write
- CliOpts DTO with Version/Name/Description
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 10:53:13 +00:00
|
|
|
// Config holds configuration settings and feature flags.
|
|
|
|
|
type Config struct {
|
refactor: AX audit fixes — no direct strings/fmt, full type names
Direct strings import removed from: data.go, error.go, fs.go
→ uses Split, SplitN, TrimPrefix, TrimSuffix, HasPrefix, Replace, Contains, Join
Direct fmt import removed from: fs.go
→ uses Print() from utils.go
fmt.Errorf in panic recovery → NewError(fmt.Sprint("panic: ", r))
Abbreviated type names renamed:
ConfigOpts → ConfigOptions
LogOpts → LogOptions
RotationLogOpts → RotationLogOptions
embed.go keeps strings import (strings.NewReader, strings.Builder).
error.go keeps fmt import (fmt.Sprint for panic values).
232 tests, 77.8% coverage.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 13:47:23 +00:00
|
|
|
*ConfigOptions
|
feat: complete DTO pattern — struct literals, no constructors
- All New* constructors removed (NewApp, NewIO, NewCoreCli, NewBus, NewService, NewCoreI18n, NewConfig)
- New() uses pure struct literals: &App{}, &Fs{}, &Config{ConfigOpts:}, &Cli{opts:}, &Service{}, &Ipc{}, &I18n{}
- Ipc methods moved to func (c *Core) — Ipc is now a DTO
- LockApply only called from WithServiceLock, not on every New()
- Service map lazy-inits on first write
- CliOpts DTO with Version/Name/Description
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 10:53:13 +00:00
|
|
|
mu sync.RWMutex
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-24 20:40:33 +00:00
|
|
|
// New initialises a Config with empty settings and features.
|
|
|
|
|
//
|
|
|
|
|
// cfg := (&core.Config{}).New()
|
|
|
|
|
func (e *Config) New() *Config {
|
|
|
|
|
e.ConfigOptions = &ConfigOptions{}
|
|
|
|
|
e.ConfigOptions.init()
|
|
|
|
|
return e
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-18 00:14:44 +00:00
|
|
|
// Set stores a configuration value by key.
|
feat: restructure Core as unified struct with DTO pattern
Complete architectural overhaul of pkg/core:
- All subsystem types renamed to idiomatic Go (no stutter)
- Core struct: App, Embed, Fs, Config, ErrPan, ErrLog, Cli, Service, Lock, Ipc, I18n
- Exports consolidated in core.go, contracts/options in contract.go
- Service() unified get/register: c.Service(), c.Service("name"), c.Service("name", svc)
- Lock() named mutex map: c.Lock("srv"), c.Lock("ipc")
- Error system: Err/ErrLog/ErrPan + Log/LogErr/LogPan (shared ErrSink interface)
- CoreCommand with optional description (i18n resolves from command path)
- Tests moved to tests/ directory (black-box package core_test)
- Removed: ServiceFor/MustServiceFor, global instance, Display/Workspace/Crypt interfaces
- New files: app.go, fs.go, ipc.go, lock.go, i18n.go, task.go, runtime.go, contract.go
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 09:12:29 +00:00
|
|
|
func (e *Config) Set(key string, val any) {
|
2026-03-18 00:14:44 +00:00
|
|
|
e.mu.Lock()
|
2026-03-20 17:25:12 +00:00
|
|
|
if e.ConfigOptions == nil {
|
|
|
|
|
e.ConfigOptions = &ConfigOptions{}
|
|
|
|
|
}
|
refactor: AX audit fixes — no direct strings/fmt, full type names
Direct strings import removed from: data.go, error.go, fs.go
→ uses Split, SplitN, TrimPrefix, TrimSuffix, HasPrefix, Replace, Contains, Join
Direct fmt import removed from: fs.go
→ uses Print() from utils.go
fmt.Errorf in panic recovery → NewError(fmt.Sprint("panic: ", r))
Abbreviated type names renamed:
ConfigOpts → ConfigOptions
LogOpts → LogOptions
RotationLogOpts → RotationLogOptions
embed.go keeps strings import (strings.NewReader, strings.Builder).
error.go keeps fmt import (fmt.Sprint for panic values).
232 tests, 77.8% coverage.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 13:47:23 +00:00
|
|
|
e.ConfigOptions.init()
|
feat: complete DTO pattern — struct literals, no constructors
- All New* constructors removed (NewApp, NewIO, NewCoreCli, NewBus, NewService, NewCoreI18n, NewConfig)
- New() uses pure struct literals: &App{}, &Fs{}, &Config{ConfigOpts:}, &Cli{opts:}, &Service{}, &Ipc{}, &I18n{}
- Ipc methods moved to func (c *Core) — Ipc is now a DTO
- LockApply only called from WithServiceLock, not on every New()
- Service map lazy-inits on first write
- CliOpts DTO with Version/Name/Description
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 10:53:13 +00:00
|
|
|
e.Settings[key] = val
|
2026-03-18 00:14:44 +00:00
|
|
|
e.mu.Unlock()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get retrieves a configuration value by key.
|
fix: AX audit round 5 — full naming, Result returns throughout
Renames (via GoLand refactor):
- Option.K → Key, Option.V → Value
- Err.Op → Operation, Err.Msg → Message, Err.Err → Error
- CrashSystem.OS → OperatingSystem, Arch → Architecture
- TaskID → TaskIdentifier, TaskWithID → TaskWithIdentifier
- Ipc → IPC, BaseDir → BaseDirectory
- ServiceRuntime.Opts → Options
Return type changes:
- Options.Get, Config.Get → Result (was (any, bool))
- Embed.ReadDir → Result (was ([]fs.DirEntry, error))
- Translator.Translate, I18n.Translate → Result (was string)
Rule 6:
- data.go: propagate opts.Get failure, typed error for bad fs.FS
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 16:32:43 +00:00
|
|
|
func (e *Config) Get(key string) Result {
|
2026-03-18 00:14:44 +00:00
|
|
|
e.mu.RLock()
|
feat: complete DTO pattern — struct literals, no constructors
- All New* constructors removed (NewApp, NewIO, NewCoreCli, NewBus, NewService, NewCoreI18n, NewConfig)
- New() uses pure struct literals: &App{}, &Fs{}, &Config{ConfigOpts:}, &Cli{opts:}, &Service{}, &Ipc{}, &I18n{}
- Ipc methods moved to func (c *Core) — Ipc is now a DTO
- LockApply only called from WithServiceLock, not on every New()
- Service map lazy-inits on first write
- CliOpts DTO with Version/Name/Description
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 10:53:13 +00:00
|
|
|
defer e.mu.RUnlock()
|
refactor: AX audit fixes — no direct strings/fmt, full type names
Direct strings import removed from: data.go, error.go, fs.go
→ uses Split, SplitN, TrimPrefix, TrimSuffix, HasPrefix, Replace, Contains, Join
Direct fmt import removed from: fs.go
→ uses Print() from utils.go
fmt.Errorf in panic recovery → NewError(fmt.Sprint("panic: ", r))
Abbreviated type names renamed:
ConfigOpts → ConfigOptions
LogOpts → LogOptions
RotationLogOpts → RotationLogOptions
embed.go keeps strings import (strings.NewReader, strings.Builder).
error.go keeps fmt import (fmt.Sprint for panic values).
232 tests, 77.8% coverage.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 13:47:23 +00:00
|
|
|
if e.ConfigOptions == nil || e.Settings == nil {
|
fix: AX audit round 5 — full naming, Result returns throughout
Renames (via GoLand refactor):
- Option.K → Key, Option.V → Value
- Err.Op → Operation, Err.Msg → Message, Err.Err → Error
- CrashSystem.OS → OperatingSystem, Arch → Architecture
- TaskID → TaskIdentifier, TaskWithID → TaskWithIdentifier
- Ipc → IPC, BaseDir → BaseDirectory
- ServiceRuntime.Opts → Options
Return type changes:
- Options.Get, Config.Get → Result (was (any, bool))
- Embed.ReadDir → Result (was ([]fs.DirEntry, error))
- Translator.Translate, I18n.Translate → Result (was string)
Rule 6:
- data.go: propagate opts.Get failure, typed error for bad fs.FS
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 16:32:43 +00:00
|
|
|
return Result{}
|
feat: complete DTO pattern — struct literals, no constructors
- All New* constructors removed (NewApp, NewIO, NewCoreCli, NewBus, NewService, NewCoreI18n, NewConfig)
- New() uses pure struct literals: &App{}, &Fs{}, &Config{ConfigOpts:}, &Cli{opts:}, &Service{}, &Ipc{}, &I18n{}
- Ipc methods moved to func (c *Core) — Ipc is now a DTO
- LockApply only called from WithServiceLock, not on every New()
- Service map lazy-inits on first write
- CliOpts DTO with Version/Name/Description
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 10:53:13 +00:00
|
|
|
}
|
|
|
|
|
val, ok := e.Settings[key]
|
fix: AX audit round 5 — full naming, Result returns throughout
Renames (via GoLand refactor):
- Option.K → Key, Option.V → Value
- Err.Op → Operation, Err.Msg → Message, Err.Err → Error
- CrashSystem.OS → OperatingSystem, Arch → Architecture
- TaskID → TaskIdentifier, TaskWithID → TaskWithIdentifier
- Ipc → IPC, BaseDir → BaseDirectory
- ServiceRuntime.Opts → Options
Return type changes:
- Options.Get, Config.Get → Result (was (any, bool))
- Embed.ReadDir → Result (was ([]fs.DirEntry, error))
- Translator.Translate, I18n.Translate → Result (was string)
Rule 6:
- data.go: propagate opts.Get failure, typed error for bad fs.FS
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 16:32:43 +00:00
|
|
|
if !ok {
|
|
|
|
|
return Result{}
|
|
|
|
|
}
|
|
|
|
|
return Result{val, true}
|
2026-03-18 00:14:44 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-25 18:07:42 +00:00
|
|
|
// String retrieves a string config value (empty string if missing).
|
|
|
|
|
//
|
|
|
|
|
// host := c.Config().String("database.host")
|
feat: restructure Core as unified struct with DTO pattern
Complete architectural overhaul of pkg/core:
- All subsystem types renamed to idiomatic Go (no stutter)
- Core struct: App, Embed, Fs, Config, ErrPan, ErrLog, Cli, Service, Lock, Ipc, I18n
- Exports consolidated in core.go, contracts/options in contract.go
- Service() unified get/register: c.Service(), c.Service("name"), c.Service("name", svc)
- Lock() named mutex map: c.Lock("srv"), c.Lock("ipc")
- Error system: Err/ErrLog/ErrPan + Log/LogErr/LogPan (shared ErrSink interface)
- CoreCommand with optional description (i18n resolves from command path)
- Tests moved to tests/ directory (black-box package core_test)
- Removed: ServiceFor/MustServiceFor, global instance, Display/Workspace/Crypt interfaces
- New files: app.go, fs.go, ipc.go, lock.go, i18n.go, task.go, runtime.go, contract.go
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 09:12:29 +00:00
|
|
|
func (e *Config) String(key string) string { return ConfigGet[string](e, key) }
|
2026-03-25 18:07:42 +00:00
|
|
|
|
|
|
|
|
// Int retrieves an int config value (0 if missing).
|
|
|
|
|
//
|
|
|
|
|
// port := c.Config().Int("database.port")
|
|
|
|
|
func (e *Config) Int(key string) int { return ConfigGet[int](e, key) }
|
|
|
|
|
|
|
|
|
|
// Bool retrieves a bool config value (false if missing).
|
|
|
|
|
//
|
|
|
|
|
// debug := c.Config().Bool("debug")
|
|
|
|
|
func (e *Config) Bool(key string) bool { return ConfigGet[bool](e, key) }
|
2026-03-18 00:14:44 +00:00
|
|
|
|
feat: restructure Core as unified struct with DTO pattern
Complete architectural overhaul of pkg/core:
- All subsystem types renamed to idiomatic Go (no stutter)
- Core struct: App, Embed, Fs, Config, ErrPan, ErrLog, Cli, Service, Lock, Ipc, I18n
- Exports consolidated in core.go, contracts/options in contract.go
- Service() unified get/register: c.Service(), c.Service("name"), c.Service("name", svc)
- Lock() named mutex map: c.Lock("srv"), c.Lock("ipc")
- Error system: Err/ErrLog/ErrPan + Log/LogErr/LogPan (shared ErrSink interface)
- CoreCommand with optional description (i18n resolves from command path)
- Tests moved to tests/ directory (black-box package core_test)
- Removed: ServiceFor/MustServiceFor, global instance, Display/Workspace/Crypt interfaces
- New files: app.go, fs.go, ipc.go, lock.go, i18n.go, task.go, runtime.go, contract.go
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 09:12:29 +00:00
|
|
|
// ConfigGet retrieves a typed configuration value.
|
|
|
|
|
func ConfigGet[T any](e *Config, key string) T {
|
fix: AX audit round 5 — full naming, Result returns throughout
Renames (via GoLand refactor):
- Option.K → Key, Option.V → Value
- Err.Op → Operation, Err.Msg → Message, Err.Err → Error
- CrashSystem.OS → OperatingSystem, Arch → Architecture
- TaskID → TaskIdentifier, TaskWithID → TaskWithIdentifier
- Ipc → IPC, BaseDir → BaseDirectory
- ServiceRuntime.Opts → Options
Return type changes:
- Options.Get, Config.Get → Result (was (any, bool))
- Embed.ReadDir → Result (was ([]fs.DirEntry, error))
- Translator.Translate, I18n.Translate → Result (was string)
Rule 6:
- data.go: propagate opts.Get failure, typed error for bad fs.FS
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 16:32:43 +00:00
|
|
|
r := e.Get(key)
|
|
|
|
|
if !r.OK {
|
2026-03-18 01:00:47 +00:00
|
|
|
var zero T
|
|
|
|
|
return zero
|
2026-03-18 00:14:44 +00:00
|
|
|
}
|
fix: AX audit round 5 — full naming, Result returns throughout
Renames (via GoLand refactor):
- Option.K → Key, Option.V → Value
- Err.Op → Operation, Err.Msg → Message, Err.Err → Error
- CrashSystem.OS → OperatingSystem, Arch → Architecture
- TaskID → TaskIdentifier, TaskWithID → TaskWithIdentifier
- Ipc → IPC, BaseDir → BaseDirectory
- ServiceRuntime.Opts → Options
Return type changes:
- Options.Get, Config.Get → Result (was (any, bool))
- Embed.ReadDir → Result (was ([]fs.DirEntry, error))
- Translator.Translate, I18n.Translate → Result (was string)
Rule 6:
- data.go: propagate opts.Get failure, typed error for bad fs.FS
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 16:32:43 +00:00
|
|
|
typed, _ := r.Value.(T)
|
2026-03-18 01:00:47 +00:00
|
|
|
return typed
|
2026-03-18 00:14:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- Feature Flags ---
|
|
|
|
|
|
2026-03-25 18:07:42 +00:00
|
|
|
// Enable activates a feature flag.
|
|
|
|
|
//
|
|
|
|
|
// c.Config().Enable("dark-mode")
|
feat: restructure Core as unified struct with DTO pattern
Complete architectural overhaul of pkg/core:
- All subsystem types renamed to idiomatic Go (no stutter)
- Core struct: App, Embed, Fs, Config, ErrPan, ErrLog, Cli, Service, Lock, Ipc, I18n
- Exports consolidated in core.go, contracts/options in contract.go
- Service() unified get/register: c.Service(), c.Service("name"), c.Service("name", svc)
- Lock() named mutex map: c.Lock("srv"), c.Lock("ipc")
- Error system: Err/ErrLog/ErrPan + Log/LogErr/LogPan (shared ErrSink interface)
- CoreCommand with optional description (i18n resolves from command path)
- Tests moved to tests/ directory (black-box package core_test)
- Removed: ServiceFor/MustServiceFor, global instance, Display/Workspace/Crypt interfaces
- New files: app.go, fs.go, ipc.go, lock.go, i18n.go, task.go, runtime.go, contract.go
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 09:12:29 +00:00
|
|
|
func (e *Config) Enable(feature string) {
|
2026-03-18 00:14:44 +00:00
|
|
|
e.mu.Lock()
|
2026-03-20 17:25:12 +00:00
|
|
|
if e.ConfigOptions == nil {
|
|
|
|
|
e.ConfigOptions = &ConfigOptions{}
|
|
|
|
|
}
|
refactor: AX audit fixes — no direct strings/fmt, full type names
Direct strings import removed from: data.go, error.go, fs.go
→ uses Split, SplitN, TrimPrefix, TrimSuffix, HasPrefix, Replace, Contains, Join
Direct fmt import removed from: fs.go
→ uses Print() from utils.go
fmt.Errorf in panic recovery → NewError(fmt.Sprint("panic: ", r))
Abbreviated type names renamed:
ConfigOpts → ConfigOptions
LogOpts → LogOptions
RotationLogOpts → RotationLogOptions
embed.go keeps strings import (strings.NewReader, strings.Builder).
error.go keeps fmt import (fmt.Sprint for panic values).
232 tests, 77.8% coverage.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 13:47:23 +00:00
|
|
|
e.ConfigOptions.init()
|
feat: complete DTO pattern — struct literals, no constructors
- All New* constructors removed (NewApp, NewIO, NewCoreCli, NewBus, NewService, NewCoreI18n, NewConfig)
- New() uses pure struct literals: &App{}, &Fs{}, &Config{ConfigOpts:}, &Cli{opts:}, &Service{}, &Ipc{}, &I18n{}
- Ipc methods moved to func (c *Core) — Ipc is now a DTO
- LockApply only called from WithServiceLock, not on every New()
- Service map lazy-inits on first write
- CliOpts DTO with Version/Name/Description
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 10:53:13 +00:00
|
|
|
e.Features[feature] = true
|
2026-03-18 00:14:44 +00:00
|
|
|
e.mu.Unlock()
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 18:07:42 +00:00
|
|
|
// Disable deactivates a feature flag.
|
|
|
|
|
//
|
|
|
|
|
// c.Config().Disable("dark-mode")
|
feat: restructure Core as unified struct with DTO pattern
Complete architectural overhaul of pkg/core:
- All subsystem types renamed to idiomatic Go (no stutter)
- Core struct: App, Embed, Fs, Config, ErrPan, ErrLog, Cli, Service, Lock, Ipc, I18n
- Exports consolidated in core.go, contracts/options in contract.go
- Service() unified get/register: c.Service(), c.Service("name"), c.Service("name", svc)
- Lock() named mutex map: c.Lock("srv"), c.Lock("ipc")
- Error system: Err/ErrLog/ErrPan + Log/LogErr/LogPan (shared ErrSink interface)
- CoreCommand with optional description (i18n resolves from command path)
- Tests moved to tests/ directory (black-box package core_test)
- Removed: ServiceFor/MustServiceFor, global instance, Display/Workspace/Crypt interfaces
- New files: app.go, fs.go, ipc.go, lock.go, i18n.go, task.go, runtime.go, contract.go
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 09:12:29 +00:00
|
|
|
func (e *Config) Disable(feature string) {
|
2026-03-18 00:14:44 +00:00
|
|
|
e.mu.Lock()
|
2026-03-20 17:25:12 +00:00
|
|
|
if e.ConfigOptions == nil {
|
|
|
|
|
e.ConfigOptions = &ConfigOptions{}
|
|
|
|
|
}
|
refactor: AX audit fixes — no direct strings/fmt, full type names
Direct strings import removed from: data.go, error.go, fs.go
→ uses Split, SplitN, TrimPrefix, TrimSuffix, HasPrefix, Replace, Contains, Join
Direct fmt import removed from: fs.go
→ uses Print() from utils.go
fmt.Errorf in panic recovery → NewError(fmt.Sprint("panic: ", r))
Abbreviated type names renamed:
ConfigOpts → ConfigOptions
LogOpts → LogOptions
RotationLogOpts → RotationLogOptions
embed.go keeps strings import (strings.NewReader, strings.Builder).
error.go keeps fmt import (fmt.Sprint for panic values).
232 tests, 77.8% coverage.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 13:47:23 +00:00
|
|
|
e.ConfigOptions.init()
|
feat: complete DTO pattern — struct literals, no constructors
- All New* constructors removed (NewApp, NewIO, NewCoreCli, NewBus, NewService, NewCoreI18n, NewConfig)
- New() uses pure struct literals: &App{}, &Fs{}, &Config{ConfigOpts:}, &Cli{opts:}, &Service{}, &Ipc{}, &I18n{}
- Ipc methods moved to func (c *Core) — Ipc is now a DTO
- LockApply only called from WithServiceLock, not on every New()
- Service map lazy-inits on first write
- CliOpts DTO with Version/Name/Description
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 10:53:13 +00:00
|
|
|
e.Features[feature] = false
|
2026-03-18 00:14:44 +00:00
|
|
|
e.mu.Unlock()
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 18:07:42 +00:00
|
|
|
// Enabled returns true if a feature flag is active.
|
|
|
|
|
//
|
|
|
|
|
// if c.Config().Enabled("dark-mode") { ... }
|
feat: restructure Core as unified struct with DTO pattern
Complete architectural overhaul of pkg/core:
- All subsystem types renamed to idiomatic Go (no stutter)
- Core struct: App, Embed, Fs, Config, ErrPan, ErrLog, Cli, Service, Lock, Ipc, I18n
- Exports consolidated in core.go, contracts/options in contract.go
- Service() unified get/register: c.Service(), c.Service("name"), c.Service("name", svc)
- Lock() named mutex map: c.Lock("srv"), c.Lock("ipc")
- Error system: Err/ErrLog/ErrPan + Log/LogErr/LogPan (shared ErrSink interface)
- CoreCommand with optional description (i18n resolves from command path)
- Tests moved to tests/ directory (black-box package core_test)
- Removed: ServiceFor/MustServiceFor, global instance, Display/Workspace/Crypt interfaces
- New files: app.go, fs.go, ipc.go, lock.go, i18n.go, task.go, runtime.go, contract.go
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 09:12:29 +00:00
|
|
|
func (e *Config) Enabled(feature string) bool {
|
2026-03-18 00:14:44 +00:00
|
|
|
e.mu.RLock()
|
2026-03-20 17:25:12 +00:00
|
|
|
defer e.mu.RUnlock()
|
|
|
|
|
if e.ConfigOptions == nil || e.Features == nil {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return e.Features[feature]
|
2026-03-18 00:14:44 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-25 18:07:42 +00:00
|
|
|
// EnabledFeatures returns all active feature flag names.
|
|
|
|
|
//
|
|
|
|
|
// features := c.Config().EnabledFeatures()
|
feat: restructure Core as unified struct with DTO pattern
Complete architectural overhaul of pkg/core:
- All subsystem types renamed to idiomatic Go (no stutter)
- Core struct: App, Embed, Fs, Config, ErrPan, ErrLog, Cli, Service, Lock, Ipc, I18n
- Exports consolidated in core.go, contracts/options in contract.go
- Service() unified get/register: c.Service(), c.Service("name"), c.Service("name", svc)
- Lock() named mutex map: c.Lock("srv"), c.Lock("ipc")
- Error system: Err/ErrLog/ErrPan + Log/LogErr/LogPan (shared ErrSink interface)
- CoreCommand with optional description (i18n resolves from command path)
- Tests moved to tests/ directory (black-box package core_test)
- Removed: ServiceFor/MustServiceFor, global instance, Display/Workspace/Crypt interfaces
- New files: app.go, fs.go, ipc.go, lock.go, i18n.go, task.go, runtime.go, contract.go
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 09:12:29 +00:00
|
|
|
func (e *Config) EnabledFeatures() []string {
|
2026-03-18 00:14:44 +00:00
|
|
|
e.mu.RLock()
|
|
|
|
|
defer e.mu.RUnlock()
|
2026-03-20 17:25:12 +00:00
|
|
|
if e.ConfigOptions == nil || e.Features == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2026-03-18 00:14:44 +00:00
|
|
|
var result []string
|
feat: complete DTO pattern — struct literals, no constructors
- All New* constructors removed (NewApp, NewIO, NewCoreCli, NewBus, NewService, NewCoreI18n, NewConfig)
- New() uses pure struct literals: &App{}, &Fs{}, &Config{ConfigOpts:}, &Cli{opts:}, &Service{}, &Ipc{}, &I18n{}
- Ipc methods moved to func (c *Core) — Ipc is now a DTO
- LockApply only called from WithServiceLock, not on every New()
- Service map lazy-inits on first write
- CliOpts DTO with Version/Name/Description
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 10:53:13 +00:00
|
|
|
for k, v := range e.Features {
|
2026-03-18 00:14:44 +00:00
|
|
|
if v {
|
|
|
|
|
result = append(result, k)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result
|
|
|
|
|
}
|