refactor: keep only one struct for package
This commit is contained in:
@ -22,6 +22,8 @@ package decoder
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
@ -52,7 +54,7 @@ type InvalidTypeError struct {
|
||||
}
|
||||
|
||||
func (ite InvalidTypeError) Error() string {
|
||||
return "variable '" + ite.name + "' is of type " + ite.vartype + ", but " + ite.exptype + " is expected"
|
||||
return fmt.Sprintf("variable '%s' is of type %s, but %s is expected", ite.name, ite.vartype, ite.exptype)
|
||||
}
|
||||
|
||||
// Decoder provides methods for decoding variable values
|
||||
@ -80,10 +82,58 @@ func (d *Decoder) DecodeVar(name string, val any) error {
|
||||
|
||||
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
||||
WeaklyTypedInput: true,
|
||||
Result: val,
|
||||
TagName: "sh",
|
||||
DecodeHook: mapstructure.DecodeHookFuncValue(func(from, to reflect.Value) (interface{}, error) {
|
||||
if strings.Contains(to.Type().String(), "alrsh.OverridableField") {
|
||||
if to.Kind() != reflect.Ptr && to.CanAddr() {
|
||||
to = to.Addr()
|
||||
}
|
||||
|
||||
names, err := overrides.Resolve(d.info, overrides.DefaultOpts.WithName(name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
isNotSet := true
|
||||
|
||||
setMethod := to.MethodByName("Set")
|
||||
setResolvedMethod := to.MethodByName("SetResolved")
|
||||
|
||||
for _, varName := range names {
|
||||
val := d.getVarNoOverrides(varName)
|
||||
if val == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
t := setMethod.Type().In(1)
|
||||
|
||||
newVal := from
|
||||
|
||||
if !newVal.Type().AssignableTo(t) {
|
||||
newVal = reflect.New(t)
|
||||
err = d.DecodeVar(name, newVal.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newVal = newVal.Elem()
|
||||
}
|
||||
|
||||
if isNotSet {
|
||||
setResolvedMethod.Call([]reflect.Value{newVal})
|
||||
}
|
||||
|
||||
override := strings.TrimPrefix(strings.TrimPrefix(varName, name), "_")
|
||||
setMethod.Call([]reflect.Value{reflect.ValueOf(override), newVal})
|
||||
}
|
||||
|
||||
return to, nil
|
||||
}
|
||||
return from.Interface(), nil
|
||||
}),
|
||||
Result: val,
|
||||
TagName: "sh",
|
||||
})
|
||||
if err != nil {
|
||||
slog.Warn("err", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -243,23 +293,31 @@ func (d *Decoder) getVar(name string) *expand.Variable {
|
||||
}
|
||||
|
||||
for _, varName := range names {
|
||||
val, ok := d.Runner.Vars[varName]
|
||||
if ok {
|
||||
// Resolve nameref variables
|
||||
_, resolved := val.Resolve(expand.FuncEnviron(func(s string) string {
|
||||
if val, ok := d.Runner.Vars[s]; ok {
|
||||
return val.String()
|
||||
}
|
||||
return ""
|
||||
}))
|
||||
val = resolved
|
||||
|
||||
return &val
|
||||
res := d.getVarNoOverrides(varName)
|
||||
if res != nil {
|
||||
return res
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) getVarNoOverrides(name string) *expand.Variable {
|
||||
val, ok := d.Runner.Vars[name]
|
||||
if ok {
|
||||
// Resolve nameref variables
|
||||
_, resolved := val.Resolve(expand.FuncEnviron(func(s string) string {
|
||||
if val, ok := d.Runner.Vars[s]; ok {
|
||||
return val.String()
|
||||
}
|
||||
return ""
|
||||
}))
|
||||
val = resolved
|
||||
|
||||
return &val
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func IsTruthy(value string) bool {
|
||||
value = strings.ToLower(strings.TrimSpace(value))
|
||||
return value == "true" || value == "yes" || value == "1"
|
||||
|
Reference in New Issue
Block a user