confetti

package module
v2.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 7, 2021 License: MIT Imports: 8 Imported by: 0

README

Confetti

A simple config manager for Go applications.

Install

Use the following:

go get -u github.com/shivanshkc/confetti/v2

When to use Confetti

Confetti only has a few, but well implemented set of features. It makes it really easy to use and understand.
If your application fits the following use-case, Confetti is the best config manager you can get.

  1. The configs have to be loaded/unmarshalled into a struct.
  2. The configs are loaded once at application startup and do not change for the entire runtime of the application.
  3. The configs are loaded either from the environment or command-line flags (No JSON/YAML files or remote servers).

Beauty of Confetti

If your application agrees with the above restrictions, you can enjoy the following features of Confetti:

  1. Concise syntax using struct tags
    package main
    
    type Configs struct {
        Port string `def:"8080" env:"PORT" arg:"port"`
    }
    

    This is all you need to make a struct usable with Confetti. Use the following code to load the configs:

    import (
        "fmt"
    
        "github.com/shivanshkc/confetti/v2"
    )   
    
    func main() {
        loader := confetti.NewDefLoader()
    
        configs := &Configs{}
        if err := loader.Load(configs); err != nil {
            panic(err)
        }
    
        fmt.Println("Configs:", configs)
    }
    

    Here, as you may have guessed:
    a. The Port config has the default value of 8080.
    b. If the environment variable PORT is provided, it will override the default value.
    c. If the -port or --port flag is provided, it will override both the default value and the environment variable.

  2. Generates documentation for your application

    If you use the code in the last point, and execute go run main.go -h, you will see the following on your console:

    Usage of configs:
    -port value
            Doc: not provided
            Default: 8080
            Environment: PORT
    panic: failed to parse flags: flag: help requested
    

    Confetti auto-generates this help documentation for your application using Go's flag package.
    In the output above, notice the Doc: not provided line. This is because we did not provide any doc on the Port config. It can be provided as follows:

    type Configs struct {
        Port string `def:"8080" env:"PORT" arg:"port,HTTP server port"`
    }
    

    Now, the output will read:

    Usage of configs:
    -port value
        Doc: HTTP server port
        Default: 8080
        Environment: PORT
    panic: failed to parse flags: flag: help requested
    

    Next, you must be getting annoyed by the panic message at the bottom. This is because Go's flag package returns an error when a -h or -help flag is provided. To get rid of this, use the following:

    import (
        "errors"
        "fmt"
    
        "github.com/shivanshkc/confetti/v2"   
    )
    
    func main() {
        loader := confetti.NewDefLoader()
    
        configs := &Configs{}
        if err := loader.Load(configs); err != nil {
            if errors.Is(err, flag.ErrHelp) {
    	        return
            }
            panic(err)
        }
    
        fmt.Println("Configs:", configs)
    }
    
  3. Nested structs

    Confetti is built to handle nested structs. Just make sure that the flag names for all fields are always different, otherwise you'll get a panic.

    type Configs struct {
        HTTP struct {
            Port string `def:"8080" env:"HTTP_PORT" arg:"http-port"`
        }
    
        GRPC struct {
            Port string `def:"7070" env:"GRPC_PORT" arg:"grpc-port"`
        }
    }
    

    The above struct is a completely valid Confetti target.

  4. Automatic type assertions

    Confetti is built to handle all types of configs, and not just strings. Consider the following example:

    type Configs struct {
        CORS struct {
            TrustedOrigins []string `def:"[\"google.com\"]" env:"TRUSTED_ORIGINS" arg:"trusted-origins"`
        }
    
        Pagination struct {
            DefaultLimit int `def:"100" env:"DEFAULT_LIMIT" arg:"default-limit"`
        }
    
        RedisDetails map[string]string `def:"{}" env:"REDIS_DETAILS" arg:"redis-details"`
    }
    

    This struct is also a valid Confetti target. Just make sure that the value of the environment variable or flag is a valid JSON string, otherwise Confetti will give you an error.

Confetti options

Confetti exposes a NewLoader function and a NewDefLoader function (as used in the examples above).
The NewDefLoader uses the default options, but users can provide their own options by using the NewLoader function.
Here is the explanation of all available options:

Name Description Default value
Title The title that shows up on help documentation. configs
DefTagName The name of the tag that controls the default value. def
EnvTagName The name of the tag that controls the env variable name. env
ArgTagName The name of the tag that controls the flag name. arg
UseDotEnv Whether to use the .env file if present. false

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ILoader

type ILoader interface {
	// Load loads the configs into the provided target.
	Load(target interface{}) error
}

ILoader represents a configuration loader.

func NewDefLoader

func NewDefLoader() ILoader

NewDefLoader provides a new ILoader instance with default settings.

func NewLoader

func NewLoader(opts LoaderOptions) ILoader

NewLoader provides a new ILoader instance.

type LoaderOptions

type LoaderOptions struct {
	// Title is the title that will show up on -h or -help.
	Title string
	// DefTagName can be used to alter the name of the def tag.
	DefTagName string
	// EnvTagName can be used to alter the name of the env tag.
	EnvTagName string
	// ArgTagName can be used to alter the name of the arg tag.
	ArgTagName string
	// UseDotEnv controls whether to read data from the .env file.
	UseDotEnv bool
}

LoaderOptions can be used to customize the ILoader.

Jump to

Keyboard shortcuts

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