Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
dba0cd229e
|
|||
ec4dba173f
|
@@ -7,6 +7,20 @@ set -o pipefail # Return value of a pipeline is the value of the last (rightmos
|
||||
IFS=$'\n\t' # Set $IFS to only newline and tab.
|
||||
|
||||
|
||||
function black() { echo -e "\x1B[30m $1 \x1B[0m"; }
|
||||
function red() { echo -e "\x1B[31m $1 \x1B[0m"; }
|
||||
function green() { echo -e "\x1B[32m $1 \x1B[0m"; }
|
||||
function yellow(){ echo -e "\x1B[33m $1 \x1B[0m"; }
|
||||
function blue() { echo -e "\x1B[34m $1 \x1B[0m"; }
|
||||
function purple(){ echo -e "\x1B[35m $1 \x1B[0m"; }
|
||||
function cyan() { echo -e "\x1B[36m $1 \x1B[0m"; }
|
||||
function white() { echo -e "\x1B[37m $1 \x1B[0m"; }
|
||||
|
||||
if [ "$( git rev-parse --abbrev-ref HEAD )" != "master" ]; then
|
||||
>&2 red "[ERROR] Can only create versions of <master>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
curr_vers=$(git describe --tags --abbrev=0 | sed 's/v//g')
|
||||
|
||||
next_ver=$(echo "$curr_vers" | awk -F. -v OFS=. 'NF==1{print ++$NF}; NF>1{if(length($NF+1)>length($NF))$(NF-1)++; $NF=sprintf("%0*d", length($NF), ($NF+1)%(10^length($NF))); print}')
|
||||
|
@@ -70,103 +70,114 @@ func processEnvOverrides(rval reflect.Value, delim string, prefix string) error
|
||||
continue
|
||||
}
|
||||
|
||||
if rvfield.Type() == reflect.TypeOf("") {
|
||||
if rvfield.Type().Kind() == reflect.Pointer {
|
||||
|
||||
rvfield.Set(reflect.ValueOf(envval))
|
||||
newval, err := parseEnvToValue(envval, fullEnvKey, rvfield.Type().Elem())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// converts reflect.Value to pointer
|
||||
ptrval := reflect.New(rvfield.Type().Elem())
|
||||
ptrval.Elem().Set(newval)
|
||||
|
||||
rvfield.Set(ptrval)
|
||||
|
||||
fmt.Printf("[CONF] Overwrite config '%s' with '%s'\n", fullEnvKey, envval)
|
||||
|
||||
} else if rvfield.Type() == reflect.TypeOf(int(0)) {
|
||||
|
||||
envint, err := strconv.ParseInt(envval, 10, bits.UintSize)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to int (value := '%s')", fullEnvKey, envval))
|
||||
}
|
||||
|
||||
rvfield.Set(reflect.ValueOf(int(envint)))
|
||||
|
||||
fmt.Printf("[CONF] Overwrite config '%s' with '%s'\n", fullEnvKey, envval)
|
||||
|
||||
} else if rvfield.Type() == reflect.TypeOf(int64(0)) {
|
||||
|
||||
envint, err := strconv.ParseInt(envval, 10, 64)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to int64 (value := '%s')", fullEnvKey, envval))
|
||||
}
|
||||
|
||||
rvfield.Set(reflect.ValueOf(int64(envint)))
|
||||
|
||||
fmt.Printf("[CONF] Overwrite config '%s' with '%s'\n", fullEnvKey, envval)
|
||||
|
||||
} else if rvfield.Type() == reflect.TypeOf(int32(0)) {
|
||||
|
||||
envint, err := strconv.ParseInt(envval, 10, 32)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to int32 (value := '%s')", fullEnvKey, envval))
|
||||
}
|
||||
|
||||
rvfield.Set(reflect.ValueOf(int32(envint)))
|
||||
|
||||
fmt.Printf("[CONF] Overwrite config '%s' with '%s'\n", fullEnvKey, envval)
|
||||
|
||||
} else if rvfield.Type() == reflect.TypeOf(int8(0)) {
|
||||
|
||||
envint, err := strconv.ParseInt(envval, 10, 8)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to int32 (value := '%s')", fullEnvKey, envval))
|
||||
}
|
||||
|
||||
rvfield.Set(reflect.ValueOf(int8(envint)))
|
||||
|
||||
fmt.Printf("[CONF] Overwrite config '%s' with '%s'\n", fullEnvKey, envval)
|
||||
|
||||
} else if rvfield.Type() == reflect.TypeOf(time.Duration(0)) {
|
||||
|
||||
dur, err := timeext.ParseDurationShortString(envval)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to duration (value := '%s')", fullEnvKey, envval))
|
||||
}
|
||||
|
||||
rvfield.Set(reflect.ValueOf(dur))
|
||||
|
||||
fmt.Printf("[CONF] Overwrite config '%s' with '%s'\n", fullEnvKey, dur.String())
|
||||
|
||||
} else if rvfield.Type() == reflect.TypeOf(time.UnixMilli(0)) {
|
||||
|
||||
tim, err := time.Parse(time.RFC3339Nano, envval)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to time.time (value := '%s')", fullEnvKey, envval))
|
||||
}
|
||||
|
||||
rvfield.Set(reflect.ValueOf(tim))
|
||||
|
||||
fmt.Printf("[CONF] Overwrite config '%s' with '%s'\n", fullEnvKey, tim.String())
|
||||
|
||||
} else if rvfield.Type().ConvertibleTo(reflect.TypeOf(int(0))) {
|
||||
|
||||
envint, err := strconv.ParseInt(envval, 10, 8)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to <%s, ,int> (value := '%s')", rvfield.Type().Name(), fullEnvKey, envval))
|
||||
}
|
||||
|
||||
envcvl := reflect.ValueOf(envint).Convert(rvfield.Type())
|
||||
|
||||
rvfield.Set(envcvl)
|
||||
|
||||
fmt.Printf("[CONF] Overwrite config '%s' with '%v'\n", fullEnvKey, envcvl.Interface())
|
||||
|
||||
} else if rvfield.Type().ConvertibleTo(reflect.TypeOf("")) {
|
||||
|
||||
envcvl := reflect.ValueOf(envval).Convert(rvfield.Type())
|
||||
|
||||
rvfield.Set(envcvl)
|
||||
|
||||
fmt.Printf("[CONF] Overwrite config '%s' with '%v'\n", fullEnvKey, envcvl.Interface())
|
||||
|
||||
} else {
|
||||
return errors.New(fmt.Sprintf("Unknown kind/type in config: [ %s | %s ]", rvfield.Kind().String(), rvfield.Type().String()))
|
||||
|
||||
newval, err := parseEnvToValue(envval, fullEnvKey, rvfield.Type())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rvfield.Set(newval)
|
||||
fmt.Printf("[CONF] Overwrite config '%s' with '%s'\n", fullEnvKey, envval)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseEnvToValue(envval string, fullEnvKey string, rvtype reflect.Type) (reflect.Value, error) {
|
||||
if rvtype == reflect.TypeOf("") {
|
||||
|
||||
return reflect.ValueOf(envval), nil
|
||||
|
||||
} else if rvtype == reflect.TypeOf(int(0)) {
|
||||
|
||||
envint, err := strconv.ParseInt(envval, 10, bits.UintSize)
|
||||
if err != nil {
|
||||
return reflect.Value{}, errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to int (value := '%s')", fullEnvKey, envval))
|
||||
}
|
||||
|
||||
return reflect.ValueOf(int(envint)), nil
|
||||
|
||||
} else if rvtype == reflect.TypeOf(int64(0)) {
|
||||
|
||||
envint, err := strconv.ParseInt(envval, 10, 64)
|
||||
if err != nil {
|
||||
return reflect.Value{}, errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to int64 (value := '%s')", fullEnvKey, envval))
|
||||
}
|
||||
|
||||
return reflect.ValueOf(int64(envint)), nil
|
||||
|
||||
} else if rvtype == reflect.TypeOf(int32(0)) {
|
||||
|
||||
envint, err := strconv.ParseInt(envval, 10, 32)
|
||||
if err != nil {
|
||||
return reflect.Value{}, errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to int32 (value := '%s')", fullEnvKey, envval))
|
||||
}
|
||||
|
||||
return reflect.ValueOf(int32(envint)), nil
|
||||
|
||||
} else if rvtype == reflect.TypeOf(int8(0)) {
|
||||
|
||||
envint, err := strconv.ParseInt(envval, 10, 8)
|
||||
if err != nil {
|
||||
return reflect.Value{}, errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to int32 (value := '%s')", fullEnvKey, envval))
|
||||
}
|
||||
|
||||
return reflect.ValueOf(int8(envint)), nil
|
||||
|
||||
} else if rvtype == reflect.TypeOf(time.Duration(0)) {
|
||||
|
||||
dur, err := timeext.ParseDurationShortString(envval)
|
||||
if err != nil {
|
||||
return reflect.Value{}, errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to duration (value := '%s')", fullEnvKey, envval))
|
||||
}
|
||||
|
||||
return reflect.ValueOf(dur), nil
|
||||
|
||||
} else if rvtype == reflect.TypeOf(time.UnixMilli(0)) {
|
||||
|
||||
tim, err := time.Parse(time.RFC3339Nano, envval)
|
||||
if err != nil {
|
||||
return reflect.Value{}, errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to time.time (value := '%s')", fullEnvKey, envval))
|
||||
}
|
||||
|
||||
return reflect.ValueOf(tim), nil
|
||||
|
||||
} else if rvtype.ConvertibleTo(reflect.TypeOf(int(0))) {
|
||||
|
||||
envint, err := strconv.ParseInt(envval, 10, 8)
|
||||
if err != nil {
|
||||
return reflect.Value{}, errors.New(fmt.Sprintf("Failed to parse env-config variable '%s' to <%s, ,int> (value := '%s')", rvtype.Name(), fullEnvKey, envval))
|
||||
}
|
||||
|
||||
envcvl := reflect.ValueOf(envint).Convert(rvtype)
|
||||
|
||||
return envcvl, nil
|
||||
|
||||
} else if rvtype.ConvertibleTo(reflect.TypeOf("")) {
|
||||
|
||||
envcvl := reflect.ValueOf(envval).Convert(rvtype)
|
||||
return envcvl, nil
|
||||
|
||||
} else {
|
||||
return reflect.Value{}, errors.New(fmt.Sprintf("Unknown kind/type in config: [ %s | %s ]", rvtype.Kind().String(), rvtype.String()))
|
||||
}
|
||||
}
|
||||
|
@@ -213,8 +213,65 @@ func TestApplyEnvOverridesRecursive(t *testing.T) {
|
||||
assertEqual(t, data.Sub4.V9, time.Unix(2335219200, 0).UTC())
|
||||
}
|
||||
|
||||
func TestApplyEnvOverridesPointer(t *testing.T) {
|
||||
|
||||
type aliasint int
|
||||
type aliasstring string
|
||||
|
||||
type testdata struct {
|
||||
V1 *int `env:"TEST_V1"`
|
||||
VX *string ``
|
||||
V2 *string `env:"TEST_V2"`
|
||||
V3 *int8 `env:"TEST_V3"`
|
||||
V4 *int32 `env:"TEST_V4"`
|
||||
V5 *int64 `env:"TEST_V5"`
|
||||
V6 *aliasint `env:"TEST_V6"`
|
||||
VY *aliasint ``
|
||||
V7 *aliasstring `env:"TEST_V7"`
|
||||
V8 *time.Duration `env:"TEST_V8"`
|
||||
V9 *time.Time `env:"TEST_V9"`
|
||||
}
|
||||
|
||||
data := testdata{}
|
||||
|
||||
t.Setenv("TEST_V1", "846")
|
||||
t.Setenv("TEST_V2", "hello_world")
|
||||
t.Setenv("TEST_V3", "6")
|
||||
t.Setenv("TEST_V4", "333")
|
||||
t.Setenv("TEST_V5", "-937")
|
||||
t.Setenv("TEST_V6", "070")
|
||||
t.Setenv("TEST_V7", "AAAAAA")
|
||||
t.Setenv("TEST_V8", "1min4s")
|
||||
t.Setenv("TEST_V9", "2009-11-10T23:00:00Z")
|
||||
|
||||
err := ApplyEnvOverrides(&data, ".")
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
assertPtrEqual(t, data.V1, 846)
|
||||
assertPtrEqual(t, data.V2, "hello_world")
|
||||
assertPtrEqual(t, data.V3, 6)
|
||||
assertPtrEqual(t, data.V4, 333)
|
||||
assertPtrEqual(t, data.V5, -937)
|
||||
assertPtrEqual(t, data.V6, 70)
|
||||
assertPtrEqual(t, data.V7, "AAAAAA")
|
||||
assertPtrEqual(t, data.V8, time.Second*64)
|
||||
assertPtrEqual(t, data.V9, time.Unix(1257894000, 0).UTC())
|
||||
}
|
||||
|
||||
func assertEqual[T comparable](t *testing.T, actual T, expected T) {
|
||||
if actual != expected {
|
||||
t.Errorf("values differ: Actual: '%v', Expected: '%v'", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func assertPtrEqual[T comparable](t *testing.T, actual *T, expected T) {
|
||||
if actual == nil {
|
||||
t.Errorf("values differ: Actual: NIL, Expected: '%v'", expected)
|
||||
}
|
||||
if *actual != expected {
|
||||
t.Errorf("values differ: Actual: '%v', Expected: '%v'", actual, expected)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user