From a341a59d82867c96d0d1abfa2161bfc8d584dd60 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Wed, 20 Nov 2019 17:36:53 +1100 Subject: [PATCH] Don't validate enum values for unused required paths. Fixes #40. --- context.go | 17 +++++++++++++++-- kong_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/context.go b/context.go index 80c262f..9baca0e 100644 --- a/context.go +++ b/context.go @@ -132,10 +132,10 @@ func (c *Context) Empty() bool { } // Validate the current context. -func (c *Context) Validate() error { +func (c *Context) Validate() error { // nolint: gocyclo err := Visit(c.Model, func(node Visitable, next Next) error { if value, ok := node.(*Value); ok { - if value.Enum != "" { + if value.Enum != "" && (!value.Required || value.Default != "") { if err := checkEnum(value, value.Target); err != nil { return err } @@ -152,6 +152,19 @@ func (c *Context) Validate() error { } } for _, path := range c.Path { + var value *Value + switch { + case path.Flag != nil: + value = path.Flag.Value + + case path.Positional != nil: + value = path.Positional + } + if value != nil && value.Tag.Enum != "" { + if err := checkEnum(value, value.Target); err != nil { + return err + } + } if err := checkMissingFlags(path.Flags); err != nil { return err } diff --git a/kong_test.go b/kong_test.go index b6fcc5f..75a7fcd 100644 --- a/kong_test.go +++ b/kong_test.go @@ -791,3 +791,27 @@ func TestEnumSequence(t *testing.T) { require.NoError(t, err) require.Equal(t, []string{"a"}, cli.State) } + +func TestIssue40EnumAcrossCommands(t *testing.T) { + var cli struct { + One struct { + OneArg string `arg:"" required:""` + } `cmd:""` + Two struct { + TwoArg string `arg:"" enum:"a,b,c" required:""` + } `cmd:""` + Three struct { + ThreeArg string `arg:"" optional:"" default:"a" enum:"a,b,c"` + } `cmd:""` + } + + p := mustNew(t, &cli) + _, err := p.Parse([]string{"one", "two"}) + require.NoError(t, err) + _, err = p.Parse([]string{"two", "d"}) + require.Error(t, err) + _, err = p.Parse([]string{"three", "d"}) + require.Error(t, err) + _, err = p.Parse([]string{"three", "c"}) + require.NoError(t, err) +}