Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/BoRuDar/configuration
Library for setting values to structs' fields from env, flags, files or default tag
https://github.com/BoRuDar/configuration
12-factor config configuration configuration-management go golang microservices reflect reflection
Last synced: about 2 months ago
JSON representation
Library for setting values to structs' fields from env, flags, files or default tag
- Host: GitHub
- URL: https://github.com/BoRuDar/configuration
- Owner: BoRuDar
- License: mit
- Created: 2019-11-27T17:58:49.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2024-04-13T22:05:48.000Z (8 months ago)
- Last Synced: 2024-07-31T20:44:00.484Z (4 months ago)
- Topics: 12-factor, config, configuration, configuration-management, go, golang, microservices, reflect, reflection
- Language: Go
- Homepage:
- Size: 127 KB
- Stars: 109
- Watchers: 4
- Forks: 10
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
- awesome-go - configuration - Library for initializing configuration structs from env variables, files, flags and 'default' tag. (Configuration / Standard CLI)
- fucking-awesome-go - configuration - Library for initializing configuration structs from env variables, files, flags and 'default' tag. (Configuration / Standard CLI)
- awesome-go - configuration - Library for initializing configuration structs from env variables, files, flags and 'default' tag. (Configuration / Standard CLI)
- awesome-go - configuration - Library for initializing configuration structs from env variables, files, flags and 'default' tag. (Configuration / Standard CLI)
- awesome-go-extra - configuration - 11-27T17:58:49Z|2022-07-27T20:20:05Z| (Configuration / Advanced Console UIs)
- awesome-go-with-stars - configuration - Library for initializing configuration structs from env variables, files, flags and 'default' tag. (Configuration / Standard CLI)
- awesome-go-cn - configuration
- awesome-go-plus - configuration - Library for initializing configuration structs from env variables, files, flags and 'default' tag. ![stars](https://img.shields.io/badge/stars-108-blue) (Configuration / Standard CLI)
- awesome-go-plus - configuration - Library for initializing configuration structs from env variables, files, flags and 'default' tag. (Configuration / Standard CLI)
README
[![Go Report Card](https://goreportcard.com/badge/github.com/BoRuDar/configuration/v4)](https://goreportcard.com/report/github.com/BoRuDar/configuration/v4)
[![codecov](https://codecov.io/gh/BoRuDar/configuration/branch/master/graph/badge.svg)](https://codecov.io/gh/BoRuDar/configuration)
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/6295/badge)](https://www.bestpractices.dev/projects/6295)
[![GoDoc](https://godoc.org/github.com/BoRuDar/configuration?status.png)](https://godoc.org/github.com/BoRuDar/configuration/v4)
[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)# Configuration
is a library for injecting values recursively into structs - a convenient way of setting up a configuration object.
Available features:
- setting *default* values for struct fields - `NewDefaultProvider()`
- setting values from *environment* variables - `NewEnvProvider()`
- setting values from command line *flags* - `NewFlagProvider(&cfg)`
- setting values from a JSON *file* - `NewJSONFileProvider("./testdata/input.json")`## Supported types:
- `string`, `*string`, `[]string`, `[]*string`
- `bool`, `*bool`, `[]bool`, `[]*bool`
- `int`, `int8`, `int16`, `int32`, `int64` + slices of these types
- `*int`, `*int8`, `*int16`, `*int32`, `*int64` + slices of these types
- `uint`, `uint8`, `uint16`, `uint32`, `uint64` + slices of these types
- `*uint`, `*uint8`, `*uint16`, `*uint32`, `*uint64` + slices of these types
- `float32`, `float64` + slices of these types
- `*float32`, `*float64` + slices of these types
- `time.Duration` from strings like `12ms`, `2s` etc.
- embedded structs and pointers to structs
- any custom type which satisfies `FieldSetter` [interface](#FieldSetter-interface)# Why?
- your entire configuration can be defined in one model
- all metadata is in your model (defined with `tags`)
- easy to set/change a source of data for your configuration
- easy to set a priority of sources to fetch data from (e.g., 1.`flags`, 2.`env`, 3.`default` or another order)
- you can implement your custom provider
- no external dependencies
- complies with `12-factor app`# Quick start
Import path `github.com/BoRuDar/configuration/v4`
```go
// defining a struct
cfg := struct {
Name string `flag:"name"`
LastName string `default:"defaultLastName"`
Age byte `env:"AGE_ENV" default:"-1"`
BoolPtr *bool `default:"false"`
ObjPtr *struct {
F32 float32 `default:"32"`
StrPtr *string `default:"str_ptr_test"`
HundredMS time.Duration `default:"100ms"`
}Obj struct {
IntPtr *int16 `default:"123"`
Beta int `file_json:"inside.beta" default:"24"`
StrSlice []string `default:"one;two"`
IntSlice []int64 `default:"3; 4"`
unexported string `xml:"ignored"`
}
}{}configurator := configuration.New(
&cfg,
// order of execution will be preserved:
configuration.NewFlagProvider(), // 1st
configuration.NewEnvProvider(), // 2nd
configuration.NewJSONFileProvider(fileName), // 3rd
configuration.NewDefaultProvider(), // 4th
)if err := configurator.InitValues(); err != nil {
log.Fatalf("unexpected error: ", err)
}
```If you need only ENV variables and default values you can use a shorter form:
```go
err := configuration.FromEnvAndDefault(&cfg)
```# Providers
You can specify one or more providers. They will be executed in order of definition:
```go
[]Provider{
NewFlagProvider(&cfg), // 1
NewEnvProvider(), // 2
NewDefaultProvider(), // 3
}
```
If provider set value successfully next ones will not be executed (if flag provider from the sample above found a value env and default providers are skipped).
The value of first successfully executed provider will be set.
If none of providers found value - an application will be terminated.
This behavior can be changed with `configurator.OnFailFnOpt` option:
```go
err := configuration.New(
&cfg,
configuration.NewEnvProvider(),
configuration.NewDefaultProvider()).
SetOptions(
configuration.OnFailFnOpt(func(err error) {
log.Println(err)
}),
).InitValues()
```### Custom provider
You can define a custom provider which should satisfy next interface:
```go
type Provider interface {
Name() string
Init(ptr any) error
Provide(field reflect.StructField, v reflect.Value) error
}
```### Default provider
Looks for `default` tag and set value from it:
```go
struct {
// ...
Name string `default:"defaultName"`
// ...
}
```### Env provider
Looks for `env` tag and tries to find an ENV variable with the name from the tag (`AGE` in this example):
```go
struct {
// ...
Age byte `env:"AGE"`
// ...
}
```
Name inside tag `env:""` must be unique for each field. Only UPPER register for ENV vars is accepted:
```bash
bad_env_var_name=bad
GOOD_ENV_VAR_NAME=good
```### Flag provider
Looks for `flag` tag and tries to set value from the command line flag `-first_name`
```go
struct {
// ...
Name string `flag:"first_name|default_value|Description"`
// ...
}
```
Name inside tag `flag:""` must be unique for each field. `default_value` and `description` sections are `optional` and can be omitted.
`NewFlagProvider(&cfg)` expects a pointer to the same object for initialization.*Note*: if program is executed with `-help` or `-h` flag you will see all available flags with description:
```bash
Flags:
-first_name "Description (default: default_value)"
```
And program execution will be terminated.
#### Options for _NewFlagProvider_
* WithFlagSet - sets a custom FlagSet### JSON File provider
Requires `file_json:""` tag.
```go
NewJSONFileProvider("./testdata/input.json")
```
For example, tag `file_json:"cache.retention"` will assume that you have this structure of your JSON file:
```json
{
"cache": {
"retention": 1
}
}
```### Additional providers
* [YAML files](https://github.com/BoRuDar/configuration-yaml-file)## FieldSetter interface
You can define how to set fields with any custom types:
```go
type FieldSetter interface {
SetField(field reflect.StructField, val reflect.Value, valStr string) error
}
```
Example:
```go
type ipTest net.IPfunc (it *ipTest) SetField(_ reflect.StructField, val reflect.Value, valStr string) error {
i := ipTest(net.ParseIP(valStr))if val.Kind() == reflect.Pointer {
val.Set(reflect.ValueOf(&i))
} else {
val.Set(reflect.ValueOf(i))
}return nil
}
```# Contribution
1. Open a feature request or a bug report in [issues](https://github.com/BoRuDar/configuration/issues)
2. Fork and create a PR into `dev` branch