Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kuritka/12f
https://github.com/kuritka/12f
Last synced: 24 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/kuritka/12f
- Owner: kuritka
- Created: 2021-10-08T13:18:15.000Z (about 3 years ago)
- Default Branch: master
- Last Pushed: 2021-11-16T10:26:24.000Z (about 3 years ago)
- Last Synced: 2024-10-11T11:21:21.465Z (about 1 month ago)
- Language: Makefile
- Size: 83 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# ENV binder
The ENV-BINDER package is used to easily bind environment variables to GO structures. ENV-BINDER is designed to
be usable in the widest possible range of scenarios.Among other things, it supports variable
prefixes and bindings to unexported arrays. Take a look at the following usage example:
```golang
import "github.com/kuritka/12f/env"type Endpoint struct {
URL string `env:"ENDPOINT_URL, require=true"`
}type Config struct {
// reading string value from NAME
Name string `env:"NAME"`// reuse an already bound env variable NAME
Description string `env:"NAME"`// reuse an already bound variable NAME, but replace only when name was not set before
AlternativeName string `env:"NAME, protected=true"`// reading int with 8080 as default value
DefaultPort uint16 `env:"PORT, default=8080"`// reading slice of strings with default values
Regions []string `env:"REGIONS, default=[us-east-1,us-east-2,us-west-1]"`// reading slice of strings from env var
Subnets []string `env:"SUBNETS, default=[10.0.0.0/24,192.168.1.0/24]"`
// default=[] ensures that if INTERVALS does not exist, []int8{} is set instead of []int8{nil}
Interval []uint8 `env:"INTERVALS, default=[]"`// nested structure
Credentials struct {// binding required value
KeyID string `env:"ACCESS_KEY_ID, require=true"`// binding to private field
secretKey string `env:"SECRET_ACCESS_KEY, require=true"`
}// expected PRIMARY_ prefix in nested environment variables
Endpoint1 Endpoint `env:"PRIMARY"`// expected FAILOVER_ prefix in nested environment variables
Endpoint2 Endpoint `env:"FAILOVER"`// the field does not have a bind tag set, so it will be ignored during bind
Args []string
}func main() {
defer clean()
os.Setenv("PRIMARY_ENDPOINT_URL", "https://ep1.cloud.example.com")
os.Setenv("FAILOVER_ENDPOINT_URL", "https://ep2.cloud.example.com")
os.Setenv("ACCESS_KEY_ID", "AKIAIOSFODNN7EXAMPLE")
os.Setenv("SECRET_ACCESS_KEY", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY")
os.Setenv("NAME", "Hello from 12-factor")
os.Setenv("PORT", "9000")
os.Setenv("SUBNETS", "10.0.0.0/24,10.0.1.0/24, 10.1.0.0/24, 10.1.1.0/24")c := &Config{}
c.AlternativeName = "protected name"
c.Description = "hello from ENV-BINDER"
if err := env.Bind(c); err != nil {
fmt.Println(err)
return
}
fmt.Println(JSONize(c))
}
```
function main generates the following output:
```json
{
"Name": "Hello from 12-factor",
"Description": "Hello from 12-factor",
"AlternativeName": "protected name",
"DefaultPort": 9000,
"Regions": [
"us-east-1",
"us-east-2",
"us-west-1"
],
"Subnets": [
"10.0.0.0/24",
"10.0.1.0/24",
"10.1.0.0/24",
"10.1.1.0/24"
],
"Interval": [],
"Credentials": {
"KeyID": "AKIAIOSFODNN7EXAMPLE"
},
"Endpoint1": {
"URL": "https://ep1.cloud.example.com"
},
"Endpoint2": {
"URL": "https://ep2.cloud.example.com"
},
"Args": null
}
```## supported types
ENV-BINDER supports all types listed in the following table. In addition, it should be noted that in the case
of slices, ENV-BINDER creates an instance of an empty slice if the value of the environment variable is
declared and its value is empty string. In this case ENV-BINDER returns an empty slice instead of the vulnerable nil.| primitive types | slices |
|---|---|
| `int`,`int8`,`int16`,`int32`,`int64` | `[]int`,`[]int8`,`[]int16`,`[]int32`,`[]int64` |
| `float32`,`float64` | `[]float32`,`[]float64` |
| `uint`,`uint8`,`uint16`,`uint32`,`uint64` | `[]uint`,`[]uint8`,`[]uint16`,`[]uint32`,`[]uint64` |
| `bool` | `[]bool` |
| `string` | `[]string` |## supported keywords
Besides the fact that ENV-BINDER works with private fields and can add prefixes to variable names, it
operates with several keywords. The structure in the introductory section works with all types
of these keywords.- `default` - the value specified in the default tag is used in case env variable does not exist. e.g:
`env: "SUBNET", default=10.0.1.0/24` or `env: "ENV_SUBNETS", default=[]` which will set an empty slice instead
of a vulnerable nil value in case `ENV_SUBNETS` does not exist.- `require` - if `require=true` then env variable must exist otherwise Bind function returns error
- `protected` - if `protected=true` then, in case the field in the structure already has a set value , the
Bind function will not set it. Otherwise, bind will be applied to it.You can combine individual tags freely: `env: "ENV_SWITCHER", default=[true, false, true], protected=true`
is a perfectly valid configuration## API
If the Bind function is not enough for you, you can use any of the static functions of our API:
```go
// string
GetEnvAsStringOrFallback(key, defaultValue string) string
GetEnvAsArrayOfStringsOrFallback(key string, defaultValue []string) []string// int
GetEnvAsIntOrFallback(key string, defaultValue int) (int, error)
GetEnvAsArrayOfIntsOrFallback(key string, defaultValue []int) ([]int, error)// float64
GetEnvAsFloat64OrFallback(key string, defaultValue float64) (float64, error)
GetEnvAsArrayOfFloat64OrFallback(key string, defaultValue []float64) ([]float64, error)// bool
GetEnvAsBoolOrFallback(key string, defaultValue bool) (bool, error)
GetEnvAsArrayOfBoolOrFallback(key string, defaultValue []bool) ([]bool, error)
```