https://github.com/aacanakin/env
Environment variable parser, mapper to go structs
https://github.com/aacanakin/env
env golang mapper parser
Last synced: 10 months ago
JSON representation
Environment variable parser, mapper to go structs
- Host: GitHub
- URL: https://github.com/aacanakin/env
- Owner: aacanakin
- License: mit
- Created: 2020-08-14T23:02:53.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2020-08-16T00:30:24.000Z (over 5 years ago)
- Last Synced: 2025-03-28T08:12:05.532Z (10 months ago)
- Topics: env, golang, mapper, parser
- Language: Go
- Homepage:
- Size: 27.3 KB
- Stars: 6
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# env: Parse environment variables, map to structs
 [](https://goreportcard.com/report/github.com/aacanakin/env) [](https://coveralls.io/github/aacanakin/env?branch=master)
env is a mapper from environment variables to structs
## Features
- Ability to map environment variables to structs
- Ability to customize environment variables with struct tags
- Ability to parse nested/sub structs
- Ability to parse embedded nested/sub structs
- Ability to parse and map types (`bool`, `string`, `int`, `int8`, `int16`, `int32`, `int64`, `uint`, `uint8`, `uint16`, `uint32`, `uint64`, `float32`, `float64`, `complex64`, `complex128`, `struct`)
## Getting started
### Install
```sh
// Requires go1.15+
go get github.com/aacanakin/env
```
### Usage
```go
// main.go
package main
import "fmt"
import "github.com/aacanakin/env"
type Config struct {
Host string
Port int
Debug bool
}
func main() {
var c Config
err := env.Parse(&c)
if err != nil {
panic(err)
}
fmt.Println("Host: ", c.Host)
fmt.Println("Port: ", c.Port)
fmt.Println("Debug: ", c.Debug)
}
```
Run
```sh
$ HOST=localhost PORT=8081 debug=true go run main.go
// Output
Host: localhost
Port: 8081
Debug: true
```
### Custom environment var mapping
```go
// main.go
package main
import "fmt"
import "github.com/aacanakin/env"
func main() {
type Config struct {
Host string `env:"SERVICE_HOST"`
Port int `env:"SERVICE_PORT"`
Debug bool `env:"SERVICE_DEBUG"`
}
var c Config
err := env.Parse(&c)
if err != nil {
panic(err)
}
fmt.Println("Host: ", c.Host)
fmt.Println("Port: ", c.Port)
fmt.Println("Debug: ", c.Debug)
}
```
Run
```sh
SERVICE_HOST=localhost SERVICE_PORT=8081 SERVICE_DEBUG=true go run main.go
// Output
Host: localhost
Port: 8081
Debug: true
```
### Nested/Sub structs
```go
// main.go
package main
import "fmt"
import "github.com/aacanakin/env"
type db struct {
Host string `env:"DB_HOST"`
Port int `env:"DB_PORT"`
}
type service struct {
Debug bool `env:"SERVICE_DEBUG"`
}
type Config struct {
DB db
Service service
}
func main() {
var c Config
err := env.Parse(&c)
if err != nil {
panic(err)
}
fmt.Println("DB Host: ", c.DB.Host)
fmt.Println("DB Port: ", c.DB.Port)
fmt.Println("Service Debug: ", c.Service.Debug)
}
```
Run
```sh
DB_HOST=localhost DB_PORT=3306 SERVICE_DEBUG=true go run main.go
// Output
DB Host: localhost
DB Port: 3306
Service Debug: true
```
### Using with .env
Install
```sh
go get github.com/joho/godotenv
```
Create a .env file
```sh
# .env
HOST=localhost
PORT=8081
```
```go
// main.go
package main
import (
"github.com/joho/godotenv"
"github.com/aacanakin/env"
"log"
)
type Config struct {
Host string
Port uint16
}
func main() {
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
var c Config
err = env.Parse(&c)
log.Println("Host: ", c.Host)
log.Println("Port: ", c.Port)
}
```
### Readonly config
Since it's a good practice to keep environment variables immutable, it will be also a good practice to keep the parsed struct immutable too. However, Go's reflect package doesn't allow setting unexported fields. So,
to keep the struct immutable;
- Create a config package
```go
package config
import "github.com/aacanakin/env"
type conf struct {
Host string
Port uint16
}
type Config struct {
conf conf
}
func (c Config) Host() string {
return c.conf.Host
}
func (c Config) Port() uint16 {
return c.conf.Port
}
func New() (*Config, error) {
var c conf
err := env.Parse(&c)
if err != nil {
return nil, err
}
return &Config{c}, nil
}
```
- Use it in your main.go
```go
package main
import (
"fmt"
"github.com/aacanakin/env_test/config"
)
func main() {
c, err := config.New()
if err != nil {
panic(err)
}
// HERE, c.conf is not accessible
fmt.Println("Host:", c.Host())
fmt.Println("Port:", c.Port())
}
```
NOTE: This looks like it's not very idiomatic go. Feedbacks here are welcome.
## Roadmap
- [ ] `omitempty` tag constraint
- [ ] `file` tag constraint
- [ ] Ability to customize tag key (default is env)
- [ ] Provide an instance based parser
- [ ] Provide a read only config example with custom conf package
- [ ] Release v0.1