cfggo

package module
v1.0.6 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2024 License: MIT Imports: 15 Imported by: 0

README

cfggo

cfggo is a Go package designed to simplify configuration management in Go applications. It provides a flexible and powerful way to handle configuration through various sources such as files, environment variables, and HTTP endpoints. The package supports default values, dynamic configuration updates, and command-line flags.

Features

  • Type safety for configuration keys
  • Load configuration from JSON files, environment variables, and HTTP endpoints.
  • Support for default values and dynamic configuration updates.
  • Command-line flag integration.
  • Thread-safe configuration access and updates.
  • Customizable configuration handlers.

Installation

To install the package, run:

go get github.com/iqhive/cfggo

Usage

Basic Example

Here's a basic example of how to use cfggo:

package main

import (
    "fmt"
    "github.com/iqhive/cfggo"
)

type MyConfig struct {
	cfggo.Structure
	StringField       func() string                 `json:"string_field" help:"My string config item"`
	IntField          func() int                    `json:"int_pos_field" help:"My int config item"`
	BoolField         func() bool                   `json:"bool_true_field" help:"My bool config item"`
	StringSlice       func() []string               `json:"string_slice" help:"My string slice config item"`
	IntSlice          func() []int                  `json:"int_slice" help:"My int slice config item"`
	BoolSlice         func() []bool                 `json:"bool_slice" help:"My bool slice config item"`
	Float64Slice      func() []float64              `json:"float64_slice" help:"My float64 slice config item"`
	Float32Slice      func() []float32              `json:"float32_slice" help:"My float32 slice config item"`
	StringMap         func() map[string]string      `json:"string_map" help:"My string map config item"`
	InterfaceMap      func() map[string]interface{} `json:"interface_map" help:"My interface map config item"`
	DurationField     func() time.Duration          `json:"duration_field" help:"My duration config item"`
	TimeField         func() time.Time              `json:"time_field" help:"My time config item"`
}

func main() {
    mycfg := &MyConfig{}
    cfggo.Init(mycfg, cfggo.WithFileConfig("myconfig.json"))

    fmt.Println("StringField:", mycfg.StringField())
    fmt.Println("IntField:", mycfg.IntField())
    fmt.Println("BoolField:", mycfg.BoolField())
    fmt.Println("StringSlice:", mycfg.StringSlice())
    fmt.Println("IntSlice:", mycfg.IntSlice())
    fmt.Println("BoolSlice:", mycfg.BoolSlice())
    fmt.Println("Float64Slice:", mycfg.Float64Slice())
    fmt.Println("Float32Slice:", mycfg.Float32Slice())
    fmt.Println("StringMap:", mycfg.StringMap())
    fmt.Println("InterfaceMap:", mycfg.InterfaceMap())
    fmt.Println("DurationField:", mycfg.DurationField())
    fmt.Println("TimeField:", mycfg.TimeField())
}
Supported Options

cfggo supports the following options:

  • WithFileConfig(filename string) Option: Sets the config source/dest to a filename.
  • WithHTTPConfig(httpLoader *http.Request, httpSaver *http.Request) Option: Sets the config source/dest to HTTP requests.
  • WithSkipEnvironment() Option: Skips loading from environment variables.
  • WithName(name string) Option: Sets the name of the configuration.
Command-Line Flag Integration

cfggo supports command-line flag integration using the flag package.

Default Values

cfggo supports default values for configuration keys. Here's an example of how to use it:

package main

import (
	"flag"
	"fmt"
	"os"
	"time"
)

type MyConfig struct {
	StringField       func() string                 `json:"string_field" help:"My string config item"`
	IntField          func() int                    `json:"int_pos_field" help:"My int config item"`
	BoolField         func() bool                   `json:"bool_true_field" help:"My bool config item"`
	StringSlice       func() []string               `json:"string_slice" help:"My string slice config item"`
	IntSlice          func() []int                  `json:"int_slice" help:"My int slice config item"`
	BoolSlice         func() []bool                 `json:"bool_slice" help:"My bool slice config item"`
	Float64Slice      func() []float64              `json:"float64_slice" help:"My float64 slice config item"`
	Float32Slice      func() []float32              `json:"float32_slice" help:"My float32 slice config item"`
	StringMap         func() map[string]string      `json:"string_map" help:"My string map config item"`
	InterfaceMap      func() map[string]interface{} `json:"interface_map" help:"My interface map config item"`
	DurationField     func() time.Duration          `json:"duration_field" help:"My duration config item"`
	TimeField         func() time.Time              `json:"time_field" help:"My time config item"`
}

func main() {
	mycfg := &MyConfig{
        StringField: cfggo.DefaultValue("default_value1"),
        IntField:    cfggo.DefaultValue(123),
        BoolField:  cfggo.DefaultValue(true),
    }
	cfggo.Init(mycfg, cfggo.WithFileConfig("myconfig.json"))

	fmt.Println("StringField:", mycfg.StringField())
	fmt.Println("IntField:", mycfg.IntField())
	fmt.Println("BoolField:", mycfg.BoolField())
	fmt.Println("StringSlice:", mycfg.StringSlice())
	fmt.Println("IntSlice:", mycfg.IntSlice())
	fmt.Println("BoolSlice:", mycfg.BoolSlice())
	fmt.Println("Float64Slice:", mycfg.Float64Slice())
	fmt.Println("Float32Slice:", mycfg.Float32Slice())
	fmt.Println("StringMap:", mycfg.StringMap())
	fmt.Println("InterfaceMap:", mycfg.InterfaceMap())
	fmt.Println("DurationField:", mycfg.DurationField())
	fmt.Println("TimeField:", mycfg.TimeField())
}
Thread-Safety

cfggo is thread-safe, meaning you can access and update the configuration from multiple goroutines concurrently without worrying about data races.

package main

import (
    "fmt"
    "github.com/iqhive/cfggo"
)

type MyConfig struct {
	StringField       func() string                 `json:"string_field" help:"My string config item"`
	IntField          func() int                    `json:"int_pos_field" help:"My int config item"`
}

func main() {
    mycfg := &MyConfig{
        StringField: cfggo.DefaultValue("default_value1"),
        IntField:    cfggo.DefaultValue(123),
    }
    cfggo.Init(mycfg, cfggo.WithFileConfig("myconfig.json"))

    // Start multiple goroutines to access and update the configuration
    for i := 0; i < 10; i++ {
        go func(i int) {
            // Access and update the configuration
            value := mycfg.StringField()
            fmt.Println("Value:", value)

            err := mycfg.Set("string_field", fmt.Sprintf("new_value_%d", i))
            if err != nil {
                fmt.Println(err)
                return
            }
        }(i)
    }

    // Wait for goroutines to finish (for demonstration purposes)
    time.Sleep(2 * time.Second)
}

Contributing

Contributions are welcome! If you find any issues or have suggestions for new features, please open an issue or submit a pull request on the GitHub repository.

License

cfggo is licensed under the MIT License.

Acknowledgments

cfggo is inspired by the viper configuration package. It aims to provide a more lightweight and flexible alternative with additional features like type safety and custom configuration handlers.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrorWrapper errorWrapper = defaultErrorWrapper
	Logger       logger       = slog.New(slog.NewTextHandler(os.Stdout, nil))
)

Functions

func DefaultValue

func DefaultValue[T any](x T) func() T

DefaultValue returns a function that returns the type of the input parameter X

func IgnoreFlags

func IgnoreFlags(flags ...string)

Types

type Option added in v1.0.3

type Option func(*Structure) error

Option is a function that configures a Structure

func WithFileConfig added in v1.0.3

func WithFileConfig(filename string) Option

WithFileConfig sets the config source/dest to a filename

func WithHTTPConfig added in v1.0.3

func WithHTTPConfig(httpLoader *http.Request, httpSaver *http.Request) Option

WithHTTPConfig sets the config source/dest to a filename

func WithName added in v1.0.3

func WithName(name string) Option

WithName sets the name of the configuration

func WithSkipEnvironment added in v1.0.3

func WithSkipEnvironment() Option

WithSkipEnvironment skips loading from environment variables

type Structure added in v1.0.2

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

func (*Structure) CheckUnrecognizedItems added in v1.0.2

func (c *Structure) CheckUnrecognizedItems(s interface{})

func (*Structure) Get added in v1.0.2

func (c *Structure) Get(key string) (interface{}, bool)

Get gets a configuration value and whether it exists from the configData

func (*Structure) GetHelpTag added in v1.0.5

func (c *Structure) GetHelpTag(key string) string

func (*Structure) GetJSONBytes added in v1.0.3

func (c *Structure) GetJSONBytes() []byte

func (*Structure) Init added in v1.0.2

func (c *Structure) Init(parent interface{}, options ...Option)

func (*Structure) NewFlag added in v1.0.3

func (c *Structure) NewFlag(configVarName string, defaultValue interface{}, configDescription string)

NewFlag creates a new configuration item, using the type of the defaultValue

func (*Structure) Set added in v1.0.2

func (c *Structure) Set(key string, value interface{}) error

Set sets a configuration value and then updates the config struct as well

func (*Structure) String added in v1.0.3

func (c *Structure) String() string

Jump to

Keyboard shortcuts

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