num30-config
This skill provides comprehensive knowledge of num30/config (github.com/num30/config), a declarative Go configuration library that reads config from YAML/JSON/TOML files, environment variables, and command-line flags in a single call.
Quick Reference
Install:
go get github.com/num30/config
Minimal usage:
import "github.com/num30/config"
type Config struct {
Host string `default:"localhost" validate:"required"`
Port int `default:"8080"`
}
func main() {
var cfg Config
err := config.NewConfReader("myapp").Read(&cfg)
if err != nil {
panic(err)
}
}
Configuration Sources & Priority
Values are merged in this order (highest priority wins):
- Command-line flags (
--host=localhost) - Environment variables (
HOST=localhost) - Config file (
myapp.yaml) - Struct tag defaults (
default:"localhost")
Struct Tags
| Tag | Purpose | Example |
|---|---|---|
default:"val" |
Default value | default:"localhost" |
validate:"rule" |
Validation rule (go-playground/validator) | validate:"required" |
flag:"name" |
Override CLI flag name | flag:"debug" |
envvar:"NAME" |
Override env var name | envvar:"DB_PASS" |
usage:"text" |
Flag usage/help text | usage:"enable debug logging" |
mapstructure:",squash" |
Squash embedded struct fields to parent level | see below |
ConfReader Builder API
config.NewConfReader("myapp") // create reader (config name = file name + env prefix base)
.WithSearchDirs("/etc/conf", "./") // override config file search dirs (default: home + current dir)
.WithPrefix("MYAPP") // prefix for env vars: MYAPP_DB_HOST
.Read(&cfg) // read and populate struct (returns error)
Watch for live config changes:
reader := config.NewConfReader("myapp")
err := reader.Read(&cfg)
mutex := reader.Watch() // call AFTER Read(); panics if called before
// thread-safe access:
mutex.RLock()
val := cfg.SomeField
mutex.RUnlock()
Config File
- File name:
<configName>.yaml(or.json,.toml,.hcl,.ini,.env,.properties) - Search order: home directory, then current directory (override with
WithSearchDirs) - Field name mapping: camelCase → lower camelCase YAML key
# For struct field DB.DbName:
db:
dbName: "mydb"
Environment Variables
- Default pattern:
FIELD_PATHwith dots replaced by_, uppercasedApp.Server.Port→APP_SERVER_PORT
- With prefix:
NewConfReader("x").WithPrefix("MYAPP")→MYAPP_APP_SERVER_PORT - Override with
envvartag:Password string \envvar:"DB_PASS"`→ reads fromDB_PASS`
Command-Line Flags
- Default pattern: lowercase dotted path with
--prefixApp.Server.Port→--app.server.port=8080
- Boolean flags: pass flag alone (no value needed):
--verbose - Override with
flagtag:Debug bool \flag:"debug"`→--debug` - Slices: repeat the flag:
--slice a --slice b - Byte slices: base64-encoded:
--bytes dGVzdA==
Complete Example
package main
import (
"fmt"
"time"
"github.com/num30/config"
)
type Config struct {
GlobalConfig `mapstructure:",squash"` // squash: fields promoted to top level
Debug bool
DB DatabaseConfig
DefaultVal string `default:"default value"`
Tags []string `default:"[\"a\",\"b\"]"`
}
type GlobalConfig struct {
Verbose bool `flag:"verbose" usage:"enable verbose logging"`
}
type DatabaseConfig struct {
Host string `default:"localhost" validate:"required"`
Password string `validate:"required" envvar:"DB_PASS"`
DbName string `default:"mydb"`
Username string `default:"root"`
Port int `default:"5432"`
Timeout time.Duration `default:"30s"`
}
func main() {
var cfg Config
err := config.NewConfReader("myapp").
WithSearchDirs("/etc/myapp", "./").
WithPrefix("MYAPP").
Read(&cfg)
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", cfg)
}
Squash Embedding
Use mapstructure:",squash" on an embedded struct to promote its fields to the parent level in config files and env vars:
type GlobalConfig struct { Verbose bool }
type AppConfig struct {
GlobalConfig `mapstructure:",squash"` // access as `verbose`, not `globalConfig.verbose`
Name string
}
Config file: verbose: true (not globalConfig.verbose: true)
Env var: VERBOSE=true (not GLOBAL_CONFIG_VERBOSE=true)
Supported Go Types
All primitive types are supported as config fields:
bool, int/int8/int16/int32/int64, uint/uint8/uint16/uint32/uint64, float32/float64, string, []string, []byte (base64 in flags/env), time.Duration
Validation
Uses go-playground/validator tags on struct fields:
type Config struct {
Host string `validate:"required"`
Port int `validate:"min=1,max=65535"`
Email string `validate:"required,email"`
}
Read() returns a validation error if constraints are violated. See validator docs for full tag list.
Built-in Config Structs (lib package)
import "github.com/num30/config/lib"
type Config struct {
DB lib.PostgresqlDb // provides Host, Password, DbName, Username, Port, SslEnabled with sane defaults
}
// Get connection string:
connStr := cfg.DB.GetConnString()
// → "host=localhost user=postgres password=pass database= port=5432 sslmode=disable"
lib.PostgresqlDb defaults: Host:"localhost", Password:"pass", Username:"postgres", Port:5432, SslEnabled:false
Slices
type Config struct {
Slice []string
}
| Source | Format |
|---|---|
| Env var | SLICE=a,b,c |
| Config file | slice: ["a", "b", "c"] |
| CLI flags | --slice a --slice b |
Error Handling
Read() returns errors for:
- Nil or non-pointer config struct
- Config file parse failures (
"failed to unmarshal struct") - Default value failures (
"failed to set default values") - Validation failures (
"validation error: Key: '...' Error:...")
Watch() panics if called before Read().
Additional References
- references/api.md — Full API reference
- references/examples.md — Real-world usage examples
More from aaronflorey/agent-skills
amber-lang
Write, debug, and explain Amber code, the `amber` language that compiles `.ab` files to Bash. Use this skill when the user asks to write an Amber script, convert Bash to Amber, compile Amber to Bash, debug Amber syntax or type errors, or asks about Amber 0.5.1-alpha syntax, functions, types, error handling, the standard library, or the `amber` CLI.
26go-cobra
Write, scaffold, and debug Go CLI applications with `github.com/spf13/cobra`. Use this skill whenever the user mentions Cobra, `cobra.Command`, a Go command-line app, subcommands, persistent or local flags, required flags, argument validation, shell completions, generated docs, or wants to build or refactor a cobra-based CLI.
24laravel-actions
Write, scaffold, explain, and refactor code using the `lorisleiva/laravel-actions` package. Use this skill whenever the user mentions Laravel Actions, `AsAction`, `php artisan make:action`, action classes, converting a controller, job, listener, or command into an action, dispatching an action as a job, using an action as a controller or listener, or adding validation, authorization, testing, or mocking around an action.
24pelican-panel-plugins
Write, scaffold, explain, and debug plugins for the Pelican gaming panel. Use this skill whenever the user mentions Pelican plugins, extending Pelican, FilamentPHP resources or pages for Pelican, plugin service providers, custom permissions, plugin settings, routes, models, widgets, or asks how to add new functionality to the Pelican panel.
21go-viper
Write, debug, and explain Go configuration code with `github.com/spf13/viper`. Use this skill whenever the user mentions Viper, `viper`, config structs, reading config from files plus env vars plus flags, Cobra or `pflag` integration, unmarshaling into structs, env key replacers, config precedence, config watching, or a clean Viper bootstrap.
20mise
Configure and use `mise` for dev tool management, environment variables, and task running. Use this skill when the user mentions `mise`, `mise.toml`, `.mise.toml`, `mise use`, `mise install`, `mise run`, `mise x`, project tool versions like Node or Python, task definitions, env vars, hooks, backends, or asks how to configure mise in a project.
17