cog

package module
v1.9.5 Latest Latest
Warning

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

Go to latest
Published: Apr 2, 2026 License: MIT Imports: 9 Imported by: 0

README

cog

Config tool for Go applications that require configuration changes on-the-fly.

go get github.com/leodeim/cog

Overview

Currently cog supports JSON, YAML and TOML configuration files with built-in handler/filehandler.go. By default it dynamically detects configuration file type. If you want to specify file type, here you can find how to use built-in file handlers. You can always write your own handler which would implement ConfigHandler interface.

Default config with initial configuration information should be placed in root folder named <name>.default.<type>. Name and type of the file could be changed using custom parameters. cog also let to you set up default values for entries in configuration with default:"some_value" tag. Right now, only bool, int and string is supported.

It is possible to load config fields values from environment variables using env:"ENV_VAR_NAME" tag. With this tag cog will take env. variable value and use it if field value not provided in the config file.

cog uses validator library for validating loaded configuration. For example you can specify required configuration items with validate:"required" tag.

Getting started

Write config structure of your app. Example of config structure with different tags:

type Config struct {
    // simple field, will be empty string if not provided
    Name      string 

    // required: will fail if not provided
    Version   string `validate:"required"` 
    
    // tries to load from env. variable "SERVER_IP_ADDRESS" if not provided in the config file
    Address   string `validate:"required,ip" env:"SERVER_IP_ADDRESS"` 
    
    // sets default value "8080" if field not provided in the config file
    Port      string `default:"8080"` 
}

Import main library:

import "github.com/leodeim/cog"

Initialize and use config:

// creates default cog instance with JSON file handler
c, err := cog.Init[Config]()

// access current configuration attributes
config := c.Config()

// make some changes to 'config' and update current configuration
c.UpdateConfig(newConfig)

For more examples check out examples/ folder.

Change notifications

Callbacks

Register a callback function, which will be called on config change in non blocking way:

id := c.AddCallback(func(cfg ConfigType) {
    // handle config update
})

Callback could be removed by id:

c.RemoveCallback(id)
Subscribers

You can register another type of callback - subscriber. It will be called on config change and will wait for it to complete. It has different signature than callback: it can return an error and in case subscriber callback returns an error - whole config update is being rolled back. Example:

id := c.AddSubscriber(func(cfg ConfigType) error {
    if err := tryConfigUpdate(cfg); err != nil {
        return err
    }
    return nil
})

Subscriber could be removed dynamically:

c.RemoveSubscriber(id)

File handler

By default cog initializes with dynamic file handler. You can specify type (JSON, YAML or TOML) by creating handler instance and providing it during initialization.

Import built-in filehandler

import (
	"github.com/leodeim/cog"
	fh "github.com/leodeim/cog/filehandler"
)
h, _ := fh.New(fh.WithType(fh.YAML))
c, _ := cog.Init[ConfigType](h)
Custom parameters

Handlers also support optional parameters with high order functions. You can specify custom path, name and file handler.

h, _ := fh.New(
    fh.WithPath("./dir"), 
    fh.WithName("name"), 
    fh.WithType(fh.JSON),
)
c, _ := cog.Init[ConfigType](h)

String representation

Use String() to get a JSON representation of the current config. You can pass optional mask functions to redact sensitive fields before serialization:

str, err := c.String()
// {"Name": "my-app", "Secret": "s3cret"}

str, err := c.String(func(cfg *Config) {
    cfg.Secret = "[REDACTED]"
})
// {"Name": "my-app", "Secret": "[REDACTED]"}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SetDefaults

func SetDefaults[T any](data *T)

SetDefaults fills zero-value fields in data using struct tags ("default" for literal values, "env" for environment variables).

Types

type C

type C[T any] struct {
	// contains filtered or unexported fields
}

func Init

func Init[T any](handler ...ConfigHandler) (*C[T], error)

Init initializes the library and returns a cog instance. An optional ConfigHandler can be provided; if omitted, a default built-in file handler is used (JSON with dynamic type detection).

func (*C[T]) AddCallback

func (c *C[T]) AddCallback(f Callback[T]) int

AddCallback registers a function that is called asynchronously (in a goroutine) after every successful config update. Returns an ID that can be used with RemoveCallback.

func (*C[T]) AddSubscriber

func (c *C[T]) AddSubscriber(f Subscriber[T]) int

AddSubscriber registers a function that is called synchronously on config update. If any subscriber returns an error, the update is rolled back. Returns an ID that can be used with RemoveSubscriber.

func (*C[T]) Config

func (c *C[T]) Config() T

Config returns a copy of the current configuration.

func (*C[T]) GetTimestamp

func (c *C[T]) GetTimestamp() time.Time

GetTimestamp returns the time of the last configuration load or update.

func (*C[T]) RemoveCallback

func (c *C[T]) RemoveCallback(id int) error

RemoveCallback removes a previously registered callback by ID.

func (*C[T]) RemoveSubscriber

func (c *C[T]) RemoveSubscriber(id int) error

RemoveSubscriber removes a previously registered subscriber by ID.

func (*C[T]) String

func (c *C[T]) String(masks ...MaskFn[T]) (string, error)

String returns a JSON representation of the current configuration. Optional MaskFn functions can be provided to redact sensitive fields before serialization.

func (*C[T]) Update

func (c *C[T]) Update(new T) error

Update replaces the current configuration. The new config is validated, subscribers are notified (with rollback on error), and the result is persisted. Callbacks fire asynchronously after the state is committed.

type Callback

type Callback[T any] func(T)

type ConfigHandler

type ConfigHandler interface {
	Load(any) error
	Save(any) error
}

type MaskFn

type MaskFn[T any] func(*T)

type Subscriber

type Subscriber[T any] func(T) error

Directories

Path Synopsis
examples
defaults command
rollback command
subscriber command
update command
validation command

Jump to

Keyboard shortcuts

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