config

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2026 License: Apache-2.0 Imports: 9 Imported by: 6

Documentation

Overview

Package config loads layered JSON configuration and defines the contract a configuration type implements to take part in that load. A configuration is loaded, used to construct the subsystems, and discarded.

The package exports:

  • Config, the constraint a configuration type's pointer satisfies
  • Load, which reads, merges, and finalizes the files
  • Options, which locates and names the files Load reads
  • EnvName, which composes an environment-variable name from a prefix
  • SetFromEnv and SetDurationFromEnv, which apply one environment override to a field
  • Duration, a time.Duration that reads from and writes to JSON

The contract

A configuration is a type T whose pointer implements Config: a Merge that overlays another instance's set fields onto the receiver, and a Finalize that runs, in order:

  • composes its environment override names from a prefix
  • applies defaults
  • reads the overrides
  • validates

Layered load

Load reads up to four files from a directory, in a fixed precedence, and merges each one that exists onto a zero value of T:

  • a base file (config.json),
  • an environment overlay (config.<env>.json),
  • a secrets file (secrets.json), and
  • a secrets overlay (secrets.<env>.json).

The value of the Options.EnvVar variable selects the active environment. The variable is named explicitly or derived from Options.EnvPrefix as the prefixed "env" name. When the value is empty, Load skips both overlays; a value containing a path separator or ".." fails the load.

A single Options.OverlayPattern produces both overlay names from the base and secrets stems. Load validates the pattern and fails one that misuses its verbs or drops the stem or the environment, rather than silently misnaming the overlays.

Every file is optional: Load skips a missing file, so a load with no files present yields a configuration carrying only what Finalize supplies. Any other read error, malformed JSON, or a key T does not declare stops the load. Every file decodes into the same T, so a secrets file carries only keys T declares.

Later sources win: the secrets overlay overrides the secrets file, which overrides the environment overlay, which overrides the base. A set source field always wins over an unset receiver. Finalize runs once, after every file has been merged, receiving Options.EnvPrefix.

Environment overrides

A capability pairs its configuration with an Env struct naming the variables its Finalize reads. Env fields are excluded from JSON and are output, not input: each Finalize composes its own names from the prefix it receives and records them on Env for introspection. An empty prefix composes no names, so nothing in the environment applies; hermetic tests rely on that. Once a prefix is supplied, the overrides Finalize reads take precedence over every file.

EnvName composes the names. SetFromEnv applies one override to a tri-state (pointer) field through a parse function, and SetDurationFromEnv is its Duration form.

Durations

Duration is a time.Duration that reads from JSON as "1m30s" or integer nanoseconds. Duration.Set parses the string form, and Duration.Duration returns the standard type.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EnvName

func EnvName(prefix string, parts ...string) string

EnvName composes an environment-variable name from a prefix and parts: each segment upper-cases, runs of characters outside A-Z and 0-9 collapse to single underscores, and empty segments drop out, so EnvName("app", "db", "host") is "APP_DB_HOST". A prefix empty once sanitized composes no name: EnvName returns "", which every reader in this module treats as no override.

func Load

func Load[T any, PT Config[T]](opts Options) (PT, error)

Load reads the layered configuration files opts names — base, environment overlay, secrets, secrets overlay, later files winning — merges each one that exists onto a zero value of T, finalizes the result, and returns it. A missing file is skipped; a read failure, malformed JSON, a key T does not declare, a malformed overlay pattern, an environment value containing a path separator or "..", or a Finalize error stops the load.

func SetDurationFromEnv

func SetDurationFromEnv(dest **Duration, name string) error

SetDurationFromEnv is SetFromEnv parsing with Duration.Set.

func SetFromEnv added in v0.5.0

func SetFromEnv[T any](dest **T, name string, parse func(string) (T, error)) error

SetFromEnv parses the environment variable name with parse and points dest at the result. An unset or empty variable, or an empty name, leaves dest untouched; a parse failure returns an error naming the variable.

Types

type Config

type Config[T any] interface {
	*T
	Merge(src *T)
	Finalize(envPrefix string) error
}

Config is the constraint Load places on *T: Merge overlays src's set fields onto the receiver, and Finalize applies defaults and envPrefix-named overrides, then validates.

type Duration

type Duration time.Duration

Duration is a time.Duration that reads from JSON as "1m30s" or integer nanoseconds, and writes as the string form.

func (Duration) Duration

func (d Duration) Duration() time.Duration

Duration returns the value as a time.Duration.

func (Duration) MarshalJSON

func (d Duration) MarshalJSON() ([]byte, error)

MarshalJSON encodes the duration as its string form.

func (*Duration) Set

func (d *Duration) Set(value string) error

Set parses value with time.ParseDuration and stores the result. An empty value is a no-op, so an unset environment variable leaves the receiver unchanged.

func (Duration) String

func (d Duration) String() string

func (*Duration) UnmarshalJSON

func (d *Duration) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes a duration string or an integer number of nanoseconds; null leaves the value unchanged, and any other number is rejected.

type Options

type Options struct {
	// Dir is the directory the files are read from; "." when empty.
	Dir string
	// EnvPrefix is passed to Finalize to name the environment overrides, and
	// derives EnvVar when that is empty. An empty EnvPrefix disables the
	// overrides and the derivation; an EnvVar set explicitly still selects the
	// overlays.
	EnvPrefix string
	// EnvVar names the variable whose value selects the overlay environment;
	// empty derives <PREFIX>_ENV from EnvPrefix. An unset or empty value
	// skips both overlays.
	EnvVar string
	// BaseName is the base file name; "config.json" when empty.
	BaseName string
	// SecretsName is the secrets file name; "secrets.json" when empty.
	SecretsName string
	// OverlayPattern produces an overlay name from a file's stem and the
	// environment, using both; "%s.%s.json" when empty.
	OverlayPattern string
}

Options locates and names the files Load reads. The zero value reads config.json and secrets.json from the current directory, with no environment overlays and no environment overrides.

Jump to

Keyboard shortcuts

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