Skip to content

Commit

Permalink
Support .env [#3613]
Browse files Browse the repository at this point in the history
  • Loading branch information
firelizzard18 committed Jul 5, 2024
1 parent 99e0e8c commit 1dca716
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 3 deletions.
69 changes: 68 additions & 1 deletion cmd/accumulated/run/marshal.go → cmd/accumulated/run/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ package run
import (
"bytes"
"encoding/json"
"fmt"
"io/fs"
"os"
"path/filepath"
"reflect"
"regexp"
"strings"

"github.com/BurntSushi/toml"
"github.com/joho/godotenv"
"gitlab.com/accumulatenetwork/accumulate/pkg/errors"
"gopkg.in/yaml.v3"
)
Expand Down Expand Up @@ -58,7 +61,31 @@ func (c *Config) Load(b []byte, format func([]byte, any) error) error {
return err
}

return json.Unmarshal(b, c)
err = json.Unmarshal(b, c)
if err != nil {
return err
}

return c.applyDotEnv()
}

func (c *Config) applyDotEnv() error {
if !setDefaultPtr(&c.DotEnv, false) {
return nil
}

file := ".env"
if c.file != "" {
dir := filepath.Dir(c.file)
file = filepath.Join(dir, file)
}

env, err := godotenv.Read(file)
if err != nil && !errors.Is(err, fs.ErrNotExist) {
return err
}

return errors.Join(expandEnv(reflect.ValueOf(c), env)...)
}

func (c *Config) Save() error {
Expand Down Expand Up @@ -165,3 +192,43 @@ func float2int(v reflect.Value) any {
return v.Interface()
}
}

func expandEnv(v reflect.Value, env map[string]string) (errs []error) {
switch v.Kind() {
case reflect.String:
s := v.String()
s = os.Expand(s, func(name string) string {
value, ok := env[name]
if ok {
return value
}
errs = append(errs, fmt.Errorf("%q is not defined", name))
return fmt.Sprintf("#!MISSING(%q)", name)
})
v.SetString(s)

case reflect.Pointer, reflect.Interface:
errs = append(errs, expandEnv(v.Elem(), env)...)

case reflect.Slice, reflect.Array:
for i, n := 0, v.Len(); i < n; i++ {
errs = append(errs, expandEnv(v.Index(i), env)...)
}

case reflect.Map:
it := v.MapRange()
for it.Next() {
errs = append(errs, expandEnv(it.Key(), env)...)
errs = append(errs, expandEnv(it.Value(), env)...)
}

case reflect.Struct:
typ := v.Type()
for i, n := 0, typ.NumField(); i < n; i++ {
if typ.Field(i).IsExported() {
errs = append(errs, expandEnv(v.Field(i), env)...)
}
}
}
return errs
}
3 changes: 3 additions & 0 deletions cmd/accumulated/run/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Config:
- name: file
type: string
marshal-as: none
- name: DotEnv
type: bool
pointer: true
- name: Network
type: string
- name: Logging
Expand Down
20 changes: 20 additions & 0 deletions cmd/accumulated/run/types_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type CometPrivValFile struct {

type Config struct {
file string
DotEnv *bool `json:"dotEnv,omitempty" form:"dotEnv" query:"dotEnv" validate:"required"`
Network string `json:"network,omitempty" form:"network" query:"network" validate:"required"`
Logging *Logging `json:"logging,omitempty" form:"logging" query:"logging" validate:"required"`
Instrumentation *Instrumentation `json:"instrumentation,omitempty" form:"instrumentation" query:"instrumentation" validate:"required"`
Expand Down Expand Up @@ -359,6 +360,10 @@ func (v *CometPrivValFile) CopyAsInterface() interface{} { return v.Copy() }
func (v *Config) Copy() *Config {
u := new(Config)

if v.DotEnv != nil {
u.DotEnv = new(bool)
*u.DotEnv = *v.DotEnv
}
u.Network = v.Network
if v.Logging != nil {
u.Logging = (v.Logging).Copy()
Expand Down Expand Up @@ -976,6 +981,14 @@ func (v *CometPrivValFile) Equal(u *CometPrivValFile) bool {
}

func (v *Config) Equal(u *Config) bool {
switch {
case v.DotEnv == u.DotEnv:
// equal
case v.DotEnv == nil || u.DotEnv == nil:
return false
case !(*v.DotEnv == *u.DotEnv):
return false
}
if !(v.Network == u.Network) {
return false
}
Expand Down Expand Up @@ -1948,13 +1961,17 @@ func (v *CometPrivValFile) MarshalJSON() ([]byte, error) {

func (v *Config) MarshalJSON() ([]byte, error) {
u := struct {
DotEnv *bool `json:"dotEnv,omitempty"`
Network string `json:"network,omitempty"`
Logging *Logging `json:"logging,omitempty"`
Instrumentation *Instrumentation `json:"instrumentation,omitempty"`
P2P *P2P `json:"p2P,omitempty"`
Configurations *encoding.JsonUnmarshalListWith[Configuration] `json:"configurations,omitempty"`
Services *encoding.JsonUnmarshalListWith[Service] `json:"services,omitempty"`
}{}
if !(v.DotEnv == nil) {
u.DotEnv = v.DotEnv
}
if !(len(v.Network) == 0) {
u.Network = v.Network
}
Expand Down Expand Up @@ -2667,6 +2684,7 @@ func (v *CometPrivValFile) UnmarshalJSON(data []byte) error {

func (v *Config) UnmarshalJSON(data []byte) error {
u := struct {
DotEnv *bool `json:"dotEnv,omitempty"`
Network string `json:"network,omitempty"`
Logging *Logging `json:"logging,omitempty"`
Instrumentation *Instrumentation `json:"instrumentation,omitempty"`
Expand All @@ -2675,6 +2693,7 @@ func (v *Config) UnmarshalJSON(data []byte) error {
Services *encoding.JsonUnmarshalListWith[Service] `json:"services,omitempty"`
}{}

u.DotEnv = v.DotEnv
u.Network = v.Network
u.Logging = v.Logging
u.Instrumentation = v.Instrumentation
Expand All @@ -2685,6 +2704,7 @@ func (v *Config) UnmarshalJSON(data []byte) error {
if err != nil {
return err
}
v.DotEnv = u.DotEnv
v.Network = u.Network
v.Logging = u.Logging
v.Instrumentation = u.Instrumentation
Expand Down
4 changes: 2 additions & 2 deletions cmd/accumulated/run/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ var (

func Ptr[T any](v T) *T { return &v }

func setDefaultPtr[V any](ptr **V, def V) *V {
func setDefaultPtr[V any](ptr **V, def V) V {
if *ptr == nil {
*ptr = &def
}
return *ptr
return **ptr
}

func setDefaultVal[V any](ptr *V, def V) V {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ require (
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/joho/godotenv v1.5.1
github.com/jonboulle/clockwork v0.3.0 // indirect
github.com/julz/importas v0.1.0 // indirect
github.com/kisielk/errcheck v1.7.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,8 @@ github.com/jjti/go-spancheck v0.5.3 h1:vfq4s2IB8T3HvbpiwDTYgVPj1Ze/ZSXrTtaZRTc7C
github.com/jjti/go-spancheck v0.5.3/go.mod h1:eQdOX1k3T+nAKvZDyLC3Eby0La4dZ+I19iOl5NzSPFE=
github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U=
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
Expand Down

0 comments on commit 1dca716

Please sign in to comment.