Skip to content

Commit

Permalink
feat: Allow Environment Variables to override config.json (#125)
Browse files Browse the repository at this point in the history
* add envvar override of config.json

* use viper

* Revert "use viper"

This reverts commit 18cb752.

* bump patch in version

* adds log to match monorepo pr

---------

Co-authored-by: colinlyguo <colinlyguo@scroll.io>
  • Loading branch information
dghelm and colinlyguo authored Aug 22, 2024
1 parent 5accd3b commit 5d5f457
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 1 deletion.
98 changes: 98 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ package config

import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"reflect"
"strconv"
"strings"

"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/log"
"github.com/scroll-tech/go-ethereum/rpc"

"github.com/scroll-tech/chain-monitor/internal/utils/database"
Expand Down Expand Up @@ -88,5 +93,98 @@ func NewConfig(file string) (*Config, error) {
if err != nil {
return nil, err
}

// Override config with environment variables
err = overrideConfigWithEnv(&cfg, "SCROLL_CHAIN_MONITOR")
if err != nil {
return nil, err
}

return &cfg, nil
}

// overrideConfigWithEnv recursively overrides config values with environment variables
func overrideConfigWithEnv(cfg interface{}, prefix string) error {
v := reflect.ValueOf(cfg)
if v.Kind() != reflect.Ptr || v.IsNil() {
return nil
}
v = v.Elem()

t := v.Type()
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
fieldValue := v.Field(i)

if !fieldValue.CanSet() {
continue
}

tag := field.Tag.Get("json")
if tag == "" {
tag = strings.ToLower(field.Name)
}

envKey := prefix + "_" + strings.ToUpper(tag)

switch fieldValue.Kind() {
case reflect.Ptr:
if !fieldValue.IsNil() {
err := overrideConfigWithEnv(fieldValue.Interface(), envKey)
if err != nil {
return err
}
}
case reflect.Struct:
err := overrideConfigWithEnv(fieldValue.Addr().Interface(), envKey)
if err != nil {
return err
}
default:
if envValue, exists := os.LookupEnv(envKey); exists {
err := setField(fieldValue, envValue)
log.Info("Overriding config with env var", "key", envKey)
if err != nil {
return err
}
}
}
}

return nil
}

// setField sets the value of a field based on the environment variable value
func setField(field reflect.Value, value string) error {
switch field.Kind() {
case reflect.String:
field.SetString(value)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
intValue, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return err
}
field.SetInt(intValue)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
uintValue, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return err
}
field.SetUint(uintValue)
case reflect.Float32, reflect.Float64:
floatValue, err := strconv.ParseFloat(value, 64)
if err != nil {
return err
}
field.SetFloat(floatValue)
case reflect.Bool:
boolValue, err := strconv.ParseBool(value)
if err != nil {
return err
}
field.SetBool(boolValue)
default:
return fmt.Errorf("unsupported type: %v", field.Kind())
}
return nil
}
2 changes: 1 addition & 1 deletion internal/utils/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"runtime/debug"
)

var tag = "v1.1.27"
var tag = "v1.1.28"

var commit = func() string {
if info, ok := debug.ReadBuildInfo(); ok {
Expand Down

0 comments on commit 5d5f457

Please sign in to comment.