config

package
v2.0.0-beta.13 Latest Latest
Warning

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

Go to latest
Published: Jan 13, 2026 License: MIT Imports: 33 Imported by: 0

README

Configuration Module

The configuration module provides a flexible system for managing application configuration with support for YAML files, environment variable substitution, and configuration merging.

Features

  • YAML-based Configuration: Declarative configuration using YAML files
  • Environment Variable Substitution: Automatic replacement of placeholders with environment values using ${ENV:"default_value"} syntax
  • Expression Engine: Dynamic configuration values using expressions similar to GitHub Actions workflow syntax ($env.ENV)
  • Configuration Merging: Support for base and override configurations
  • Hot Reloading: Dynamic configuration updates without application restart

Installation

go get github.com/pubgo/funk/v2/config

Quick Start

Basic Configuration
import "github.com/pubgo/funk/v2/config"

type ServerConfig struct {
    Host string `yaml:"host"`
    Port int    `yaml:"port"`
}

type AppConfig struct {
    Server ServerConfig `yaml:"server"`
    Debug  bool         `yaml:"debug"`
}

// Load configuration
cfg := config.Load[AppConfig]()

// Access configuration values
fmt.Printf("Server: %s:%d\n", cfg.T.Server.Host, cfg.T.Server.Port)
fmt.Printf("Debug mode: %t\n", cfg.T.Debug)
Environment Variable Substitution

Configuration files support environment variable substitution using the ${ENV:"default_value"} syntax:

# config.yaml
server:
  host: ${SERVER_HOST:"localhost"}
  port: ${SERVER_PORT:8080}
database:
  url: postgres://${DB_USER}:${DB_PASS}@${DB_HOST}/${DB_NAME}
Expression Engine

Advanced configuration values can be computed using expressions similar to GitHub Actions workflow syntax:

# config.yaml
app:
  version: ${{env.VERSION}}
  build_time: ${{env.BUILD_TIME}}
  config_dir: ${{config_dir()}}
  cert_data: ${{embed("cert.pem")}}

Available expression functions:

  • env.ENV_VAR: Access environment variables (similar to GitHub Actions syntax)
  • config_dir(): Get the configuration directory
  • embed(filename): Embed file content as base64
Configuration Structure
type Resources struct {
    Resources       []string `yaml:"resources"`
    PatchResources  []string `yaml:"patch_resources"`
    PatchEnvs       []string `yaml:"patch_envs"`
}

Core Concepts

Configuration Loading

The module provides a generic Load[T]() function that loads and parses configuration files:

cfg := config.Load[AppConfig]()

This function:

  1. Finds the configuration file in predefined locations
  2. Loads and parses the YAML content
  3. Processes environment variable substitutions using both ${ENV} and ${env.ENV} syntax
  4. Merges with additional configuration files if specified
  5. Returns a typed configuration structure
Environment Variable Integration

Environment variables can be used in configuration files with optional default values:

# Syntax: ${VAR_NAME:"default_value"}
setting1: ${SETTING_1:"default_value"}
setting2: ${REQUIRED_SETTING}  # No default, will error if not set

Expression syntax (GitHub Actions style):

# Syntax: ${env.VAR_NAME}
setting1: ${env.SETTING_1}
setting2: ${env.REQUIRED_SETTING}
Configuration Merging

The module supports merging multiple configuration files:

# config.yaml
resources:
  - configs/database.yaml
  - configs/cache.yaml
patch_resources:
  - configs/local-overrides.yaml
Expression Evaluation

Advanced configuration values can be computed using expressions:

# config.yaml
app:
  version: ${env.VERSION}
  build_time: ${env.BUILD_TIME}
  config_dir: ${config_dir()}
  cert_data: ${embed("cert.pem")}

Advanced Usage

Custom Configuration Paths
// Set custom configuration path
config.SetConfigPath("/path/to/custom/config.yaml")

// Load configuration
cfg := config.Load[AppConfig]()
Manual Configuration Loading
var appConfig AppConfig
envCfgMap := config.LoadFromPath(&appConfig, "path/to/config.yaml")
Configuration Validation
type ValidatedConfig struct {
    Port int `yaml:"port" validate:"min=1,max=65535"`
}

cfg := config.Load[ValidatedConfig]()
// Add custom validation logic here

API Reference

Core Functions
Function Description
Load[T]() Load and parse configuration generically
LoadFromPath[T](val *T, cfgPath string) Load configuration from specific path
SetConfigPath(path string) Set custom configuration file path
GetConfigPath() Get current configuration file path
Configuration Structures
Structure Description
Cfg[T] Wrapper containing loaded configuration and metadata
Resources Configuration for resource loading and merging
Node YAML node wrapper for flexible access
Environment Integration
Function Description
LoadEnvMap(cfgPath string) Load environment configuration map
RegisterExpr(name string, expr any) Register custom expression functions

Best Practices

  1. Use Struct Tags: Clearly define YAML mappings with struct tags
  2. Provide Defaults: Specify sensible default values for configuration options
  3. Validate Early: Implement configuration validation to catch errors early
  4. Environment Overrides: Use environment variables for deployment-specific settings
  5. Modular Configs: Split large configurations into logical modules
  6. Documentation: Document configuration options and their purposes

Integration Patterns

With Feature Flags
import (
    "github.com/pubgo/funk/v2/config"
    "github.com/pubgo/funk/v2/features"
)

type AppConfig struct {
    Debug bool `yaml:"debug"`
}

cfg := config.Load[AppConfig]()
debugMode := features.Bool("debug", cfg.T.Debug, "Enable debug mode")
With Logging
import (
    "github.com/pubgo/funk/v2/config"
    "github.com/pubgo/funk/v2/log"
)

type LogConfig struct {
    Level string `yaml:"level"`
}

cfg := config.Load[LogConfig]()
logger := log.GetLogger("app")
logger.Info().Str("config_level", cfg.T.Level).Msg("Configuration loaded")

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetConfigData

func GetConfigData(cfgPath string, workDir string, envSpecMap ...EnvSpecMap) (_ []byte, gErr error)

GetConfigData loads and processes config file content with optional envSpecMap validation. If envSpecMap is provided, env() calls in the config will be validated against defined vars. workDir is the root config directory used for embed() path resolution.

func GetConfigDir

func GetConfigDir() string

func GetConfigPath

func GetConfigPath() string

func Merge

func Merge[A any, B any | *any](dst *A, src ...B) error

func MergeR

func MergeR[A any, B any | *any](dst *A, src ...B) (r result.Result[*A])

func RegisterExpr

func RegisterExpr(name string, fn any) error

RegisterExpr registers a custom expression function for use in config templates. Returns error if the name already exists. For backward compatibility, use MustRegisterExpr for panic behavior. Note: Custom functions must have simple signatures: func() T or func(T) R

func SetConfigPath

func SetConfigPath(confPath string)

Types

type Base64File

type Base64File string

func (*Base64File) MarshalYAML

func (b *Base64File) MarshalYAML() (any, error)

func (*Base64File) UnmarshalYAML

func (b *Base64File) UnmarshalYAML(value *yaml.Node) error

type Cfg

type Cfg[T any] struct {
	T      T
	P      *T
	EnvCfg *EnvSpecMap
}

func Load

func Load[T any]() Cfg[T]

Load loads configuration (panics on error). For better error handling, use TryLoad instead.

func LoadFromPath

func LoadFromPath[T any](cfgPath string) (*Cfg[T], error)

func TryLoad

func TryLoad[T any]() (*Cfg[T], error)

TryLoad attempts to load configuration and returns error instead of panicking. This is the recommended way to load config for better error handling.

type EnvSpec

type EnvSpec struct {
	// Name of the environment variable.
	Name string `yaml:"name"`

	Desc    string `yaml:"desc"`
	Default string `yaml:"default"`
	Value   string `yaml:"value"`
	Example string `yaml:"example"`

	// Validation using go-playground/validator tags
	// Examples: "required", "email", "url", "uuid", "ip", "numeric", "min=3,max=50"
	Rule string `yaml:"validate"`
}

func (EnvSpec) GetValue

func (e EnvSpec) GetValue() string

func (EnvSpec) Validate

func (e EnvSpec) Validate() error

Validate performs validation on the env spec using go-playground/validator

type EnvSpecMap

type EnvSpecMap map[string]*EnvSpec

func LoadEnvMap

func LoadEnvMap(cfgPath string) EnvSpecMap

func (EnvSpecMap) ValidateAll

func (m EnvSpecMap) ValidateAll() error

ValidateAll validates all environment specs in the map

type ExprExistsError

type ExprExistsError struct {
	Name string
}

ExprExistsError is returned when trying to register a duplicate expression

func (*ExprExistsError) Error

func (e *ExprExistsError) Error() string

type ListOrMap

type ListOrMap[T any] []T

func (*ListOrMap[T]) MarshalYAML

func (ts *ListOrMap[T]) MarshalYAML() (any, error)

MarshalYAML implements the yaml.Marshaler interface.

func (*ListOrMap[T]) UnmarshalYAML

func (ts *ListOrMap[T]) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML implements the yaml.Unmarshaler interface.

type Manager

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

Manager provides thread-safe configuration management

func Global

func Global() *Manager

Global returns the global config manager instance

func NewManager

func NewManager() *Manager

NewManager creates a new Manager instance

func (*Manager) GetDir

func (m *Manager) GetDir() string

GetDir returns the config directory in a thread-safe manner

func (*Manager) GetExprFuncs

func (m *Manager) GetExprFuncs() map[string]any

GetExprFuncs returns a copy of registered expression functions

func (*Manager) GetPath

func (m *Manager) GetPath() string

GetPath returns the config path in a thread-safe manner

func (*Manager) RegisterExprFunc

func (m *Manager) RegisterExprFunc(name string, fn any) error

RegisterExprFunc registers a custom expression function in a thread-safe manner

func (*Manager) SetDir

func (m *Manager) SetDir(dir string)

SetDir sets the config directory in a thread-safe manner

func (*Manager) SetPath

func (m *Manager) SetPath(path string)

SetPath sets the config path in a thread-safe manner

type NamedConfig

type NamedConfig interface {
	// ConfigUniqueName unique name
	ConfigUniqueName() string
}

type Node

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

func (*Node) Decode

func (c *Node) Decode(val any) error

func (*Node) Get

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

func (*Node) IsNil

func (c *Node) IsNil() bool

func (*Node) MarshalJSON

func (c *Node) MarshalJSON() ([]byte, error)

func (*Node) MarshalYAML

func (c *Node) MarshalYAML() (any, error)

func (*Node) UnmarshalYAML

func (c *Node) UnmarshalYAML(value *yaml.Node) error

func (*Node) YamlNode

func (c *Node) YamlNode() *yaml.Node

type Resources

type Resources struct {
	// Resources resource config file or dir must exist
	Resources []string `yaml:"resources"`

	// PatchResources resource config file or dir not required to exist
	PatchResources []string `yaml:"patch_resources"`

	// PatchEnvs env config file or dir not required to exist
	PatchEnvs []string `yaml:"patch_envs"`
}

Jump to

Keyboard shortcuts

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