config

package module
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Jun 21, 2023 License: MIT Imports: 16 Imported by: 1

README

go-config

Effortless, stateful go configuration.

A straightforward go configuration library that supports flags, environment variables, toml, yaml and JSON configuration formats.

go-config also supports using multiple configuration format options at the same time. For example, you can provide flags and environment variables.

Because creating configuration files is tedious, go-config can generate configuration files for you. This helps remove human error from configuration files and makes configuration files easier to maintain since you only need to make changes in a single location.

Getting Started

Get the library:

> go get -u github.com/pcelvng/go-config

General use:

// myapp.go
package main

import (
	"fmt"
	"os"
	"time"

	"github.com/pcelvng/go-config"
)

func main() {
	appCfg := options{
		RunDuration: time.Second * 1,
		EchoTime:    time.Now(),
		DuckNames:   []string{"Freddy", "Eugene", "Alladin", "Sarah"},
		DB: DB{
			Host:     "localhost:5432",
			Username: "default_username",
		},
	}
	err := config.Load(&appCfg)
	if err != nil {
		fmt.Printf("err: %v\n", err.Error())
		os.Exit(1)
	}
	// show values
	fmt.Println("configuration values:")
	if err := config.Show(); err != nil {
		fmt.Printf("err: %v\n", err.Error())
		os.Exit(1)
	}

	// Run for RunDuration.
	fmt.Println("waiting for " + appCfg.RunDuration.String() + "...")
	<-time.NewTicker(appCfg.RunDuration).C

	fmt.Printf("echo time: " + time.Now().Format(time.RFC3339) + "\n")
	fmt.Println("done")
}

type options struct {
	RunDuration time.Duration // Supports time.Duration
	EchoTime    time.Time     `fmt:"RFC3339"`      // Suports time.Time with go-style formatting.
	DuckNames   []string      `sep:";"`            // Supports slices. (Default separator is ",")
	IgnoreMe    int           `env:"-" flag:"-"`   // Ignore for specified types.
	DB          DB            `env:"DB" flag:"db"` // Supports struct types.
}

type DB struct {
	Name     string
	Host     string `help:"The db host:port."`
	Username string `env:"UN" flag:"un,u" help:"The db username."`
	Password string `env:"PW" flag:"pw,p" help:"The db password." show:"false"`
}

Build app:

> go build 

Built in help menu:

> ./myapp -h # or --help

  -c, --config string   Config file path. Extension must be toml|yaml|yml|json.
  -g, --gen string      Generate config template (json|env|toml|yaml).
      --show bool       Print loaded config values and exit. 

      --run-duration duration   (default: 1s)
      --echo-time time          fmt: RFC3339 (default: 2020-11-30T17:04:00-07:00)
      --duck-names strings      (default: [Freddy;Eugene;Alladin;Sarah])
      --db-name string          
      --db-host string          The db host:port. (default: "localhost:5432")
  -u, --db-un string            The db username. (default: "default_username")
  -p, --db-pw string            The db password.

Generate config templates to save typing:

> ./myapp -g=env
#!/usr/bin/env sh

export RUN_DURATION=1s
export ECHO_TIME=2020-11-30T17:04:41-07:00 # fmt: RFC3339
export DUCK_NAMES=[Freddy;Eugene;Alladin;Sarah]
export DB_NAME=
export DB_HOST=localhost:5432 # The db host:port.
export DB_UN=default_username # The db username.
export DB_PW= # The db password.

When assigning structs as field values you may ignore the value as a prefix by using the "omitprefix" env value. This special value only works on struct and struct pointer types.

type options struct {
    Host    string                     // Defaults to 'HOST'.
    DB      DB      `env:"omitprefix"` // No prefix is expected or generated.
}

type DB struct {
    Username string `env:"UN"` 
    Password string `env:"PW"`
}

...

> ./myapp -gen=env

#!/usr/bin/env bash

export HOST=localhost:5432;
export UN=; # no prefix
export PW=; # no prefix

Long Help Descriptions

For longer help descriptions you may call the "Help" method. Embedded struct methods are addressed using "." in between members. Long help descriptions will likely be rendered on the line above a field when rendering to a template.

func main() {
    appCfg := options{
        Host: "localhost:5432", // default host value
    }
    config.FieldHelp("Host", "once upon a time there was a very long description....")
    config.FieldHelp("DB.Username", "a really long custom description for the username field...")
    err := config.Load(&appCfg)
    if err != nil {
        println("err: %v", err.Error())
        os.Exit(1)
    }
}

type options struct {
    Host    string
    DB      DB
}

type DB struct {
    Username string 
}

By default all configuration modes are enabled. You may specify the exact modes you wish to use by calling the "With" method.

NOTE: Configs are loaded in the same order specified by "With".

func main() {
    appCfg := &options{}
    err := config.With("flag", "env", "toml", "json", "yaml").Load(appCfg)
    if err != nil {
        fmt.Printf("err: %v\n", err.Error())
        os.Exit(1)
    }
}

type options struct {
	RunDuration time.Duration // Supports time.Duration
	EchoTime    time.Time     `fmt:"RFC3339"`      // Suports time.Time with go-style formatting.
	DuckNames   []string      `sep:";"`            // Supports slices. (Default separator is ",")
	IgnoreMe    int           `env:"-" flag:"-"`   // Ignore for specified types.
	DB          DB            `env:"DB" flag:"db"` // Supports struct types.
}

type DB struct {
	Name     string
	Host     string `help:"The db host:port."`
	Username string `env:"UN" flag:"un,u" help:"The db username."`
	Password string `env:"PW" flag:"pw,p" help:"The db password." show:"false"`
}

Prefixed Keys (env and flags):

NOTE: prefix must be applied at time of construction and cannot be set after initialization

func main() {
    appCfg := &options{}
    cfg := config.NewWithPrefix("my_app").With("env")
    err := cfg.Load(appCfg)
    if err != nil {
        fmt.Printf("err: %v\n", err.Error())
        os.Exit(1)
    }
}

type options struct {
	Host string // Loaded from MY_APP_HOST env var
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Load

func Load(appCfgs ...interface{}) error

Load is a package wrapper around *GoConfig.Load().

func LoadOrDie

func LoadOrDie(appCfgs ...interface{})

LoadOrDie is a package wrapper around *GoConfig.LoadOrDie().

func Show added in v0.2.0

func Show() error

func ShowOrDie added in v0.2.0

func ShowOrDie()

Types

type ConfigExtNotFoundErr added in v0.3.0

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

func (ConfigExtNotFoundErr) Error added in v0.3.0

func (ce ConfigExtNotFoundErr) Error() string

type GoConfig added in v0.3.1

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

func DisableStdFlags added in v0.5.0

func DisableStdFlags() *GoConfig

DisableStdFlags is a package wrapper around *GoConfig.DisableFlagHelp().

func FieldHelp added in v0.3.3

func FieldHelp(fieldName, helpTxt string) *GoConfig

func FieldTag added in v0.3.3

func FieldTag(fieldName, tagName, helpTxt string) *GoConfig

func New

func New() *GoConfig

New creates a new config.

func NewWithPrefix added in v0.6.0

func NewWithPrefix(prefix string) *GoConfig

NewWithPrefix creates a new config with a global prefix for loaders.

func RegisterLoadUnloader added in v0.3.0

func RegisterLoadUnloader(loadUnloader *LoadUnloader) *GoConfig

RegisterLoadUnloader is a package wrapper around *GoConfig.RegisterLoadUnloader().

func SetConfigPath added in v0.5.0

func SetConfigPath(pth string) *GoConfig

SetConfigPath is a package wrapper around *GoConfig.SetConfigPath().

func Version

func Version(s string) *GoConfig

Version is a package wrapper around GoConfig.Version().

func With

func With(with ...string) *GoConfig

With is a package wrapper around *GoConfig.With().

func WithFlagOptions added in v0.3.2

func WithFlagOptions(o flg.Options) *GoConfig

func WithShowOptions added in v0.3.0

func WithShowOptions(o render.Options) *GoConfig

func (*GoConfig) DisableStdFlags added in v0.5.0

func (g *GoConfig) DisableStdFlags() *GoConfig

DisableStdFlags will disable standard CLI options such as --gen.

Note: This does not disable flag usage. To disable flags entirely call "With" providing the config types you wish to include.

func (*GoConfig) FShowValues added in v0.3.1

func (g *GoConfig) FShowValues(w io.Writer) error

func (*GoConfig) FieldHelp added in v0.3.3

func (g *GoConfig) FieldHelp(fieldName, helpTxt string) *GoConfig

FieldHelp allows adding a struct field help tag at runtime. Field names are dot "." separated values when referring to struct fields in struct fields.

Field names are validated when "Load" is called.

func (*GoConfig) FieldTag added in v0.3.3

func (g *GoConfig) FieldTag(fieldName, tagName, helpTxt string) *GoConfig

FieldTag allows for runtime modification of struct field tags. Field names are dot "." separated values when referring to struct fields in struct fields.

Field names are validated when "Load" is called.

func (*GoConfig) Load added in v0.3.1

func (g *GoConfig) Load(appCfgs ...interface{}) error

Load handles: - basic validation - flag pre-loading for handling standard flags and customizing the help screen - final config load - post load validation by:

  • enforcing "validate" struct field tag directives TODO
  • calling the custom Validate method (if implemented) TODO

func (*GoConfig) LoadOrDie added in v0.3.1

func (g *GoConfig) LoadOrDie(appCfg ...interface{})

LoadOrDie calls Load and prints an error message and exits if there is an error.

func (*GoConfig) RegisterLoadUnloader added in v0.3.1

func (g *GoConfig) RegisterLoadUnloader(loadUnloader *LoadUnloader) *GoConfig

RegisterLoadUnloader registers a LoadUnloader.

The name is the name referenced when using With if specifying a custom subset of loaders.

TODO: Change this behavior to include the custom loader unless "With" is exercised and the loader is not included. When using "With" you must also include the name of the custom registered loader or it will not be used.

Using a standard loader name replaces that standard loader. If, for example "toml" is the provided custom name then the custom "toml" implementation will be used instead of the standard one. Note that custom implementations of standard file loaders will need to specify the desired fileExt file extensions.

FileExts is optional and if specified indicates the configuration is found at a file with the provided file extension. At least one FileExts is required for loading from a configuration file. Multiple file extensions can be registered. Space characters and leading periods (".") are trimmed. Therefore you could also provide ".yaml" or "yaml". It doesn't matter.

Because of its special nature, overriding "flag" is not allowed. Attempting to override "flag" will panic. Flags can be disabled by taking advantage of the "With" method and omitting "flag".

Not providing name or LoadUnloader will panic.

func (*GoConfig) SetConfigPath added in v0.5.0

func (g *GoConfig) SetConfigPath(pth string) *GoConfig

SetConfigPath can be used to set the config path in a manner other than through the standard "--config,-c" standard flag.

This can be useful when the user: - Wishes to set a default config flag value. - Wishes to set a config path while having standard flags disabled.

Note: The --config,-c flag value will override this value unless standard flags are disabled.

func (*GoConfig) ShowValues added in v0.3.1

func (g *GoConfig) ShowValues() error

ShowValues writes the values to os.Stderr.

func (*GoConfig) Version added in v0.3.1

func (g *GoConfig) Version(v string) *GoConfig

Version sets the application version. If a version is provided then the user can specify the --version flag to show the version. Otherwise the version flag is not seen on the help screen.

func (*GoConfig) With added in v0.3.1

func (g *GoConfig) With(newWith ...string) *GoConfig

With sets which configuration loaders are enabled. Order matters. Configuration is loaded in the same order as the new specified "with" list.

Values can be any of: "env", "toml", "yaml", "json", "flag" or names of custom loaders registered with RegisterLoadUnloader.

If a loader name does not exist then With panics. Custom LoadUnloaders must be registered before calling With.

func (*GoConfig) WithFlagOptions added in v0.3.2

func (g *GoConfig) WithFlagOptions(o flg.Options) *GoConfig

func (*GoConfig) WithShowOptions added in v0.3.1

func (g *GoConfig) WithShowOptions(o render.Options) *GoConfig

type LoadUnloader added in v0.3.0

type LoadUnloader struct {
	Name string

	// FileExts tells go-config what extensions to look for when matching a config file
	// name to a LoadUnloader. No file extensions means the config can be loaded by some
	// other means such as environment variables loading from the environment or from a server
	// like etcd, consul or vault.
	FileExts []string

	// Loader is required.
	Loader load.Loader

	// Unloader is not required; if not present then config templates will not be generatable for it.
	Unloader load.Unloader
}

type LoaderNotFoundErr added in v0.3.0

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

func (LoaderNotFoundErr) Error added in v0.3.0

func (ue LoaderNotFoundErr) Error() string

type UnloaderNotFoundErr added in v0.3.0

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

func (UnloaderNotFoundErr) Error added in v0.3.0

func (ue UnloaderNotFoundErr) Error() string

type Validator

type Validator interface {
	Validate() error
}

Validator can be implemented by the user provided config struct. Validate() is called after loading and running tag level validation.

Directories

Path Synopsis
env

Jump to

Keyboard shortcuts

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