Documentation
¶
Overview ¶
Package config loads application configuration from embedded TOML files, user override files, and environment variables.
Each TOML file is a namespace. A file named "database.toml" creates a namespace called "database"; its keys are addressed as `config.String("database.<key.path>")`. This mirrors the pattern used in production by real Go services.
Priority order for each namespace (highest wins):
- environment variables (mapped via env.yaml)
- user config files with the same filename
- embedded default TOML files
The env.yaml file is a binding declaration, not app config. See ADR-0005. Its top-level keys are namespaces; its leaves map dotted config keys to environment variable names:
database: dsn: MYAPP_DATABASE_DSN log: level: MYAPP_LOG_LEVEL
Example:
//go:embed defaults/*.toml env.yaml
var configFS embed.FS
store, err := config.Load(config.Config{
Defaults: configFS,
DefaultsDir: "defaults",
EnvMap: configFS,
EnvMapFile: "env.yaml",
UserDir: "~/.config/myapp",
})
if err != nil { return err }
dsn := store.String("database.dsn")
port := store.Int("server.port")
Index ¶
- func Bool(path string) bool
- func Duration(path string) time.Duration
- func Float64(path string) float64
- func Has(path string) bool
- func Int(path string) int
- func Namespaces() []string
- func Set(path string, value any) error
- func SetDefault(s *Store)
- func String(path string) string
- func StringSlice(path string) []string
- func Unmarshal(path string, target any) error
- func ViperFor(namespace string) *viper.Viper
- type Config
- type Store
- func (s *Store) Bool(fullpath string) bool
- func (s *Store) Duration(fullpath string) time.Duration
- func (s *Store) Float64(fullpath string) float64
- func (s *Store) Has(fullpath string) bool
- func (s *Store) Int(fullpath string) int
- func (s *Store) Namespaces() []string
- func (s *Store) Schema(namespace string) cue.Value
- func (s *Store) Set(fullpath string, value any) error
- func (s *Store) String(fullpath string) string
- func (s *Store) StringSlice(fullpath string) []string
- func (s *Store) Unmarshal(fullpath string, target any) error
- func (s *Store) Validate(namespace string) error
- func (s *Store) Viper(namespace string) *viper.Viper
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Namespaces ¶
func Namespaces() []string
Namespaces returns the sorted namespace list from the default store, or nil.
func Set ¶
Set overrides a value in the default store. Returns an error if no default has been set or the namespace is unknown.
func SetDefault ¶
func SetDefault(s *Store)
SetDefault installs s as the package-level default. Subsequent calls to the package-level accessors delegate to s. Safe to call at any time; typically invoked once from a config provider's Register hook.
func StringSlice ¶
StringSlice returns the []string at path in the default store, or nil.
Types ¶
type Config ¶
type Config struct {
// Sources is an ordered list of fs.FS layers. Each source is scanned
// for *.toml + *.cue files; later sources override earlier ones for
// the same namespace (for TOML) or unify with them (for CUE).
//
// Typical ordering:
//
// []fs.FS{
// hexdb.Configs(), // framework defaults + schema
// hexcache.Configs(),
// appconfig.Files, // consumer overrides + own schema.cue
// }
Sources []fs.FS
// SourcesDir is the subdirectory scanned within each source. Empty
// means the source's root.
SourcesDir string
// UserDir is an optional directory on disk containing user override
// files. For each namespace <name>, if UserDir contains a matching
// <name>.toml it is merged over the layered sources. Leading ~ in
// UserDir is expanded to the user's home directory. Missing UserDir
// is not an error.
UserDir string
// EnvMap is an fs.FS containing the env-var binding YAML. Optional.
EnvMap fs.FS
// EnvMapFile is the path within EnvMap to the binding YAML. When empty,
// no env-var bindings are applied.
EnvMapFile string
// EnvFile is an optional path to a .env file loaded before env-var
// bindings resolve. Missing files are ignored.
//
// When Environment is non-empty, Load also attempts to load
// `<EnvFile>.<Environment>` FIRST (so values there win over the
// base .env). Common pattern:
//
// .env local defaults (typically gitignored)
// .env.test committed; test overrides
// .env.production committed; production overrides
//
// OS env still wins over anything godotenv loads.
EnvFile string
// Environment names the runtime environment. When non-empty, Load
// also loads `<EnvFile>.<Environment>` (see EnvFile above) to
// apply env-specific overrides.
//
// Env-bound values (declared in EnvMap / env.yaml) participate in
// CUE schema validation at Load time, so bad env overrides fail
// loudly like bad TOML values would.
Environment string
// StrictValidation, when true, causes Load to return an error if any
// loaded TOML namespace has no matching schema. Off by default —
// consumers opt into schemas per-namespace.
StrictValidation bool
}
Config configures a Load call.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store holds all loaded configuration namespaces. Each namespace is a separate *viper.Viper with its own defaults, overrides, and env-var bindings. Value access uses dotted paths of the form "<namespace>.<key.path>".
func Default ¶
func Default() *Store
Default returns the current package-level Store, or nil if SetDefault has not been called.
func Load ¶
Load builds a Store by walking every cfg.Sources FS in order, merging any user override files from cfg.UserDir, and binding env-var overrides. CUE schemas found in any source are unified per namespace and applied at the end. Missing files (empty source, no user dir, no .env) are not errors.
func (*Store) Duration ¶
Duration returns the time.Duration at path, parsed via time.ParseDuration on strings like "5s" or "1h30m". Zero on error.
func (*Store) Namespaces ¶
Namespaces returns the sorted list of loaded namespace names. Useful for diagnostics and for consumers wiring commands like `myapp config list`.
func (*Store) Schema ¶
Schema returns the merged CUE schema value for a namespace, or the zero cue.Value when no schema was registered. Useful for doc generation or programmatic constraint inspection.
func (*Store) Set ¶
Set overrides a value at runtime. Useful for tests; production paths should prefer files or env vars.
func (*Store) StringSlice ¶
StringSlice returns the []string at path, or nil.
func (*Store) Unmarshal ¶
Unmarshal decodes the value at path into target (a pointer). To unmarshal an entire namespace, pass "<namespace>".
Directories
¶
| Path | Synopsis |
|---|---|
|
Package lua exposes hex/config to Lua scripts as the "config" module.
|
Package lua exposes hex/config to Lua scripts as the "config" module. |
|
Package provider is the default hex/config service provider.
|
Package provider is the default hex/config service provider. |