confkit

package module
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Jul 10, 2026 License: MIT Imports: 15 Imported by: 0

README

confkit

CI Go Reference

Typed configuration loading and validation for Go services.

confkit defines the environment variables a service expects, validates them at startup, assigns typed values into a struct, and can generate .env.example or Markdown documentation from the same contract.

It is intentionally env-first. It does not try to be a full configuration system for every backend or file format.

Install

go get github.com/ahmertsengol/confkit

Usage

package main

import (
	"log"

	conf "github.com/ahmertsengol/confkit"
)

type Config struct {
	Port        int
	DatabaseURL string
	JWTSecret   string
	Env         string
}

func main() {
	cfg, err := conf.Load[Config](conf.Contract(
		conf.Int("PORT").
			Default(8080).
			Min(1).
			Max(65535).
			Description("HTTP server port"),

		conf.String("DATABASE_URL").
			Required().
			URL().
			Description("Primary database connection URL"),

		conf.String("JWT_SECRET").
			Required().
			Min(32).
			Secret().
			Description("JWT signing secret"),

		conf.Enum("ENV", "development", "staging", "production").
			Default("development"),
	).Strict(), conf.WithDotEnv(".env"))
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("starting %s service on port %d", cfg.Env, cfg.Port)
}

Example error:

Invalid configuration:

DATABASE_URL
  Required environment variable is missing.

PORT
  Expected integer, got "abc".

JWT_SECRET
  Must be at least 32 characters. Current value: [REDACTED].

Loading rules

Load reads values in this order:

defaults < dotenv files < process environment < explicit sources
  • WithDotEnv(".env") ignores a missing file.
  • WithRequiredDotEnv(path) returns an error if the file cannot be read.
  • WithSource(MapSource(...)) is useful for tests and explicit overrides.
  • Secret fields are redacted in errors and generated examples.
  • Contract errors, parse errors, and validation errors are returned together as *confkit.Error.
  • Contract(...).Strict() rejects exported struct fields that are not present in the contract.
  • Generated examples validate defaults and quote values when needed so the output can be read back by confkit.
  • List defaults used for generated examples must not contain the list separator.
  • Custom validators should be pure predicates; they may run during loading and documentation generation.

Dotenv support is intentionally minimal and meant for local development. It supports common KEY=value, export KEY=value, quoted values, and inline comments. For advanced dotenv behavior, load values with another package and pass them through WithSource.

For small programs that only need typed env parsing:

type Config struct {
	Port        int    `conf:"PORT"`
	ServiceName string // SERVICE_NAME
	Debug       bool   `conf:"DEBUG"`
}

cfg, err := conf.LoadEnv[Config]()

LoadEnv does not apply contract validation, required fields, defaults, or secret redaction. Fields without a conf tag use screaming snake case; tags are only needed when the environment key should differ from the field name.

Generated files

The contract can be used to generate .env.example:

_ = conf.WriteExample(contract, os.Stdout)
# HTTP server port
PORT=8080

# Primary database connection URL
DATABASE_URL=

# JWT signing secret
JWT_SECRET=

It can also generate Markdown documentation:

_ = conf.WriteMarkdown(contract, os.Stdout)
| Key | Type | Required | Default | Secret | Description |
|---|---|---|---|---|---|
| PORT | int | no | 8080 | no | HTTP server port |

Supported API

Category API
Field types String, Int, Float, Bool, Duration, Enum, List
Contract options Strict
Modifiers Required, Optional, Default, Secret, Description, Desc
Validators Min, Max, Regex, URL, Email, Hostname, IP, NonEmpty, Validate for typed custom rules, enum membership through Enum

Notes

  • Duplicate contract keys are rejected.
  • Duplicate struct field mappings are rejected.
  • Invalid regex validators return contract errors instead of panicking.
  • Strict mode can reject struct fields missing from the contract.
  • conf:"-" skips a struct field.
  • Remote providers, hot reload, Vault, Consul, and Kubernetes integrations are outside the current package scope.

Documentation

Overview

Package confkit validates, types, redacts, and documents Go service configuration at startup.

Define a configuration contract once, then use it to load typed structs, format actionable errors, and generate .env.example or Markdown docs.

Index

Examples

Constants

View Source
const (
	CodeRequired         = "required"
	CodeInvalidType      = "invalid_type"
	CodeMin              = "min"
	CodeMax              = "max"
	CodeRegex            = "regex"
	CodeInvalidURL       = "invalid_url"
	CodeInvalidEnum      = "invalid_enum"
	CodeInvalidEmail     = "invalid_email"
	CodeInvalidHost      = "invalid_hostname"
	CodeInvalidIP        = "invalid_ip"
	CodeNonEmpty         = "non_empty"
	CodeInvalidRegex     = "invalid_regex"
	CodeInvalidContract  = "invalid_contract"
	CodeCustomValidation = "custom_validation"
	CodeDuplicateKey     = "duplicate_key"
	CodeUnconfigured     = "unconfigured_field"
	CodeUnknown          = "unknown_field"
)

Variables

This section is empty.

Functions

func Load

func Load[T any](contract *ConfigContract, opts ...Option) (T, error)

Load reads configuration values from sources, validates them with the contract, and assigns the typed result into T.

Example
package main

import (
	"fmt"

	conf "github.com/ahmertsengol/confkit"
)

func main() {
	type Config struct {
		Port        int
		DatabaseURL string
		Env         string
	}

	cfg, err := conf.Load[Config](
		conf.Contract(
			conf.Int("PORT").Default(8080).Min(1).Max(65535),
			conf.String("DATABASE_URL").Required().URL(),
			conf.Enum("ENV", "development", "staging", "production").Default("development"),
		).Strict(),
		conf.WithSource(conf.MapSource(map[string]string{
			"DATABASE_URL": "https://db.example.com/app",
		})),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Printf("%d %s %s\n", cfg.Port, cfg.DatabaseURL, cfg.Env)
}
Output:
8080 https://db.example.com/app development

func LoadEnv

func LoadEnv[T any]() (T, error)

LoadEnv loads a struct directly from the process environment using conf tags and field types. Missing values leave the field's zero value unchanged.

func WriteExample

func WriteExample(contract *ConfigContract, writer io.Writer) error

WriteExample writes a deterministic .env.example from contract metadata.

Example
package main

import (
	"os"

	conf "github.com/ahmertsengol/confkit"
)

func main() {
	contract := conf.Contract(
		conf.Int("PORT").Default(8080).Desc("HTTP server port"),
		conf.String("DATABASE_URL").Required().URL().Desc("Primary database connection URL"),
	)

	_ = conf.WriteExample(contract, os.Stdout)
}
Output:
# HTTP server port
PORT=8080

# Primary database connection URL
DATABASE_URL=

func WriteMarkdown

func WriteMarkdown(contract *ConfigContract, writer io.Writer) error

WriteMarkdown writes a Markdown table documenting the contract.

Types

type BoolField

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

BoolField validates boolean configuration values.

func Bool

func Bool(key string) *BoolField

Bool creates a boolean field.

func (*BoolField) Default

func (f *BoolField) Default(value bool) *BoolField

func (*BoolField) Desc

func (f *BoolField) Desc(description string) *BoolField

func (*BoolField) Description

func (f *BoolField) Description(description string) *BoolField

func (*BoolField) Optional

func (f *BoolField) Optional() *BoolField

func (*BoolField) Required

func (f *BoolField) Required() *BoolField

func (*BoolField) Secret

func (f *BoolField) Secret() *BoolField

func (*BoolField) Validate added in v0.1.1

func (f *BoolField) Validate(code, message string, fn func(bool) bool) *BoolField

type ConfigContract

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

ConfigContract describes the configuration keys, parsers, validation rules, and documentation metadata used by Load.

func Contract

func Contract(fields ...Field) *ConfigContract

Contract creates a configuration contract from field builders.

func (*ConfigContract) Strict added in v0.1.1

func (c *ConfigContract) Strict() *ConfigContract

Strict rejects exported struct fields that are not represented in the contract. It is useful for service configuration where zero-value drift should be treated as a startup error.

type DurationField

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

DurationField validates time.Duration configuration values.

func Duration

func Duration(key string) *DurationField

Duration creates a time.Duration field parsed with time.ParseDuration.

func (*DurationField) Default

func (f *DurationField) Default(value time.Duration) *DurationField

func (*DurationField) Desc

func (f *DurationField) Desc(description string) *DurationField

func (*DurationField) Description

func (f *DurationField) Description(description string) *DurationField

func (*DurationField) Max

func (*DurationField) Min

func (*DurationField) Optional

func (f *DurationField) Optional() *DurationField

func (*DurationField) Required

func (f *DurationField) Required() *DurationField

func (*DurationField) Secret

func (f *DurationField) Secret() *DurationField

func (*DurationField) Validate added in v0.1.1

func (f *DurationField) Validate(code, message string, fn func(time.Duration) bool) *DurationField

type EnumField

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

EnumField validates a string against a fixed set of values.

func Enum

func Enum(key string, values ...string) *EnumField

Enum creates an enum field.

func (*EnumField) Default

func (f *EnumField) Default(value string) *EnumField

func (*EnumField) Desc

func (f *EnumField) Desc(description string) *EnumField

func (*EnumField) Description

func (f *EnumField) Description(description string) *EnumField

func (*EnumField) Optional

func (f *EnumField) Optional() *EnumField

func (*EnumField) Required

func (f *EnumField) Required() *EnumField

func (*EnumField) Secret

func (f *EnumField) Secret() *EnumField

func (*EnumField) Validate added in v0.1.1

func (f *EnumField) Validate(code, message string, fn func(string) bool) *EnumField

type Error

type Error struct {
	Issues []Issue
}

Error aggregates all configuration issues found in a load attempt.

func (*Error) Error

func (e *Error) Error() string

type Field

type Field interface {
	// contains filtered or unexported methods
}

Field is implemented by all configuration field builders.

type FloatField

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

FloatField validates float64 configuration values.

func Float

func Float(key string) *FloatField

Float creates a float64 field.

func (*FloatField) Default

func (f *FloatField) Default(value float64) *FloatField

func (*FloatField) Desc

func (f *FloatField) Desc(description string) *FloatField

func (*FloatField) Description

func (f *FloatField) Description(description string) *FloatField

func (*FloatField) Max

func (f *FloatField) Max(max float64) *FloatField

func (*FloatField) Min

func (f *FloatField) Min(min float64) *FloatField

func (*FloatField) Optional

func (f *FloatField) Optional() *FloatField

func (*FloatField) Required

func (f *FloatField) Required() *FloatField

func (*FloatField) Secret

func (f *FloatField) Secret() *FloatField

func (*FloatField) Validate added in v0.1.1

func (f *FloatField) Validate(code, message string, fn func(float64) bool) *FloatField

type IntField

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

IntField validates integer configuration values.

func Int

func Int(key string) *IntField

Int creates an integer field.

func (*IntField) Default

func (f *IntField) Default(value int) *IntField

func (*IntField) Desc

func (f *IntField) Desc(description string) *IntField

func (*IntField) Description

func (f *IntField) Description(description string) *IntField

func (*IntField) Max

func (f *IntField) Max(max int) *IntField

func (*IntField) Min

func (f *IntField) Min(min int) *IntField

func (*IntField) Optional

func (f *IntField) Optional() *IntField

func (*IntField) Required

func (f *IntField) Required() *IntField

func (*IntField) Secret

func (f *IntField) Secret() *IntField

func (*IntField) Validate added in v0.1.1

func (f *IntField) Validate(code, message string, fn func(int) bool) *IntField

type Issue

type Issue struct {
	Key     string
	Code    string
	Message string
	Secret  bool
}

Issue describes one configuration problem.

type ListField

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

ListField validates comma-separated string lists.

func List

func List(key string) *ListField

List creates a comma-separated string list field.

func (*ListField) Default

func (f *ListField) Default(value []string) *ListField

func (*ListField) Desc

func (f *ListField) Desc(description string) *ListField

func (*ListField) Description

func (f *ListField) Description(description string) *ListField

func (*ListField) Max

func (f *ListField) Max(max int) *ListField

func (*ListField) Min

func (f *ListField) Min(min int) *ListField

func (*ListField) Optional

func (f *ListField) Optional() *ListField

func (*ListField) Required

func (f *ListField) Required() *ListField

func (*ListField) Secret

func (f *ListField) Secret() *ListField

func (*ListField) Separator

func (f *ListField) Separator(separator string) *ListField

func (*ListField) Validate added in v0.1.1

func (f *ListField) Validate(code, message string, fn func([]string) bool) *ListField

type Option

type Option func(*options)

Option customizes Load.

func WithDotEnv

func WithDotEnv(path string) Option

WithDotEnv loads values from a dotenv file when it exists. Missing files are ignored so local .env files can be used in development without breaking production deployments.

func WithRequiredDotEnv

func WithRequiredDotEnv(path string) Option

WithRequiredDotEnv loads values from a dotenv file and returns an error when the file cannot be read.

func WithSource

func WithSource(source Source) Option

WithSource adds an explicit source. Explicit sources have higher precedence than .env files and the process environment.

type Source

type Source interface {
	Lookup(key string) (string, bool)
}

Source provides raw string values by configuration key.

func MapSource

func MapSource(values map[string]string) Source

MapSource creates an in-memory source for tests and explicit overrides.

type StringField

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

StringField validates string configuration values.

func String

func String(key string) *StringField

String creates a string field.

func (*StringField) Default

func (f *StringField) Default(value string) *StringField

func (*StringField) Desc

func (f *StringField) Desc(description string) *StringField

func (*StringField) Description

func (f *StringField) Description(description string) *StringField

func (*StringField) Email

func (f *StringField) Email() *StringField

func (*StringField) Hostname

func (f *StringField) Hostname() *StringField

func (*StringField) IP

func (f *StringField) IP() *StringField

func (*StringField) Max

func (f *StringField) Max(max int) *StringField

func (*StringField) Min

func (f *StringField) Min(min int) *StringField

func (*StringField) NonEmpty

func (f *StringField) NonEmpty() *StringField

func (*StringField) Optional

func (f *StringField) Optional() *StringField

func (*StringField) Regex

func (f *StringField) Regex(pattern string) *StringField

func (*StringField) Required

func (f *StringField) Required() *StringField

func (*StringField) Secret

func (f *StringField) Secret() *StringField

func (*StringField) URL

func (f *StringField) URL() *StringField

func (*StringField) Validate added in v0.1.1

func (f *StringField) Validate(code, message string, fn func(string) bool) *StringField

Directories

Path Synopsis
examples
basic command
http-server command

Jump to

Keyboard shortcuts

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