Skip to content

Commit

Permalink
PR Fix, use an already developed method
Browse files Browse the repository at this point in the history
  • Loading branch information
jakeschuurmans committed Aug 23, 2024
1 parent 6760d3c commit 5e0c559
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 34 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ require (
github.com/jackc/pgx/v4 v4.18.3 // indirect
github.com/jacobweinstock/iamt v0.0.0-20230502042727-d7cdbe67d9ef // indirect
github.com/jacobweinstock/registrar v0.4.7 // indirect
github.com/jeremywohl/flatten v1.0.1 // indirect
github.com/jmoiron/sqlx v1.4.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.9 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,8 @@ github.com/jacobweinstock/iamt v0.0.0-20230502042727-d7cdbe67d9ef h1:G4k02HGmBUf
github.com/jacobweinstock/iamt v0.0.0-20230502042727-d7cdbe67d9ef/go.mod h1:FgmiLTU6cJewV4Xgrq6m5o8CUlTQOJtqzaFLGA0mG+E=
github.com/jacobweinstock/registrar v0.4.7 h1:s4dOExccgD+Pc7rJC+f3Mc3D+NXHcXUaOibtcEsPxOc=
github.com/jacobweinstock/registrar v0.4.7/go.mod h1:PWmkdGFG5/ZdCqgMo7pvB3pXABOLHc5l8oQ0sgmBNDU=
github.com/jeremywohl/flatten v1.0.1 h1:LrsxmB3hfwJuE+ptGOijix1PIfOoKLJ3Uee/mzbgtrs=
github.com/jeremywohl/flatten v1.0.1/go.mod h1:4AmD/VxjWcI5SRB0n6szE2A6s2fsNHDLO0nAlMHgfLQ=
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
Expand Down
57 changes: 23 additions & 34 deletions internal/app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package app

import (
"os"
"reflect"
"strings"

"github.com/jeremywohl/flatten"
"github.com/metal-toolbox/flipflop/internal/model"
"github.com/metal-toolbox/flipflop/internal/store/fleetdb"
"github.com/metal-toolbox/rivets/events"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
"github.com/spf13/viper"
)

var (
Expand Down Expand Up @@ -56,7 +56,7 @@ func (a *App) LoadConfiguration(cfgFilePath, loglevel string) error {
cfg := &Configuration{}
a.Config = cfg

err := setConfigDefaults(a.v, cfg, "", ".")
err := a.envBindVars()
if err != nil {
return err
}
Expand Down Expand Up @@ -130,40 +130,29 @@ func (cfg *Configuration) validate() error {
return nil
}

// setConfigDefaults sets all values in the struct to empty. This is to get around a weird quirk of viper.
// Viper will not override from a ENV variable if the value isnt set first.
// Resulting in ENV variables never getting loaded in if they arent in the config.yaml, even empty in the config.
// https://github.com/spf13/viper/issues/584#issuecomment-1210957041
func setConfigDefaults(v *viper.Viper, i interface{}, parent, delim string) error {
// Retrieve the underlying type of variable `i`.
r := reflect.TypeOf(i)

// If `i` is of type pointer, retrieve the referenced type.
if r.Kind() == reflect.Ptr {
r = r.Elem()
// envBindVars binds environment variables to the struct
// without a configuration file being unmarshalled,
// this is a workaround for a viper bug,
//
// This can be replaced by the solution in https://github.com/spf13/viper/pull/1429
// once that PR is merged.
func (a *App) envBindVars() error {
envKeysMap := map[string]interface{}{}
if err := mapstructure.Decode(a.Config, &envKeysMap); err != nil {
return err
}

// Iterate over each field for the type. By default, there is a single field.
for i := 0; i < r.NumField(); i++ {
// Retrieve the current field and get the `mapstructure` tag.
f := r.Field(i)
env := f.Tag.Get("mapstructure")

// By default, set the key to the current tag value. If a parent value was passed in
// prepend the parent and the delimiter.
if parent != "" {
env = parent + delim + env
}
// Flatten nested conf map
flat, err := flatten.Flatten(envKeysMap, "", flatten.DotStyle)
if err != nil {
return errors.Wrap(err, "Unable to flatten config")
}

// If it's a struct, only bind properties.
if f.Type.Kind() == reflect.Struct {
t := reflect.New(f.Type).Elem().Interface()
_ = setConfigDefaults(v, t, env, delim)
continue
for k := range flat {
if err := a.v.BindEnv(k); err != nil {
return errors.Wrap(ErrConfig, "env var bind error: "+err.Error())
}

// Bind the environment variable.
v.SetDefault(env, nil)
}
return v.Unmarshal(i)

return nil
}

0 comments on commit 5e0c559

Please sign in to comment.