config

package
v0.0.2-alpha Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 11, 2026 License: MIT Imports: 16 Imported by: 0

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):

  1. environment variables (mapped via env.yaml)
  2. user config files with the same filename
  3. 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

Constants

This section is empty.

Variables

This section is empty.

Functions

func Bool

func Bool(path string) bool

Bool returns the bool at path in the default store, or false if no default is set.

func Duration

func Duration(path string) time.Duration

Duration returns the duration at path in the default store, or 0.

func Float64

func Float64(path string) float64

Float64 returns the float64 at path in the default store, or 0.

func Has

func Has(path string) bool

Has reports whether path is set in the default store.

func Int

func Int(path string) int

Int returns the int at path in the default store, or 0 if no default is set.

func Namespaces

func Namespaces() []string

Namespaces returns the sorted namespace list from the default store, or nil.

func Set

func Set(path string, value any) error

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 String

func String(path string) string

String returns the string at path in the default store, or "" if no default is set.

func StringSlice

func StringSlice(path string) []string

StringSlice returns the []string at path in the default store, or nil.

func Unmarshal

func Unmarshal(path string, target any) error

Unmarshal decodes path into target using the default store. Returns an error if no default has been set.

func ViperFor

func ViperFor(namespace string) *viper.Viper

ViperFor returns the raw *viper.Viper for a namespace in the default store. Escape hatch. Returns nil if there is no default or no such namespace.

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

func Load(cfg Config) (*Store, error)

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) Bool

func (s *Store) Bool(fullpath string) bool

Bool returns the bool at path, or false if unset or invalid.

func (*Store) Duration

func (s *Store) Duration(fullpath string) time.Duration

Duration returns the time.Duration at path, parsed via time.ParseDuration on strings like "5s" or "1h30m". Zero on error.

func (*Store) Float64

func (s *Store) Float64(fullpath string) float64

Float64 returns the float64 at path, or 0 if unset or invalid.

func (*Store) Has

func (s *Store) Has(fullpath string) bool

Has reports whether path resolves to a set value.

func (*Store) Int

func (s *Store) Int(fullpath string) int

Int returns the int at path, or 0 if unset or invalid.

func (*Store) Namespaces

func (s *Store) Namespaces() []string

Namespaces returns the sorted list of loaded namespace names. Useful for diagnostics and for consumers wiring commands like `myapp config list`.

func (*Store) Schema

func (s *Store) Schema(namespace string) cue.Value

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

func (s *Store) Set(fullpath string, value any) error

Set overrides a value at runtime. Useful for tests; production paths should prefer files or env vars.

func (*Store) String

func (s *Store) String(fullpath string) string

String returns the string at path, or "" if unset or invalid.

func (*Store) StringSlice

func (s *Store) StringSlice(fullpath string) []string

StringSlice returns the []string at path, or nil.

func (*Store) Unmarshal

func (s *Store) Unmarshal(fullpath string, target any) error

Unmarshal decodes the value at path into target (a pointer). To unmarshal an entire namespace, pass "<namespace>".

func (*Store) Validate

func (s *Store) Validate(namespace string) error

Validate re-runs schema validation against the current in-memory values for a namespace. Runtime overrides via Set() bypass validation by default; call Validate to check them explicitly.

func (*Store) Viper

func (s *Store) Viper(namespace string) *viper.Viper

Viper returns the underlying *viper.Viper for a namespace, or nil if the namespace is not loaded. Escape hatch for consumers that need Viper methods hex does not expose.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL