Skip to content

Instantly share code, notes, and snippets.

@frectonz
Created August 7, 2025 10:10
Show Gist options
  • Select an option

  • Save frectonz/9162d6824f54f1dc35c6d563dfe89ff9 to your computer and use it in GitHub Desktop.

Select an option

Save frectonz/9162d6824f54f1dc35c6d563dfe89ff9 to your computer and use it in GitHub Desktop.
package env
import (
"fmt"
"net"
"os"
"reflect"
"strconv"
"strings"
"github.com/joho/godotenv"
)
type Env struct {
MinioAddress string `env:"MINIO_ADDRESS" help:"The URL used to access MinIO."`
MinioAccessKeyId string `env:"MINIO_ACCESS_KEY_ID" help:"The ID of the access key used to connect to MinIO."`
MinioUseSsl bool `env:"MINIO_USE_SSL" help:"Whether SSL should be used when connecting to MinIO."`
MinioAccessKeySecret string `env:"MINO_ACCESS_KEY_SECRET" help:"The secret of the access key used to connect to minio."`
SocketAddress string `env:"SOCKET_ADDRESS" help:"The TCP address the server should listen at."`
}
func Parse(program string) Env {
var (
errors []fmt.Stringer
result Env
val = reflect.ValueOf(&result).Elem()
typ = val.Type()
prefix = strings.ToUpper(program) + "_"
)
err := godotenv.Load()
if err != nil {
errors = append(errors, LoadDotenvFailed{Err: err})
}
for i := 0; i < typ.NumField(); i++ {
field := typ.Field(i)
envTag := field.Tag.Get("env")
fullEnvKey := prefix + envTag
envValue, ok := os.LookupEnv(fullEnvKey)
if !ok {
errors = append(errors, MissingEnvVarError{Key: fullEnvKey})
continue
}
if envValue == "" {
errors = append(errors, EmptyEnvVarError{Key: fullEnvKey})
continue
}
switch field.Type {
case reflect.TypeOf((*net.TCPAddr)(nil)):
addr, err := net.ResolveTCPAddr("tcp", envValue)
if err != nil {
errors = append(errors, InvalidAddressError{Key: fullEnvKey, Value: envValue, Err: err})
continue
}
val.Field(i).Set(reflect.ValueOf(addr))
case reflect.TypeOf(""):
val.Field(i).Set(reflect.ValueOf(envValue))
case reflect.TypeOf(true):
boolean, err := strconv.ParseBool(envValue)
if err != nil {
errors = append(errors, InvalidBooleanError{Key: fullEnvKey, Value: envValue, Err: err})
continue
}
val.Field(i).Set(reflect.ValueOf(boolean))
default:
errors = append(errors, UnsupportedTypeError{Field: field.Name, Type: field.Type.String()})
}
}
if len(errors) > 0 {
printHelp(program, Env{})
fmt.Println()
fmt.Println(Bold + "I faced an error parsing the following environment variables:\n" + Reset)
for _, err := range errors {
fmt.Println(err.String())
}
fmt.Println()
os.Exit(1)
}
return result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment