Skip to content
Snippets Groups Projects
Verified Commit a28e2242 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

feat implements proxy interface #2

parent 2f3ee8a9
No related branches found
No related tags found
No related merge requests found
......@@ -146,14 +146,16 @@ The function `Execute()` executes the command. See the section
setting.Execute()
```
### Shadow
### Proxy
The shadow structure is used to copy the values of the flags to the
shadow structure. The shadow structure is set using the `SetShadow()`
and configured using the tag `shadow`.
The proxy structure is used to copy the values of the flags to the
proxy structure. The proxy structure is used to access the values of the
flags.
The proxy structure must implement the `Proxy` interface.
```go
type Shadow struct {
type MyObj struct {
Verbose bool
Serve struct {
Host string
......@@ -161,12 +163,14 @@ type Shadow struct {
}
}
func (m *MyObj) Copy(_ map[string]any) {
}
func main() {
setting := New(os.Args[0], Definition{})
setting.SetShadow(Shadow{})
setting.SetProxy(&MyObj{})
setting.Parse(os.Args[1:])
setting.Execute()
fmt.Printf("Shadow: %+v", setting.GetShadow())
}
```
......
......@@ -12,18 +12,22 @@ import (
"reflect"
)
// ExecuteWithShadow executes the command line arguments and calls the functions.
func ExecuteWithShadow[C any, D Copyable[D]](cmd C, cnf D) *Settings[C] {
return execute(cmd, cnf, os.Args[0], os.Args[1:])
}
type noShadow struct{}
type dummyCopyArg struct{}
func (n noShadow) Copy(a noShadow) {}
func (n dummyCopyArg) Copy(_ map[string]any) {}
// Execute executes the command line arguments and calls the functions.
func Execute[C any](cmd C) *Settings[C] {
return execute(cmd, noShadow{}, os.Args[0], os.Args[1:])
func Execute[C any](cmd C, cpy ...Proxy) *Settings[C] {
if cpy == nil {
return execute(cmd, dummyCopyArg{}, os.Args[0], os.Args[1:])
}
if len(cpy) > 1 {
panic("too many arguments")
}
return execute(cmd, cpy[0], os.Args[0], os.Args[1:])
}
// PrintFlagOutput prints the flag output to the standard output.
......@@ -36,15 +40,15 @@ func (s *Settings[C]) GetFlagOutput() {
fmt.Println(s.command.flagSet.Output())
}
// execute is the internal implementation of ExecuteWithShadow.
func execute[C any, D Copyable[D]](cmd C, cnf D, name string, args []string) *Settings[C] {
// execute is the internal implementation of Execute.
func execute[C any, D Proxy](cmd C, proxy D, name string, args []string) *Settings[C] {
instance := New(name, cmd)
if instance.HasErrors() {
return instance
}
if (reflect.ValueOf(&cnf).Elem().Type() != reflect.TypeOf(noShadow{})) {
instance.SetShadow(cnf)
if (reflect.ValueOf(&proxy).Elem().Type() != reflect.TypeOf(dummyCopyArg{})) {
instance.SetProxy(proxy)
if instance.HasErrors() {
return instance
}
......@@ -59,10 +63,6 @@ func execute[C any, D Copyable[D]](cmd C, cnf D, name string, args []string) *Se
return instance
}
if instance.shadow != nil {
cnf.Copy(instance.shadow.(D))
}
instance.Execute()
if instance.HasErrors() {
return instance
......@@ -87,6 +87,8 @@ func New[C any](name string, definitions C) *Settings[C] {
return s
}
s.mapping = make(map[string]any)
buf := bytes.NewBufferString("")
s.flagOutput = io.Writer(buf)
s.definitions = definitions
......
......@@ -25,7 +25,7 @@ func TestUsage(t *testing.T) {
type TestDataStruct struct {
}
func (s *TestDataStruct) Copy(x *TestDataStruct) {
func (s *TestDataStruct) Copy(_ map[string]any) {
}
......@@ -44,8 +44,7 @@ func TestExecuteTypeStringIsNotSupported(t *testing.T) {
func TestExecuteHelp(t *testing.T) {
instance := execute(CmdTest1{}, &TestDataStruct{}, "test", []string{"-h"})
assert.False(t, instance.HasErrors())
assert.True(t, instance.HelpRequested())
}
func TestNewIntWithError(t *testing.T) {
......
......@@ -12,7 +12,6 @@ type cmd[C any] struct {
name string
flagSet *flag.FlagSet
tagMapping map[string]string
shadowMapping map[string]string
commands []*cmd[C]
settings *Settings[C]
valuePath []string
......@@ -61,7 +60,6 @@ func buildCommandStruct[C any](s *Settings[C], name, fkt string, errorHandling f
commands: []*cmd[C]{},
settings: s,
tagMapping: map[string]string{},
shadowMapping: map[string]string{},
valuePath: path,
functionName: fkt,
}
......@@ -157,15 +155,8 @@ func (c *cmd[C]) parseStruct(dta any) {
if m[tagLong] != "" {
c.tagMapping[m[tagLong]] = v.Type().Field(i).Name
}
if m[tagShadow] != "" {
c.shadowMapping[v.Type().Field(i).Name] = m[tagShadow]
}
c.initFlags(x, m)
} else if m[tagCommand] != "" {
//c.valuePath = append(c.valuePath, )
c.tagMapping[m[tagCommand]] = v.Type().Field(i).Name
c.initCommands(x, m, v.Type().Field(i).Name)
......
......@@ -126,3 +126,9 @@ type MissingFunctionError error
func newMissingFunctionError(missing string) MissingFunctionError {
return MissingFunctionError(errors.New("missing function " + missing))
}
type InvalidTypeForPathError error
func newInvalidTypeForPathError(path string, pt string, nt string) InvalidTypeForPathError {
return InvalidTypeForPathError(errors.New("invalid type for path " + path + ": expected " + pt + ", got " + nt))
}
......@@ -96,3 +96,9 @@ func TestMissingFunctionError(t *testing.T) {
_, ok := err.(MissingFunctionError)
assert.True(t, ok)
}
func TestInvalidTypeForPathError(t *testing.T) {
err := newInvalidTypeForPathError("test", "test", "test")
_, ok := err.(InvalidTypeForPathError)
assert.True(t, ok)
}
......@@ -6,8 +6,10 @@ package xflags
import (
"flag"
"fmt"
"github.com/stretchr/testify/assert"
"reflect"
"strings"
"testing"
)
func (s *Settings[C]) Execute() *Settings[C] {
......@@ -31,7 +33,6 @@ func (s *Settings[C]) Execute() *Settings[C] {
func callCmdFunctions[C any](settings *Settings[C], commands []*cmd[C]) bool {
//result := false
wasExecuted := false
shouldExecute := false
......@@ -117,3 +118,33 @@ func (s *Settings[C]) MissingCommand() bool {
func (s *Settings[C]) WasExecuted() bool {
return s.wasExecuted
}
func TestWrongDefinitionType(t *testing.T) {
c := New("root", 2)
c.Parse([]string{"test"})
c.Execute()
assert.True(t, c.HasErrors())
}
type testExecuteCommandStruct struct {
Command1 struct {
} `command:"command1" description:"Command 1" callback:"command1Callback" `
Command2 struct {
Command3 struct {
} `command:"command3" description:"Command 3" callback:"command3Callback" call:"DoCmd3"`
} `command:"command2" description:"Command 2" callback:"command2Callback" `
}
func (c *testExecuteCommandStruct) DoCmd3(s *Settings[testExecuteCommandStruct]) {
}
func (c *testExecuteCommandStruct) command1Callback(args []string) {
fmt.Println("command1Callback", args)
}
func TestExecute1(t *testing.T) {
c := New("root", testExecuteCommandStruct{})
c.Parse([]string{"command2", "command3", "commandX"})
c.Execute()
assert.False(t, c.HasErrors())
}
// Copyright 2022 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0
package xflags
// Copyright 2022 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0
package xflags
import (
"fmt"
"github.com/stretchr/testify/assert"
"testing"
)
func TestWrongDefinitionType(t *testing.T) {
c := New("root", 2)
c.Parse([]string{"test"})
c.Execute()
assert.True(t, c.HasErrors())
}
type testExecuteCommandStruct struct {
Command1 struct {
} `command:"command1" description:"Command 1" callback:"command1Callback" `
Command2 struct {
Command3 struct {
} `command:"command3" description:"Command 3" callback:"command3Callback" call:"DoCmd3"`
} `command:"command2" description:"Command 2" callback:"command2Callback" `
}
func (c *testExecuteCommandStruct) DoCmd3(s *Settings[testExecuteCommandStruct]) {
}
func (c *testExecuteCommandStruct) command1Callback(args []string) {
fmt.Println("command1Callback", args)
}
func TestExecute1(t *testing.T) {
c := New("root", testExecuteCommandStruct{})
c.Parse([]string{"command2", "command3", "commandX"})
c.Execute()
assert.False(t, c.HasErrors())
}
......@@ -60,7 +60,7 @@ func TestIssue1TestCallCMD4(tp *testing.T) {
for i, tt := range testData {
tp.Run(strconv.Itoa(i)+":"+strings.Join(tt.args, ","), func(t *testing.T) {
s := execute(testCmdStructIssue1{}, noShadow{}, "test", tt.args)
s := execute(testCmdStructIssue1{}, dummyCopyArg{}, "test", tt.args)
assert.Equal(t, tt.hasErrors, s.HasErrors())
assert.Equal(t, tt.hasHint, s.HasHint())
......@@ -75,27 +75,27 @@ func TestIssue1TestCallCMD4(tp *testing.T) {
}
func TestIssue1TestNoCallback(t *testing.T) {
s := execute(testCmdStructIssue1{}, noShadow{}, "test", []string{"cmd1", "cmd6", "cmd7"})
s := execute(testCmdStructIssue1{}, dummyCopyArg{}, "test", []string{"cmd1", "cmd6", "cmd7"})
assert.Equal(t, 3, len(s.Errors()))
assert.False(t, s.WasExecuted())
}
func TestIssue1TestToMuchCommands(t *testing.T) {
s := execute(testCmdStructIssue1{}, noShadow{}, "test", []string{"cmd1", "cmd9"})
s := execute(testCmdStructIssue1{}, dummyCopyArg{}, "test", []string{"cmd1", "cmd9"})
assert.True(t, s.MissingCommand())
assert.False(t, s.WasExecuted())
}
// here it is tested whether the last and defined callback is called
func TestIssue1TestCallCMD3(t *testing.T) {
s := execute(testCmdStructIssue1{}, noShadow{}, "test", []string{"cmd1", "cmd2", "cmd3"})
s := execute(testCmdStructIssue1{}, dummyCopyArg{}, "test", []string{"cmd1", "cmd2", "cmd3"})
assert.Equal(t, 0, len(s.Errors()))
assert.True(t, s.WasExecuted())
}
// NoShadow is an internal Struct for testing
func TestIssue1MessageWithNoShadow(t *testing.T) {
s := execute(testCmdStructIssue1{}, noShadow{}, "test", []string{"cmd1", "cmd2", "cmd3", "-v3"})
s := execute(testCmdStructIssue1{}, dummyCopyArg{}, "test", []string{"cmd1", "cmd2", "cmd3", "-v3"})
assert.Equal(t, 0, len(s.Errors()))
}
......@@ -139,7 +139,7 @@ func TestIssue1Summary(tp *testing.T) {
for _, tt := range data {
tp.Run(tt.args[0], func(t *testing.T) {
s := execute(testCmdStructIssue1{}, noShadow{}, "test", tt.args)
s := execute(testCmdStructIssue1{}, dummyCopyArg{}, "test", tt.args)
assert.Equal(t, tt.helpRequested, s.HelpRequested())
assert.Equal(t, tt.wasExecuted, s.WasExecuted())
assert.Equal(t, tt.missingCommand, s.MissingCommand())
......
......@@ -9,25 +9,26 @@ import (
"strings"
)
// SetShadow sets the shadow struct for the flag configuration.
func (s *Settings[C]) SetShadow(shadow any) *Settings[C] {
// SetProxy sets the shadow struct for the flag configuration.
func (s *Settings[C]) SetProxy(proxy Proxy) *Settings[C] {
if reflect.TypeOf(shadow).Kind() != reflect.Ptr {
if reflect.TypeOf(proxy).Kind() != reflect.Ptr {
s.errors = append(s.errors, ShadowMustBePointerError)
return s
}
if reflect.TypeOf(shadow).Elem().Kind() != reflect.Struct {
if reflect.TypeOf(proxy).Elem().Kind() != reflect.Struct {
s.errors = append(s.errors, ShadowMustBePointerError)
return s
}
s.shadow = shadow
s.proxy = proxy
return s
}
type Copyable[C any] interface {
Copy(data C)
// Proxy is the interface for the proxy struct.
type Proxy interface {
Copy(map[string]any)
}
func (s *Settings[C]) assignValues(c cmd[C]) {
......@@ -46,33 +47,15 @@ func (s *Settings[C]) assignValues(c cmd[C]) {
pa := append(c.valuePath, k)
p := strings.Join(pa, ".")
err := setValueUsingPath(&s.definitions, p, value)
err := SetValueUsingPath(&s.definitions, p, value)
if err != nil {
s.errors = append(s.errors, err)
}
err = c.setShadowValue(s.shadow, k, value)
if err != nil {
s.errors = append(s.errors, err)
}
s.mapping[p] = value
return
})
}
func (c cmd[C]) setShadowValue(obj any, k string, value string) error {
if obj == nil {
return nil
}
// set shadow
n, ok := c.shadowMapping[k]
if !ok {
return nil
}
return setValueUsingPath(obj, n, value)
}
......@@ -20,13 +20,6 @@ type ConfigStruct6 struct {
ValSub ConfigStruct6Sub1
}
func TestFlagSetShadowError(t *testing.T) {
settings := New("test", testExecutionStruct{})
settings.SetShadow(3)
assert.True(t, settings.HasErrors())
}
func TestFlagCopyToShadow(t *testing.T) {
c := ConfigStruct6{}
......@@ -35,7 +28,7 @@ func TestFlagCopyToShadow(t *testing.T) {
settings := New("test", testExecutionStruct{})
assert.NotNil(t, settings)
settings.SetShadow(&c)
settings.SetProxy(&c)
assert.False(t, settings.HasErrors())
settings.Parse([]string{"-a", "command1", "-d"})
......@@ -45,8 +38,9 @@ func TestFlagCopyToShadow(t *testing.T) {
}
func (s *ConfigStruct6) Copy(p *ConfigStruct6) {
func (s *ConfigStruct6) Copy(m map[string]any) {
SetValueUsingPath(s, "ValGlobal1", (m["Global1"]))
SetValueUsingPath(s, "ValCommand1Flag2", (m["Command1.Command1Flag2"]))
}
func TestCopyable(t *testing.T) {
......
......@@ -38,5 +38,9 @@ func (s *Settings[C]) Parse(args []string) *Settings[C] {
s.command.parse(r)
if s.mapping != nil && s.proxy != nil {
s.proxy.Copy(s.mapping)
}
return s
}
......@@ -4,13 +4,14 @@
package xflags
import (
"fmt"
"reflect"
"strconv"
"strings"
)
// This function returns the value of a field in a struct, given a path to the field.
func getValueFrom[D any](obj D, keyWithDots string) (interface{}, error) {
func GetValueFrom[D any](obj D, keyWithDots string) (any, error) {
keySlice := strings.Split(keyWithDots, ".")
v := reflect.ValueOf(obj)
......@@ -49,7 +50,7 @@ func getValueFrom[D any](obj D, keyWithDots string) (interface{}, error) {
}
// This function sets the value of a field in a struct, given a path to the field.
func setValueUsingPath[D any](obj D, keyWithDots string, newValue string) error {
func SetValueUsingPath[D any](obj D, keyWithDots string, newValue any) error {
keySlice := strings.Split(keyWithDots, ".")
v := reflect.ValueOf(obj)
......@@ -94,29 +95,83 @@ func setValueUsingPath[D any](obj D, keyWithDots string, newValue string) error
return newCannotSetError(keyWithDots)
}
switch v.Kind() {
case reflect.Ptr:
if newValue == nil {
v.Set(reflect.Zero(v.Type()))
} else {
v.Set(reflect.ValueOf(&newValue))
}
return nil
}
newValueType := reflect.TypeOf(newValue)
if newValueType == nil {
return newUnsupportedTypePathError(keyWithDots, v.Type())
}
newValueKind := reflect.TypeOf(newValue).Kind()
switch v.Kind() {
case reflect.String:
v.SetString(newValue)
case reflect.Int:
if newValueKind == reflect.String {
v.SetString(newValue.(string))
} else {
v.SetString(fmt.Sprintf("%v", newValue))
}
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
if newValueKind == reflect.Int {
v.SetInt(int64(newValue.(int)))
} else {
s, err := strconv.ParseInt(newValue.(string), 10, 64)
if err != nil {
return err
}
v.SetInt(s)
}
s, err := strconv.Atoi(newValue)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
if newValueKind == reflect.Int {
v.SetUint(uint64(newValue.(int)))
} else {
s, err := strconv.ParseInt(newValue.(string), 10, 64)
if err != nil {
return err
}
v.SetUint(uint64(s))
}
v.SetInt(int64(s))
case reflect.Bool:
v.SetBool(newValue == "true")
case reflect.Float64:
s, err := strconv.ParseFloat(newValue, 64)
if newValueKind == reflect.Bool {
v.SetBool(newValue.(bool))
} else {
b, err := strconv.ParseBool(newValue.(string))
if err != nil {
return err
}
v.SetBool(b)
}
case reflect.Float64, reflect.Float32:
if newValueKind == reflect.Float64 {
v.SetFloat(newValue.(float64))
} else {
s, err := strconv.ParseFloat(newValue.(string), 64)
if err != nil {
return err
}
v.SetFloat(s)
}
default:
return newUnsupportedTypeAtTopOfPathError(keyWithDots, v.Type())
return newInvalidTypeForPathError(keyWithDots, v.Type().String(), newValueKind.String())
}
return nil
......
......@@ -32,7 +32,7 @@ func TestPathFindError(t *testing.T) {
s := PathfindTestStruct1{}
_, err := getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.XX")
_, err := GetValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.XX")
if err == nil {
t.Error("err == nil")
}
......@@ -58,7 +58,7 @@ func TestPathFindSetValueString(t *testing.T) {
for k, v := range testData {
s := &PathfindTestStruct1{}
err := setValueUsingPath[*PathfindTestStruct1](s, k, v)
err := SetValueUsingPath[*PathfindTestStruct1](s, k, v)
if err != nil {
t.Error(err)
}
......@@ -74,7 +74,7 @@ func TestPathFindGetValueFrom(t *testing.T) {
s.Sub1.Bs = "3"
s.Sub1.Bf = 4.0
v, err := getValueFrom[PathfindTestStruct1](s, "Sub1.B")
v, err := GetValueFrom[PathfindTestStruct1](s, "Sub1.B")
if err != nil {
t.Error(err)
}
......@@ -83,7 +83,7 @@ func TestPathFindGetValueFrom(t *testing.T) {
t.Error("v != true")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Bi")
v, err = GetValueFrom[PathfindTestStruct1](s, "Sub1.Bi")
if err != nil {
t.Error(err)
}
......@@ -92,7 +92,7 @@ func TestPathFindGetValueFrom(t *testing.T) {
t.Error("v != 2")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Bs")
v, err = GetValueFrom[PathfindTestStruct1](s, "Sub1.Bs")
if err != nil {
t.Error(err)
}
......@@ -101,7 +101,7 @@ func TestPathFindGetValueFrom(t *testing.T) {
t.Error("v != 3")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Bf")
v, err = GetValueFrom[PathfindTestStruct1](s, "Sub1.Bf")
if err != nil {
t.Error(err)
}
......@@ -115,7 +115,7 @@ func TestPathFindGetValueFrom(t *testing.T) {
s.Sub1.Sub2.Cs = "3"
s.Sub1.Sub2.Cf = 4.0
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.C")
v, err = GetValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.C")
if err != nil {
t.Error(err)
}
......@@ -124,7 +124,7 @@ func TestPathFindGetValueFrom(t *testing.T) {
t.Error("v != true")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Ci")
v, err = GetValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Ci")
if err != nil {
t.Error(err)
}
......@@ -133,7 +133,7 @@ func TestPathFindGetValueFrom(t *testing.T) {
t.Error("v != 2")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Cs")
v, err = GetValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Cs")
if err != nil {
t.Error(err)
}
......@@ -142,7 +142,7 @@ func TestPathFindGetValueFrom(t *testing.T) {
t.Error("v != 3")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Cf")
v, err = GetValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Cf")
if err != nil {
t.Error(err)
}
......@@ -156,7 +156,7 @@ func TestPathFindGetValueFrom(t *testing.T) {
s.Sub1.Sub2.Sub3.Ds = "3"
s.Sub1.Sub2.Sub3.Df = 4.0
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.D")
v, err = GetValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.D")
if err != nil {
t.Error(err)
......@@ -166,7 +166,7 @@ func TestPathFindGetValueFrom(t *testing.T) {
t.Error("v != true")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Di")
v, err = GetValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Di")
if err != nil {
t.Error(err)
}
......@@ -175,7 +175,7 @@ func TestPathFindGetValueFrom(t *testing.T) {
t.Error("v != 2")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Ds")
v, err = GetValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Ds")
if err != nil {
t.Error(err)
}
......@@ -184,7 +184,7 @@ func TestPathFindGetValueFrom(t *testing.T) {
t.Error("v != 3")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Df")
v, err = GetValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Df")
if err != nil {
t.Error(err)
}
......@@ -198,10 +198,10 @@ func TestPathFindGetValueFrom(t *testing.T) {
func TestPathFindSetValueFrom(t *testing.T) {
s := &PathfindTestStruct1{}
setValueUsingPath[*PathfindTestStruct1](s, "Sub1.B", "true")
setValueUsingPath[*PathfindTestStruct1](s, "Sub1.Bi", "2")
setValueUsingPath[*PathfindTestStruct1](s, "Sub1.Bs", "3")
setValueUsingPath[*PathfindTestStruct1](s, "Sub1.Bf", "4.0")
SetValueUsingPath[*PathfindTestStruct1](s, "Sub1.B", "true")
SetValueUsingPath[*PathfindTestStruct1](s, "Sub1.Bi", "2")
SetValueUsingPath[*PathfindTestStruct1](s, "Sub1.Bs", "3")
SetValueUsingPath[*PathfindTestStruct1](s, "Sub1.Bf", "4.0")
if s.Sub1.B != true {
t.Error("s.Sub1.B != true")
......@@ -220,10 +220,10 @@ func TestPathFindSetValueFrom(t *testing.T) {
t.Error("s.Sub1.Bf != 4.0")
}
setValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.C", "true")
setValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Ci", "2")
setValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Cs", "3")
setValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Cf", "4.0")
SetValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.C", "true")
SetValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Ci", "2")
SetValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Cs", "3")
SetValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Cf", "4.0")
if s.Sub1.Sub2.C != true {
t.Error("s.Sub1.Sub2.C != true")
......@@ -250,10 +250,10 @@ func TestPathFindSetValueFrom(t *testing.T) {
}
setValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.D", "true")
setValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Di", "2")
setValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Ds", "3")
setValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Df", "4.0")
SetValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.D", "true")
SetValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Di", "2")
SetValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Ds", "3")
SetValueUsingPath[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Df", "4.0")
if s.Sub1.Sub2.Sub3.D != true {
t.Error("s.Sub1.Sub2.Sub3.D != true")
......
......@@ -25,6 +25,13 @@ func TestReadMeInit(t *testing.T) {
setting.Parse([]string{"-v", "serve", "-h", "localhost", "-p", "8080"})
setting.Execute()
assert.True(t, setting.definitions.Verbose)
if setting.HasErrors() {
for _, err := range setting.Errors() {
t.Log(err)
}
}
assert.False(t, setting.HasErrors())
}
......
......@@ -17,6 +17,7 @@ type config struct {
errorHandling flag.ErrorHandling
}
// Settings[C] is the main struct for the xflags package.
type Settings[C any] struct {
definitions C
......@@ -29,7 +30,8 @@ type Settings[C any] struct {
config config
shadow any
mapping map[string]any
proxy Proxy
wasExecuted bool
hint string
......
......@@ -15,7 +15,6 @@ const (
tagShort = "short"
tagLong = "long"
tagDescription = "description"
tagShadow = "shadow"
)
func getTagMap(field reflect.StructField) (value map[string]string) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment