Documentation
¶
Overview ¶
Package cfgcascade provides a generic, layered configuration cascade.
A Cascade resolves configuration by loading values from ranked providers (least-specific first), merging them with a caller-supplied function, and tracking which providers contributed to the final value.
Providers that return os.ErrNotExist are silently skipped (source not present). Any other error is recorded but does not stop resolution.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cascade ¶
type Cascade[T any] struct { // Layers are the ranked config sources. They do not need to be pre-sorted; // Resolve sorts them by Rank before processing. Layers []Layer[T] // MergeFn combines two values. It receives (base, overlay) where overlay // comes from the higher-ranked (more specific) layer. The returned value // becomes the new base for subsequent merges. MergeFn func(base, overlay T) T }
Cascade merges config layers in rank order using a provided merge function.
func (*Cascade[T]) Resolve ¶
func (c *Cascade[T]) Resolve(getenv func(string) string) *ResolvedValue[T]
Resolve loads all layers in rank order (ascending), skips providers that return os.ErrNotExist, records real errors, and merges using MergeFn.
If no provider succeeds, Value will be the zero value of T with an empty Sources slice.
type DefaultProvider ¶
DefaultProvider returns a static default value. It never fails.
func (*DefaultProvider[T]) Load ¶
func (p *DefaultProvider[T]) Load(_ func(string) string) (T, error)
func (*DefaultProvider[T]) Name ¶
func (p *DefaultProvider[T]) Name() string
type EnvProvider ¶
type EnvProvider struct {
// ProviderName is the human-readable name for this provider.
ProviderName string
// Prefix is the env var prefix to match (e.g. "TAP_"). Only variables
// starting with this prefix are included.
Prefix string
// Keys lists the env var names (without prefix) to look up. If empty,
// the provider returns ErrNotExist. Each key is looked up as Prefix+key.
// For example, Keys=["DEFAULT_KEG", "LOG_LEVEL"] with Prefix="TAP_"
// looks up TAP_DEFAULT_KEG and TAP_LOG_LEVEL.
Keys []string
}
EnvProvider reads environment variables with a configurable prefix and returns a map[string]string of stripped, lowercased keys.
For example, with prefix "TAP_" and env vars TAP_DEFAULT_KEG=home and TAP_LOG_LEVEL=debug, Load returns {"default_keg": "home", "log_level": "debug"}.
If no matching env vars are found, Load returns os.ErrNotExist so the cascade treats it as an absent source.
func (*EnvProvider) Load ¶
Load reads environment variables matching Prefix+key for each key in Keys. The getenv parameter accepts a func(string) string for env var lookup, keeping cfgcascade decoupled from any specific env abstraction. Runtime- managed applications should pass their sandboxed lookup (e.g. rt.Env().Get) to preserve test isolation. If getenv is nil, falls back to os.Getenv for standalone use outside Runtime-managed applications.
func (*EnvProvider) Name ¶
func (p *EnvProvider) Name() string
type FuncProvider ¶
type FuncProvider[T any] struct { ProviderName string Fn func(getenv func(string) string) (T, error) }
FuncProvider wraps a function as a Provider.
func (*FuncProvider[T]) Load ¶
func (p *FuncProvider[T]) Load(getenv func(string) string) (T, error)
func (*FuncProvider[T]) Name ¶
func (p *FuncProvider[T]) Name() string
type Layer ¶
Layer is a ranked config source. Lower Rank values are less specific (loaded first, overridden by higher ranks).
type MissingProvider ¶
MissingProvider always returns os.ErrNotExist. Useful for representing an optional source that is not configured.
func (*MissingProvider[T]) Load ¶
func (p *MissingProvider[T]) Load(_ func(string) string) (T, error)
func (*MissingProvider[T]) Name ¶
func (p *MissingProvider[T]) Name() string
type Provider ¶
type Provider[T any] interface { // Load returns a value from this source. Return an error wrapping // os.ErrNotExist to signal that the source is absent (graceful skip). Load(getenv func(string) string) (T, error) // Name returns a human-readable name for this provider (e.g. "user-config", // "env-vars"). Name() string }
Provider loads a config value from a single source.
type ProviderError ¶
ProviderError records a provider that failed with a non-ErrNotExist error.
func (ProviderError) Error ¶
func (pe ProviderError) Error() string
func (ProviderError) Unwrap ¶
func (pe ProviderError) Unwrap() error
type ResolvedValue ¶
type ResolvedValue[T any] struct { // Value is the final merged configuration. Value T // Sources lists the names of providers that contributed, ordered from // most-specific (highest rank) to least-specific. Sources []string // Errors lists providers that returned non-ErrNotExist errors. Errors []ProviderError }
ResolvedValue holds the merged result and provenance metadata.