diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..13566b81b018ad684f3a35fee301741b2734c8f4 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/markdown.xml b/.idea/markdown.xml new file mode 100644 index 0000000000000000000000000000000000000000..ec0b30fa7ea2824af6923493653e32595b0907a8 --- /dev/null +++ b/.idea/markdown.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="MarkdownSettings"> + <enabledExtensions> + <entry key="MermaidLanguageExtension" value="false" /> + <entry key="PlantUMLLanguageExtension" value="true" /> + </enabledExtensions> + </component> +</project> \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000000000000000000000000000000000000..639900d13c6182e452e33a3bd638e70a0146c785 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectRootManager"> + <output url="file://$PROJECT_DIR$/out" /> + </component> +</project> \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000000000000000000000000000000000000..4a09e5cc182bc2a952f8696404b3ab97bc42b353 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea/xflags.iml" filepath="$PROJECT_DIR$/.idea/xflags.iml" /> + </modules> + </component> +</project> \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="VcsDirectoryMappings"> + <mapping directory="" vcs="Git" /> + </component> +</project> \ No newline at end of file diff --git a/.idea/xflags.iml b/.idea/xflags.iml new file mode 100644 index 0000000000000000000000000000000000000000..25ed3f6e7b6e344b6ca91ebcc5d005f35357f9cf --- /dev/null +++ b/.idea/xflags.iml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="Go" enabled="true" /> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$" /> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module> \ No newline at end of file diff --git a/execute.go b/execute.go index 06b96d42e891fc88f7b0ebf290a4b30447ba0fb3..68a06c612477211264501f11003dc5901308f6fd 100644 --- a/execute.go +++ b/execute.go @@ -80,10 +80,9 @@ func callCmdFunctions[C any](settings *Settings[C], commands []*cmd[C]) bool { if settings.hint == "" { settings.hint = fmt.Sprintf("Did you mean: %v?", strings.Join(availableCommands, ", ")) } + settings.errors = append(settings.errors, MissingCommandError) } - settings.errors = append(settings.errors, MissingCommandError) - return false } diff --git a/hint.go b/hint.go index 3b4f870cc8080085889fa98312b2055c22c99c5c..8586d2033980a9330987a340141bcc45837e19ce 100644 --- a/hint.go +++ b/hint.go @@ -1,3 +1,6 @@ +// Copyright 2023 schukai GmbH +// SPDX-License-Identifier: AGPL-3.0 + package xflags func (s *Settings[C]) SetHint(hint string) *Settings[C] { diff --git a/mapping.go b/mapping.go index 19a0b66771c6c7947fc10bb2dcc5dc980a2fa7bd..f4f04381876bac98e0df65bbd0a6eaf03b34ffb3 100644 --- a/mapping.go +++ b/mapping.go @@ -7,6 +7,7 @@ import ( "flag" "gitlab.schukai.com/oss/libraries/go/utilities/pathfinder" "reflect" + "strconv" "strings" ) @@ -37,7 +38,7 @@ func (s *Settings[C]) assignValues(c cmd[C]) { flgs.Visit(func(f *flag.Flag) { name := f.Name - value := f.Value.String() + stringValue := f.Value.String() k, ok := c.tagMapping[name] if !ok { @@ -55,10 +56,48 @@ func (s *Settings[C]) assignValues(c cmd[C]) { } if q == nil { - q = reflect.New(reflect.TypeOf(q).Elem()).Interface() + s.errors = append(s.errors, newUnknownFlagError(name)) + return } - err = pathfinder.SetValue(&s.definitions, p, value) + typeOf := reflect.TypeOf(q) + + switch typeOf.Kind() { + case reflect.String: + err = pathfinder.SetValue(&s.definitions, p, stringValue) + case reflect.Int: + intVar, err := strconv.Atoi(stringValue) + if err != nil { + s.errors = append(s.errors, err) + return + } + err = pathfinder.SetValue(&s.definitions, p, intVar) + case reflect.Bool: + boolVar, err := strconv.ParseBool(stringValue) + if err != nil { + s.errors = append(s.errors, err) + return + } + err = pathfinder.SetValue(&s.definitions, p, boolVar) + case reflect.Slice: + + switch typeOf.Elem().Kind() { + case reflect.String: + qs := q.(StringFlags) + stringSliceValue := f.Value.(*StringFlags) + for _, v := range *stringSliceValue { + err = qs.Set(v) + if err != nil { + s.errors = append(s.errors, err) + return + } + } + err = pathfinder.SetValue(&s.definitions, p, qs) + default: + err = pathfinder.SetValue(&s.definitions, p, stringValue) + } + + } if err != nil { s.errors = append(s.errors, err) @@ -66,7 +105,7 @@ func (s *Settings[C]) assignValues(c cmd[C]) { if c.proxyMapping[k] != "" { p = c.proxyMapping[k] - s.mapping[p] = value + s.mapping[p] = stringValue } }) diff --git a/parse_test.go b/parse_test.go new file mode 100644 index 0000000000000000000000000000000000000000..36d7f9f2a7e225e79514ef505e5f375011aa8195 --- /dev/null +++ b/parse_test.go @@ -0,0 +1,28 @@ +// Copyright 2022 schukai GmbH +// SPDX-License-Identifier: AGPL-3.0 + +package xflags + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +type ParseMultiTestDefinition struct { + Values StringFlags `short:"x" long:"yyy" description:"Host to bind to" default:"localhost"` +} + +func TestMultiParseIt(t *testing.T) { + setting := New("test", ParseMultiTestDefinition{}) + setting.Parse([]string{"-x", "a1", "-x", "a2", "--yyy", "a3"}) + setting.Execute() + + if setting.HasErrors() { + for _, err := range setting.Errors() { + t.Log(err) + } + } + + assert.False(t, setting.HasErrors()) + assert.Equal(t, StringFlags{"a1", "a2", "a3"}, setting.definitions.Values) +} diff --git a/type.go b/type.go index c03332a70eb403daeccdd42cbe32141d6a915dae..b5602b6dfefb4afdb0bec5ef62307f3362e75987 100644 --- a/type.go +++ b/type.go @@ -1,3 +1,6 @@ +// Copyright 2023 schukai GmbH +// SPDX-License-Identifier: AGPL-3.0 + package xflags import (