Documentation
¶
Overview ¶
Package gokart provides thin wrappers around best-in-class Go packages with sensible defaults.
GoKart is an opinionated service toolkit. Every component must justify its existence - we wrap battle-tested packages, not reinvent them.
Components ¶
Root module (github.com/dotcommander/gokart):
- Config: viper wrapper for config files + env vars
- State: JSON state persistence for CLI tools
Submodules:
- gokart/logger: slog wrapper with JSON/text formatting
- gokart/cli: CLI framework wrapping cobra + lipgloss
- gokart/web: HTTP router, client, templ helpers, validator
- gokart/postgres: pgx/v5 connection pool
- gokart/sqlite: modernc.org/sqlite (zero CGO) with WAL mode
- gokart/cache: go-redis/v9 with convenience methods
- gokart/migrate: goose/v3 schema migrations
- gokart/ai: OpenAI client factory functions
Design Principles ¶
- Thin wrappers: No business logic, just factory functions
- Sensible defaults: Zero-config works for development and production
- Best-in-class: Wrap proven packages, don't reinvent
- Fight for inclusion: stdlib-sufficient things stay in stdlib
Quick Start ¶
// Logger
log := logger.New(logger.Config{Level: "info", Format: "json"})
// Config
cfg, err := gokart.LoadConfig[AppConfig]("config.yaml")
// Router (gokart/web)
router := web.NewRouter(web.RouterConfig{Middleware: web.StandardMiddleware})
// PostgreSQL (gokart/postgres)
pool, err := postgres.Open(ctx, "postgres://localhost/mydb")
// Cache (gokart/cache)
c, err := cache.Open(ctx, "localhost:6379")
// Migrations (gokart/migrate)
migrate.Postgres(ctx, db, "migrations")
CLI Subpackage ¶
For CLI applications, use the gokart/cli subpackage which wraps cobra and lipgloss:
import "github.com/dotcommander/gokart/cli"
app := cli.NewApp("myapp", "1.0.0").
WithDescription("My application").
WithStandardFlags()
app.Run()
Not Included ¶
GoKart intentionally excludes things where stdlib is sufficient:
- Error handling: use errors.Is/As and fmt.Errorf("%w", err)
- File operations: use os, io, filepath
- String manipulation: use strings
- Environment variables: viper.AutomaticEnv() handles this
Domain-specific features belong in separate modules so applications only import the dependencies they use.
Index ¶
- func GetBool(config map[string]any, key string, defaultValue bool) bool
- func GetFloat(config map[string]any, key string, defaultValue float32) float32
- func GetInt(config map[string]any, key string, defaultValue int) int
- func GetString(config map[string]any, key, defaultValue string) string
- func LoadConfig[T any](paths ...string) (T, error)
- func LoadConfigWithDefaults[T any](defaults T, paths ...string) (T, error)
- func LoadState[T any](appName, filename string) (T, error)
- func MustParseConfig[T any](config map[string]any) T
- func ParseConfig[T any](config map[string]any) (T, error)
- func SaveState[T any](appName, filename string, data T) error
- func StatePath(appName, filename string) string
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GetBool ¶ added in v0.10.3
GetBool returns the bool value for key or defaultValue when the key is absent or has another type.
func GetInt ¶ added in v0.10.3
GetInt returns the numeric value for key as an int. Values decoded from JSON maps commonly arrive as float64, so those and int64 values are accepted.
func GetString ¶ added in v0.10.3
GetString returns the string value for key or defaultValue when the key is absent or has another type.
func LoadConfig ¶
LoadConfig loads configuration from the first available file path into type T.
Features:
- Supports multiple config paths (first found wins)
- Automatic environment variable binding
- DOT to UNDERSCORE env key mapping (e.g., db.host → DB_HOST)
Supported formats: JSON, YAML, TOML, HCL, envfile, Java properties
Example:
type Config struct {
DB struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
} `mapstructure:"db"`
}
cfg, err := gokart.LoadConfig[Config]("config.yaml", "config.json")
func LoadConfigWithDefaults ¶
LoadConfigWithDefaults loads configuration with default values pre-populated.
The defaults parameter provides fallback values that will be overridden by values from config files or environment variables.
Example:
defaults := Config{
DB: struct{Host string; Port int}{
Host: "localhost",
Port: 5432,
},
}
cfg, err := gokart.LoadConfigWithDefaults(defaults, "config.yaml")
func LoadState ¶
LoadState loads typed state from the platform user config directory.
Returns zero value and os.ErrNotExist if the file doesn't exist. This allows callers to distinguish between missing file and parse errors.
Example:
state, err := gokart.LoadState[AppState]("myapp", "state.json")
if errors.Is(err, os.ErrNotExist) {
// First run, use defaults
state = AppState{WindowSize: 800}
} else if err != nil {
return err
}
func MustParseConfig ¶ added in v0.10.2
MustParseConfig is ParseConfig for initialization paths where invalid configuration is a programmer error.
func ParseConfig ¶ added in v0.10.2
ParseConfig converts a config map to a typed struct. The config tag names fields, default supplies missing scalar values, and required marks fields that must be present after defaults are applied. Anonymous structs are flattened.
func SaveState ¶
SaveState saves typed state under the platform user config directory.
The file is written as indented JSON for human readability. Directory is created with 0755, files with 0600 permissions.
Example:
type AppState struct {
LastOpened string `json:"last_opened"`
WindowSize int `json:"window_size"`
}
err := gokart.SaveState("myapp", "state.json", AppState{
LastOpened: "/path/to/file",
WindowSize: 1024,
})
Types ¶
This section is empty.
