confy

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2026 License: MIT Imports: 19 Imported by: 0

README

Confy

A full-scenario Go configuration management library built on viper.

Features

  • Environment-aware multi-file merging — auto-discovers config.yamlconfig.local.yamlconfig.{env}.yamlconfig.{env}.local.yaml
  • Environment variable overridedatabase.hostMYAPP_DATABASE_HOST
  • Multi-format support — YAML, JSON, TOML (mixed in same directory)
  • .env file loading — environment-aware .env discovery: .env.env.local.env.{env}.env.{env}.local
  • Hot-reload — file watching with fsnotify for development
  • Struct binding — unmarshal to Go structs with mapstructure tags
  • Struct defaultsdefault:"value" tag support via creasty/defaults
  • Validation — custom Validator interface + required:"true" tag
  • Config encryption — AES-256-GCM for sensitive values
  • Template inheritancebase: parent.yaml for config inheritance
  • Snapshot/Restore — capture and rollback config state
  • Functional options — clean, extensible API

Install

go get github.com/JsonLee12138/confy@latest

Quick Start

package main

import (
    "fmt"
    "github.com/JsonLee12138/confy"
)

type AppConfig struct {
    Server struct {
        Port int    `mapstructure:"port"`
        Host string `mapstructure:"host"`
    } `mapstructure:"server"`
    Database struct {
        Host     string `mapstructure:"host"`
        Port     int    `mapstructure:"port"`
        Password string `mapstructure:"password"`
    } `mapstructure:"database"`
}

func main() {
    cfg, err := confy.New(
        confy.WithPath("config"),
        confy.WithEnvPrefix("MYAPP"),
    )
    if err != nil {
        panic(err)
    }

    var appCfg AppConfig
    if err := cfg.BindWithDefaults(&appCfg); err != nil {
        panic(err)
    }

    fmt.Printf("Server: %s:%d\n", appCfg.Server.Host, appCfg.Server.Port)
}

Configuration Files

Place config files in the config/ directory:

config/
├── config.yaml              # Base config
├── config.local.yaml        # Local overrides (git-ignored)
├── config.production.yaml   # Production overrides
├── database.yaml            # Module config (loaded with LoadAll)
File Priority (highest last)
  1. config.yaml
  2. config.local.yaml
  3. config.{env}.yaml
  4. config.{env}.local.yaml

Environment is detected via GO_ENV_MODE env var (development/production/test).

Options

Option Description
WithPath(path) Config directory path
WithFile(name) Base config file name
WithFileType(ft) Default format: confy.YAML, confy.JSON, confy.TOML
WithEnvPrefix(prefix) Env var prefix
WithWatch(enable) Enable hot-reload
WithOnChange(fn) Callback on config change
WithLoadAll(enable) Load all files in directory
WithDotEnv(path) Load a .env file
WithDotEnvAuto(dir...) Auto-discover .env files by env mode
WithEncryption(algo, key) Enable value encryption

.env Files

Two ways to load .env files:

Manual — WithDotEnv(path)

Load specific .env files by path:

confy.New(
    confy.WithDotEnv(".env"),
    confy.WithDotEnv(".env.local"),
)
Auto-discovery — WithDotEnvAuto(dir...)

Automatically discovers and loads .env files based on GO_ENV_MODE, following the same priority pattern as config files:

confy.New(confy.WithDotEnvAuto())      // search in current directory
confy.New(confy.WithDotEnvAuto("etc")) // search in "etc/" directory
.env File Priority (highest last)
  1. .env
  2. .env.local
  3. .env.{env}
  4. .env.{env}.local

When GO_ENV_MODE=production, the discovery order is:

.env → .env.local → .env.production → .env.production.local

Environment aliases are supported: dev/development, prod/pro/production, test/testing.

Files that don't exist are silently skipped. System environment variables always take highest priority.

Encrypted Values

Mark encrypted values with enc:AES_GCM: prefix:

database:
  password: "enc:AES_GCM:base64EncodedCiphertext"

Template Inheritance

# base.yaml
server:
  port: 8080
  host: 0.0.0.0

# config.yaml
base: base.yaml
server:
  port: 9090  # overrides parent

Example

A complete Gin + confy demo is available in the example/ directory:

cd example
go run .

The example demonstrates:

  • Multi-file mergingconfig.yaml + config.local.yaml
  • Template inheritanceconfig.yaml extends base.yaml
  • Hot-reload — config changes trigger automatic rebind
  • Struct defaults — Go struct default tags fill in missing values
  • ValidationApp.Validate() enforces port ranges
  • Env var overrides — set MYAPP_SERVER_PORT=9090 to override

Endpoints:

  • GET /health — health check
  • GET /config — view current config (password masked)

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNilConfig       = errors.New("confy: config instance is nil")
	ErrNilTarget       = errors.New("confy: target instance is nil")
	ErrNoConfigFiles   = errors.New("confy: no valid configuration files found")
	ErrNoSnapshot      = errors.New("confy: no snapshot available to restore")
	ErrNilSnapshot     = errors.New("confy: snapshot is nil")
	ErrEmptyExportPath = errors.New("confy: export path is empty")
	ErrMustBeStruct    = errors.New("confy: config must be a struct")
	ErrCycleDetected   = errors.New("confy: circular base inheritance detected")
)

Functions

This section is empty.

Types

type Config

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

Config is the main configuration instance.

func New

func New(opts ...Option) (*Config, error)

New creates a new Config instance with the given options.

func (*Config) Bind

func (c *Config) Bind(instance any) error

Bind unmarshals the config into the target struct. If watching is enabled, the target will be automatically updated on config changes.

func (*Config) BindWithDefaults

func (c *Config) BindWithDefaults(instance any) error

BindWithDefaults applies struct default values before and after binding.

func (*Config) Export

func (c *Config) Export(path string) error

Export writes the current config state to a file.

func (*Config) Get

func (c *Config) Get(key string) any

Get returns the value for the given key.

func (*Config) Restore

func (c *Config) Restore(snapshot map[string]any) error

Restore restores config from a snapshot.

func (*Config) Set

func (c *Config) Set(key string, value any)

Set sets a config value.

func (*Config) Snapshot

func (c *Config) Snapshot() (map[string]any, error)

Snapshot captures the current config state for later restoration.

func (*Config) Validate

func (c *Config) Validate() error

Validate checks if the bound config implements the Validator interface and calls it.

func (*Config) ValidateType

func (c *Config) ValidateType(instance any) error

ValidateType checks struct fields with `required:"true"` are non-zero, and validates type compatibility via mapstructure tags.

type ConfigInterface

type ConfigInterface interface {
	Bind(instance any) error
	BindWithDefaults(instance any) error
	Validate() error
	ValidateType(instance any) error
	Export(path string) error
	Snapshot() (map[string]any, error)
	Restore() error
	Get(key string) any
	Set(key string, value any)
}

ConfigInterface defines the public contract for a Config instance.

type Event

type Event struct {
	Name string
	Op   EventOp
}

Event represents a configuration file change event.

type EventOp

type EventOp uint32
const (
	EventCreate EventOp = 1 << iota
	EventWrite
	EventRemove
	EventRename
	EventChmod
)

type FileType

type FileType string

FileType represents supported configuration file formats.

const (
	YAML FileType = "yaml"
	JSON FileType = "json"
	TOML FileType = "toml"
)

type Option

type Option func(*configOptions)

Option is a function that configures a configOptions instance.

func WithDotEnv

func WithDotEnv(path string) Option

WithDotEnv adds a .env file to load.

func WithDotEnvAuto

func WithDotEnvAuto(dir ...string) Option

WithDotEnvAuto enables automatic .env file discovery based on environment mode. It discovers and loads .env files in priority order: .env → .env.local → .env.{env} → .env.{env}.local The dir parameter specifies the directory to search in (defaults to "." if empty).

func WithEncryption

func WithEncryption(algo string, key []byte) Option

WithEncryption enables config value encryption/decryption.

func WithEnvPrefix

func WithEnvPrefix(prefix string) Option

WithEnvPrefix sets the environment variable prefix.

func WithFile

func WithFile(name string) Option

WithFile sets the base config file name (without extension).

func WithFileType

func WithFileType(ft FileType) Option

WithFileType sets the default config file format.

func WithLoadAll

func WithLoadAll(enable bool) Option

WithLoadAll enables loading all config files in the directory.

func WithOnChange

func WithOnChange(fn func(Event)) Option

WithOnChange sets the callback for config file changes.

func WithPath

func WithPath(path string) Option

WithPath sets the directory to search for config files.

func WithWatch

func WithWatch(enable bool) Option

WithWatch enables or disables file watching for hot-reload.

type Validator

type Validator interface {
	Validate() error
}

Validator is an interface that config structs can implement to perform custom validation.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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