config

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2026 License: MIT Imports: 16 Imported by: 0

README

config

CI CodeQL Coverage Mutation Documentation Go Reference Release Go License

config loads explicit, layered configuration sources into caller-owned Go structs. It provides deterministic precedence, strict decoding, immutable snapshots, safe provenance, validation orchestration, and redacted secrets without introducing global state or implicit filesystem discovery.

The root library and its separately released AWS Secrets Manager adapter are stable v1 modules. Their minimum supported Go version is 1.26.6; repository verification currently tests exactly Go 1.26.6.

Install

go get github.com/faustbrian/go-config@v1
go get github.com/faustbrian/go-config/adapters/awssecretsmanager@v1

Install the second module only when an application reads configuration directly from AWS Secrets Manager.

Five-minute quickstart

package main

import (
	"context"
	"fmt"

	config "github.com/faustbrian/go-config"
	"github.com/faustbrian/go-config/defaults"
	"github.com/faustbrian/go-config/environment"
	jsonsource "github.com/faustbrian/go-config/json"
	"github.com/faustbrian/go-config/programmatic"
)

type Settings struct {
	Host  string        `config:"host" env:"HOST" default:"127.0.0.1"`
	Port  int           `config:"port" env:"PORT" default:"8080"`
	Token config.Secret `config:"token,secret" env:"TOKEN"`
}

func main() {
	forDefaults := defaults.For[Settings]
	base, _ := forDefaults("defaults")
	file, _ := jsonsource.Bytes(
		[]byte(`{"host":"service.internal","port":9000}`),
		jsonsource.Options{Name: "config.json"},
	)
	env, _ := environment.EnvironFor[Settings](
		[]string{"PORT=9443", "TOKEN=not-printed"},
		environment.Options{Name: "environment"},
	)
	override, _ := programmatic.Overrides(
		"command-line", map[string]any{"host": "localhost"},
	)

	plan, _ := config.NewDefaultPlan(config.DefaultSources{
		Defaults: []config.Source{base},
		DiscoveredBase: []config.Source{file},
		Environment: []config.Source{env},
		Overrides: []config.Source{override},
	})
	load := config.Load[Settings]
	snapshot, err := load(context.Background(), plan)
	if err != nil {
		panic(err)
	}

	settings := snapshot.Value()
	fmt.Printf("%s:%d token=%s\n", settings.Host, settings.Port, settings.Token)
	// localhost:9443 token=[REDACTED]
}

All constructors return errors; production code should handle them. The omitted checks above keep the precedence example compact. A complete version is in examples/quickstart.

Service command loading

The target-oriented adapters/service package adapts a typed plan to service.CommandSpec.Load. Import it conventionally as configservice. It loads only after command selection and before component construction. Local dotenv files require the explicit Local option; process environment and caller overrides retain the standard precedence.

loader, err := configservice.New(configservice.Options[Settings]{
    Local: true,
    Dotenv: &configservice.Dotenv{
        FS: os.DirFS("."),
        Path: ".env",
        Options: dotenv.Options{Name: "local-dotenv", Prefix: "APP_"},
    },
    Environment: &environment.Options{
        Name: "process-environment",
        Prefix: "APP_",
    },
})
if err != nil {
    return err
}

command := service.CommandFor(service.CommandSpec[Settings]{
    Name: "serve",
    Kind: service.CommandKindLongRunning,
    Load: loader,
    Build: build,
})

The adapter owns no resource, performs no retries, and does not reload configuration. The caller owns every source and decides whether repeated loads are safe.

The original github.com/faustbrian/go-config/configservice path remains an API-compatible facade, so existing consumers do not need to migrate in lockstep.

What is included

Strict JSON, YAML, TOML, dotenv, environment, map, byte, reader, fs.FS, and explicit-file sources compose with bounded discovery, merging, typed values, validation, immutable snapshots, provenance, and an optional service adapter.

The independently versioned github.com/faustbrian/go-config/adapters/awssecretsmanager module adapts one bounded AWS Secrets Manager JSON document into the same config.Source contract. Use it only when an operator, CSI driver, or sidecar does not already materialize the secret as an environment variable or file.

Documentation

For shared package selection, ownership, construction, and lifecycle guidance, see the versioned Golib ecosystem index and its Foundations family.

Use the documentation index for formats, layering, discovery, Kubernetes, security, migration, and package-author guidance. Observable structured-format choices are recorded in the specification decision register.

Design boundaries

The package does not load automatically, mutate process environment, traverse parents by default, execute configuration code, hot-reload snapshots, manage secrets, or define vendor credential structs. Kubernetes applications should normally receive Infisical values through the Operator, CSI, or Agent and load the resulting environment variables or files normally.

The root module starts no background goroutines, watchers, refresh loops, or retry loops and exposes no Close or Shutdown method. Callers own supplied sources and collaborators, decide when loads occur, and finish in-flight loads before releasing those collaborators. Built-in sources close the transient I/O they open during a load; returned snapshots remain immutable values rather than live resource handles. The AWS adapter follows the same no-shutdown boundary and leaves its client, transport, credentials, retries, and refresh scheduling with the caller.

Development

Run make check. See CONTRIBUTING.md for focused and release verification.

License

MIT. See LICENSE.

Documentation

Overview

Package config loads deterministic layered configuration snapshots.

Example (DefaultsAndProgrammaticSources)
package main

import (
	"context"
	"fmt"

	config "github.com/faustbrian/go-config"
	"github.com/faustbrian/go-config/defaults"
	"github.com/faustbrian/go-config/programmatic"
)

func main() {
	type settings struct {
		Name   string `config:"name" default:"default"`
		Region string `config:"region"`
		Port   int    `config:"port"`
	}
	typedDefaults, _ := defaults.For[settings]("typed-defaults")
	mapDefaults, _ := programmatic.Defaults(
		"map-defaults",
		map[string]any{"region": "eu"},
	)
	middle, _ := programmatic.Map(
		"runtime",
		config.PriorityExplicitFiles,
		map[string]any{"port": int64(8080)},
	)
	overrides, _ := programmatic.Overrides(
		"overrides",
		map[string]any{"name": "worker"},
	)
	plan, _ := config.NewPlan(overrides, middle, mapDefaults, typedDefaults)
	snapshot, _ := config.Load[settings](context.Background(), plan)
	value := snapshot.Value()
	fmt.Println(value.Name, value.Region, value.Port)
}
Output:
worker eu 8080
Example (DiscoveryAndValidation)
package main

import (
	"context"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"runtime"

	config "github.com/faustbrian/go-config"
	"github.com/faustbrian/go-config/discover"
	"github.com/faustbrian/go-config/filesystem"
	"github.com/faustbrian/go-config/validation"
)

func main() {
	directory, _ := os.MkdirTemp("", "config-discovery-")
	defer func() { _ = os.RemoveAll(directory) }()
	path := filepath.Join(directory, "app.yaml")
	_ = os.WriteFile(path, []byte("port: 8080\n"), 0o600)
	permissions := discover.OwnerOnly
	if runtime.GOOS == "windows" {
		permissions = discover.IgnorePermissions
	}
	results, _ := discover.Search(context.Background(), discover.Options{
		Root: directory, Directories: []string{directory},
		SearchPlaces: []string{"app.yaml"}, Mode: discover.SearchFirst,
		Symlinks: discover.RejectSymlinks, Permissions: permissions,
	})
	source, _ := filesystem.FromDiscovered(
		results[0],
		filesystem.Options{Name: "discovered", Priority: config.PriorityDiscoveredBase},
	)
	type settings struct {
		Port int `config:"port,required"`
	}
	plan, _ := config.NewPlan(source)
	snapshot, _ := config.LoadWithValidators(
		context.Background(),
		plan,
		func(_ context.Context, value settings) error {
			if value.Port < 1 || value.Port > 65535 {
				return validation.At("port", errors.New("port outside supported range"))
			}
			return nil
		},
	)
	fmt.Println(snapshot.Value().Port, results[0].SearchPlace)
}
Output:
8080 app.yaml
Example (DotenvSources)
package main

import (
	"context"
	"fmt"
	"testing/fstest"

	config "github.com/faustbrian/go-config"
	"github.com/faustbrian/go-config/dotenv"
)

func main() {
	type settings struct {
		FromBytes string `config:"from_bytes" env:"FROM_BYTES"`
		FromFS    string `config:"from_fs" env:"FROM_FS"`
	}
	files := fstest.MapFS{
		"settings.env": &fstest.MapFile{Data: []byte("APP_FROM_FS=${VALUE:-filesystem}\n")},
	}
	fromBytes, _ := dotenv.BytesFor[settings](
		[]byte("APP_FROM_BYTES=${VALUE:-bytes}\n"),
		dotenv.Options{
			Name: "dotenv-bytes", Prefix: "APP_",
			Interpolation: &dotenv.Interpolation{IncludeFile: true},
		},
	)
	fromFS, _ := dotenv.FromFSFor[settings](
		files,
		"settings.env",
		dotenv.Options{
			Name: "dotenv-fs", Prefix: "APP_",
			Interpolation: &dotenv.Interpolation{IncludeFile: true},
		},
	)
	plan, _ := config.NewPlan(fromBytes, fromFS)
	snapshot, _ := config.Load[settings](context.Background(), plan)
	fmt.Println(snapshot.Value().FromBytes, snapshot.Value().FromFS)
}
Output:
bytes filesystem
Example (EnvironmentSources)
package main

import (
	"context"
	"fmt"
	"os"

	config "github.com/faustbrian/go-config"
	"github.com/faustbrian/go-config/environment"
)

func main() {
	type settings struct {
		Explicit string `config:"explicit" env:"EXPLICIT"`
		Process  string `config:"process" env:"PROCESS"`
	}
	const processName = "GO_CONFIG_EXAMPLE_PROCESS"
	previous, existed := os.LookupEnv(processName)
	_ = os.Setenv(processName, "process")
	defer func() {
		if existed {
			_ = os.Setenv(processName, previous)
		} else {
			_ = os.Unsetenv(processName)
		}
	}()

	explicit, _ := environment.EnvironFor[settings](
		[]string{"GO_CONFIG_EXAMPLE_EXPLICIT=explicit"},
		environment.Options{Name: "explicit", Prefix: "GO_CONFIG_EXAMPLE_"},
	)
	process, _ := environment.ProcessFor[settings](environment.Options{
		Name: "process", Prefix: "GO_CONFIG_EXAMPLE_",
	})
	plan, _ := config.NewPlan(explicit, process)
	snapshot, _ := config.Load[settings](context.Background(), plan)
	fmt.Println(snapshot.Value().Explicit, snapshot.Value().Process)
}
Output:
explicit process
Example (FilesystemSources)
package main

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"testing/fstest"

	config "github.com/faustbrian/go-config"
	"github.com/faustbrian/go-config/discover"
	"github.com/faustbrian/go-config/filesystem"
)

func main() {
	files := fstest.MapFS{
		"embedded.json": &fstest.MapFile{Data: []byte(`{"embedded":"loaded"}`)},
	}
	fromFS, _ := filesystem.FromFS(
		files,
		"embedded.json",
		filesystem.Options{Name: "embedded"},
	)
	reader, _ := filesystem.Reader(
		func(context.Context) (io.ReadCloser, error) {
			return io.NopCloser(bytes.NewBufferString("reader: loaded\n")), nil
		},
		filesystem.Options{Name: "reader", Format: filesystem.FormatYAML},
	)

	directory, _ := os.MkdirTemp("", "config-example-")
	defer func() { _ = os.RemoveAll(directory) }()
	path := filepath.Join(directory, "settings.toml")
	_ = os.WriteFile(path, []byte(`path = "loaded"`), 0o600)
	fromPath, _ := filesystem.FromPath(path, filesystem.Options{Name: "path"})
	fromDiscovery, _ := filesystem.FromDiscovered(
		discover.Result{Path: path, ResolvedPath: path},
		filesystem.Options{Name: "discovered"},
	)

	plan, _ := config.NewPlan(fromFS, reader, fromPath, fromDiscovery)
	snapshot, _ := config.LoadTree(context.Background(), plan)
	value := snapshot.Value()
	fmt.Println(value["embedded"], value["reader"], value["path"])
}
Output:
loaded loaded loaded
Example (SecretsProvenanceAndConfigtest)
package main

import (
	"context"
	"errors"
	"fmt"

	config "github.com/faustbrian/go-config"
	"github.com/faustbrian/go-config/configtest"
)

func main() {
	type settings struct {
		Token config.Secret `config:"token,secret"`
	}
	fixture := configtest.NewSource(
		config.SourceInfo{Name: "fixture", Sensitive: true},
		config.Document{Tree: map[string]any{"token": "secret-value"}},
	)
	plan, _ := config.NewPlan(fixture)
	snapshot, _ := config.Load[settings](context.Background(), plan)
	origin, _ := snapshot.Origin("token")

	environmentFixture := configtest.Environment(map[string]string{"B": "2", "A": "1"})
	filesystemFixture := configtest.Filesystem(map[string]string{"config.json": `{}`})
	_, openErr := filesystemFixture.Open("config.json")
	failure := errors.New("fixture failure")
	failingPlan, _ := config.NewPlan(configtest.FailingSource(
		config.SourceInfo{Name: "failure"},
		failure,
	))
	_, loadErr := config.LoadTree(context.Background(), failingPlan)

	fmt.Println(snapshot.Value().Token, origin.Sensitive)
	fmt.Println(environmentFixture, openErr == nil, errors.Is(loadErr, failure))
}
Output:
[REDACTED] true
[A=1 B=2] true true
Example (StructuredSources)
package main

import (
	"context"
	"fmt"
	"testing/fstest"

	config "github.com/faustbrian/go-config"

	jsonsource "github.com/faustbrian/go-config/json"

	tomlsource "github.com/faustbrian/go-config/toml"

	yamlsource "github.com/faustbrian/go-config/yaml"
)

func main() {
	files := fstest.MapFS{
		"settings.json": &fstest.MapFile{Data: []byte(`{"json_fs":"loaded"}`)},
		"settings.yaml": &fstest.MapFile{Data: []byte("yaml_fs: loaded\n")},
		"settings.toml": &fstest.MapFile{Data: []byte(`toml_fs = "loaded"`)},
	}
	jsonBytes, _ := jsonsource.Bytes(
		[]byte(`{"json_bytes":"loaded"}`),
		jsonsource.Options{Name: "json-bytes"},
	)
	jsonFS, _ := jsonsource.FromFS(
		files,
		"settings.json",
		jsonsource.Options{Name: "json-fs"},
	)
	yamlBytes, _ := yamlsource.Bytes(
		[]byte("yaml_bytes: loaded\n"),
		yamlsource.Options{Name: "yaml-bytes"},
	)
	yamlFS, _ := yamlsource.FromFS(
		files,
		"settings.yaml",
		yamlsource.Options{Name: "yaml-fs"},
	)
	tomlBytes, _ := tomlsource.Bytes(
		[]byte(`toml_bytes = "loaded"`),
		tomlsource.Options{Name: "toml-bytes"},
	)
	tomlFS, _ := tomlsource.FromFS(
		files,
		"settings.toml",
		tomlsource.Options{Name: "toml-fs"},
	)
	plan, _ := config.NewPlan(jsonBytes, jsonFS, yamlBytes, yamlFS, tomlBytes, tomlFS)
	snapshot, _ := config.LoadTree(context.Background(), plan)
	value := snapshot.Value()
	fmt.Println(
		value["json_bytes"], value["json_fs"],
		value["yaml_bytes"], value["yaml_fs"],
		value["toml_bytes"], value["toml_fs"],
	)
}
Output:
loaded loaded loaded loaded loaded loaded

Index

Examples

Constants

View Source
const (
	PriorityDefaults          = 10
	PriorityDiscoveredBase    = 20
	PriorityDiscoveredProfile = 30
	PriorityExplicitFiles     = 40
	PriorityDotenv            = 50
	PriorityEnvironment       = 60
	PriorityOverrides         = 70
)

Documented default source priorities, ordered from lowest to highest.

View Source
const Redacted = "[REDACTED]"

Redacted is the stable replacement used for secret values.

Variables

View Source
var ErrNotFound = errors.New("configuration source not found")

ErrNotFound is returned by sources that are absent. Only optional sources suppress this error.

View Source
var ErrSourceChanged = errors.New("configuration source changed during read")

ErrSourceChanged indicates that a filesystem source changed while it was being read, so no candidate snapshot was accepted.

Functions

This section is empty.

Types

type ByteSize

type ByteSize int64

ByteSize is a count of bytes decoded from values such as 10MiB or 2GB.

const (
	KiB ByteSize = 1 << 10
	MiB ByteSize = 1 << 20
	GiB ByteSize = 1 << 30
	KB  ByteSize = 1_000
	MB  ByteSize = 1_000_000
	GB  ByteSize = 1_000_000_000
)

func (*ByteSize) UnmarshalText

func (b *ByteSize) UnmarshalText(text []byte) error

UnmarshalText parses an integer followed by an optional supported unit.

type ContextCloser

type ContextCloser interface {
	CloseContext(context.Context) error
}

ContextCloser exposes a cancellable close operation for remote resources. Filesystem sources call it with an independent bounded cleanup context and otherwise call Close.

type ContextFS

type ContextFS interface {
	fs.FS
	OpenContext(context.Context, string) (fs.File, error)
}

ContextFS extends fs.FS with a cancellable open operation. Filesystem source constructors use it when implemented and otherwise call fs.FS.Open.

type ContextFile

type ContextFile interface {
	fs.File
	ReadContext(context.Context, []byte) (int, error)
	StatContext(context.Context) (fs.FileInfo, error)
}

ContextFile extends fs.File with cancellable read and metadata operations. Filesystem sources use these methods when implemented.

type DefaultSources

type DefaultSources struct {
	Defaults          []Source
	DiscoveredBase    []Source
	DiscoveredProfile []Source
	ExplicitFiles     []Source
	Dotenv            []Source
	Environment       []Source
	Overrides         []Source
}

DefaultSources groups sources by the documented default precedence model. Order within each category is preserved.

type Document

type Document struct {
	Tree    map[string]any
	Origins map[string]Origin
}

Document is the intermediate tree produced by a Source.

type GenerationFile

type GenerationFile interface {
	fs.File
	GenerationContext(context.Context) (string, error)
}

GenerationFile exposes an opaque stable generation token. Filesystem sources compare it before and after reads to reject mixed generations.

type Optional

type Optional[T any] struct {
	// contains filtered or unexported fields
}

Optional preserves absence, explicit null, and present zero values.

func (Optional[T]) ConfigTextTarget

func (o Optional[T]) ConfigTextTarget() reflect.Type

ConfigTextTarget identifies T to typed textual sources.

func (Optional[T]) Get

func (o Optional[T]) Get() (T, bool)

Get returns the value when it is present or defaulted.

func (Optional[T]) State

func (o Optional[T]) State() Presence

State reports the value's presence state.

func (*Optional[T]) UnmarshalConfigValue

func (o *Optional[T]) UnmarshalConfigValue(input any) error

UnmarshalConfigValue implements decode.ValueUnmarshaler.

type Origin

type Origin struct {
	Source     string
	Location   string
	Sensitive  bool
	Deprecated bool
	Present    bool
	State      Presence
}

Origin identifies the winning source for a configuration path.

type Plan

type Plan struct {
	// contains filtered or unexported fields
}

Plan is an immutable, inspectable low-to-high precedence source plan.

func NewDefaultPlan

func NewDefaultPlan(sources DefaultSources) (Plan, error)

NewDefaultPlan assigns category priorities and returns an inspectable plan.

func NewPlan

func NewPlan(sources ...Source) (Plan, error)

NewPlan validates sources and orders them from lowest to highest priority. Sources with equal priority retain caller order.

func (Plan) Sources

func (p Plan) Sources() []SourceInfo

Sources returns safe metadata in resolved precedence order.

type Presence

type Presence uint8

Presence distinguishes values that ordinary Go zero values cannot.

const (
	// Absent means no source supplied the field.
	Absent Presence = iota
	// Null means a source explicitly supplied null.
	Null
	// Present means a source supplied a value, including empty or zero.
	Present
	// Defaulted means a default source supplied the value.
	Defaulted
)

type Secret

type Secret struct {
	// contains filtered or unexported fields
}

Secret stores sensitive text with redacted default formatting and marshaling. Reveal is the only supported way to obtain the underlying value.

func NewSecret

func NewSecret(value string) Secret

NewSecret wraps sensitive text.

func (Secret) Format

func (Secret) Format(state fmt.State, _ rune)

Format redacts every fmt formatting verb.

func (Secret) GoString

func (Secret) GoString() string

func (Secret) MarshalJSON

func (Secret) MarshalJSON() ([]byte, error)

MarshalJSON prevents JSON diagnostics from exposing the value.

func (Secret) MarshalText

func (Secret) MarshalText() ([]byte, error)

MarshalText prevents text-based encoders from exposing the value.

func (Secret) Reveal

func (s Secret) Reveal() string

Reveal explicitly returns the sensitive text.

func (Secret) String

func (Secret) String() string

func (*Secret) UnmarshalText

func (s *Secret) UnmarshalText(text []byte) error

UnmarshalText allows strict decoders to populate Secret from string values.

type Snapshot

type Snapshot[T any] struct {
	// contains filtered or unexported fields
}

Snapshot is an immutable configuration tree and its safe provenance.

func Load

func Load[T any](ctx context.Context, plan Plan) (*Snapshot[T], error)

Load resolves and strictly decodes a Plan into an immutable typed snapshot.

func LoadTree

func LoadTree(ctx context.Context, plan Plan) (*Snapshot[map[string]any], error)

LoadTree resolves a Plan atomically. Any source or merge failure returns no snapshot.

func LoadWithValidators

func LoadWithValidators[T any](
	ctx context.Context,
	plan Plan,
	validators ...validation.Validator[T],
) (*Snapshot[T], error)

LoadWithValidators resolves, decodes, and validates a Plan atomically.

func (*Snapshot[T]) Origin

func (s *Snapshot[T]) Origin(path string) (Origin, bool)

Origin returns provenance without exposing the field value.

func (*Snapshot[T]) Value

func (s *Snapshot[T]) Value() T

Value returns an independent copy of the loaded value.

type SnapshotValueError

type SnapshotValueError struct {
	Path string
	Type string
}

SnapshotValueError reports typed state that cannot be copied without retaining caller-visible mutable references. It never formats the value.

func (*SnapshotValueError) Error

func (e *SnapshotValueError) Error() string

type Source

type Source interface {
	Info() SourceInfo
	Load(context.Context) (Document, error)
}

Source loads one configuration document without mutating global state.

type SourceError

type SourceError struct {
	Name  string
	Cause error
}

SourceError identifies a failed source without exposing arbitrary source error text. Cause identity remains available through errors.Is.

func (*SourceError) Error

func (e *SourceError) Error() string

func (*SourceError) Format

func (e *SourceError) Format(state fmt.State, _ rune)

func (*SourceError) MarshalText

func (e *SourceError) MarshalText() ([]byte, error)

MarshalText serializes only the redacted diagnostic message.

func (*SourceError) Unwrap

func (e *SourceError) Unwrap() error

type SourceInfo

type SourceInfo struct {
	Name      string
	Priority  int
	Sensitive bool
	Optional  bool
}

SourceInfo describes a source without exposing its values.

type TreeCycleError

type TreeCycleError struct {
	Path string
}

TreeCycleError reports a cyclic source tree without traversing it.

func (*TreeCycleError) Error

func (e *TreeCycleError) Error() string

type TreeLimitError

type TreeLimitError struct {
	Path  string
	Kind  string
	Limit int
}

TreeLimitError reports a source-tree structural bound without formatting a value.

func (*TreeLimitError) Error

func (e *TreeLimitError) Error() string

type TreeValueError

type TreeValueError struct {
	Path string
	Type string
}

TreeValueError reports a non-canonical value returned by a Source. It never formats the rejected value.

func (*TreeValueError) Error

func (e *TreeValueError) Error() string

Directories

Path Synopsis
adapters
service
Package configservice adapts typed configuration plans to service command loaders without owning long-lived resources.
Package configservice adapts typed configuration plans to service command loaders without owning long-lived resources.
Package configservice is the compatibility import path for the target-oriented service adapter at github.com/faustbrian/go-config/adapters/service.
Package configservice is the compatibility import path for the target-oriented service adapter at github.com/faustbrian/go-config/adapters/service.
Package configtest provides deterministic configuration fixtures and test assertions without mutating process-global state.
Package configtest provides deterministic configuration fixtures and test assertions without mutating process-global state.
Package decode maps format-independent configuration trees into Go values.
Package decode maps format-independent configuration trees into Go values.
Package defaults builds typed lowest-precedence sources from struct tags.
Package defaults builds typed lowest-precedence sources from struct tags.
Package discover provides explicit, bounded configuration file discovery.
Package discover provides explicit, bounded configuration file discovery.
Package dotenv provides strict, bounded, optionally interpolated dotenv configuration sources.
Package dotenv provides strict, bounded, optionally interpolated dotenv configuration sources.
Package environment maps explicit environment snapshots into typed trees.
Package environment maps explicit environment snapshots into typed trees.
examples
discovery command
quickstart command
testing command
Package filesystem dispatches explicit and discovered files to strict format sources while preserving path provenance.
Package filesystem dispatches explicit and discovered files to strict format sources while preserving path provenance.
internal
safeerror
Package safeerror preserves error identity without exposing arbitrary error text through an unwrap chain.
Package safeerror preserves error identity without exposing arbitrary error text through an unwrap chain.
sourceio
Package sourceio provides immutable, bounded byte and fs.FS inputs for format source packages.
Package sourceio provides immutable, bounded byte and fs.FS inputs for format source packages.
Package json provides strict, bounded JSON configuration sources.
Package json provides strict, bounded JSON configuration sources.
Package merge combines configuration trees without mutating its inputs.
Package merge combines configuration trees without mutating its inputs.
Package programmatic provides immutable map-backed configuration sources.
Package programmatic provides immutable map-backed configuration sources.
Package toml provides strict, bounded TOML configuration sources.
Package toml provides strict, bounded TOML configuration sources.
Package validation orchestrates small post-decode configuration validators.
Package validation orchestrates small post-decode configuration validators.
Package yaml provides strict, bounded YAML configuration sources.
Package yaml provides strict, bounded YAML configuration sources.

Jump to

Keyboard shortcuts

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