From ff93d67a8d293b03196d3354ece8880975b7b873 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Wed, 9 Jun 2021 13:01:16 +1000 Subject: [PATCH] Validate duplicate short flags. Fixes #174. --- build.go | 17 ++++++++++++++--- kong_test.go | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/build.go b/build.go index 4d9081a..d2ca41c 100644 --- a/build.go +++ b/build.go @@ -119,7 +119,10 @@ func buildNode(k *Kong, v reflect.Value, typ NodeType, seenFlags map[string]bool // "Unsee" flags. for _, flag := range node.Flags { - delete(seenFlags, flag.Name) + delete(seenFlags, "--"+flag.Name) + if flag.Short != 0 { + delete(seenFlags, "-"+string(flag.Short)) + } } // Scan through argument positionals to ensure optional is never before a required. @@ -205,10 +208,18 @@ func buildField(k *Kong, node *Node, v reflect.Value, ft reflect.StructField, fv if tag.Arg { node.Positional = append(node.Positional, value) } else { - if seenFlags[value.Name] { + if seenFlags["--"+value.Name] { fail("duplicate flag --%s", value.Name) + } else { + seenFlags["--"+value.Name] = true + } + if tag.Short != 0 { + if seenFlags["-"+string(tag.Short)] { + fail("duplicate short flag -%c", tag.Short) + } else { + seenFlags["-"+string(tag.Short)] = true + } } - seenFlags[value.Name] = true flag := &Flag{ Value: value, Short: tag.Short, diff --git a/kong_test.go b/kong_test.go index 857c6ca..66fbe1b 100644 --- a/kong_test.go +++ b/kong_test.go @@ -1062,3 +1062,23 @@ func TestDynamicCommands(t *testing.T) { require.NoError(t, err) require.True(t, two.ran) } + +func TestDuplicateShortflags(t *testing.T) { + cli := struct { + Flag1 bool `short:"t"` + Flag2 bool `short:"t"` + }{} + _, err := kong.New(&cli) + require.EqualError(t, err, "duplicate short flag -t") +} + +func TestDuplicateNestedShortFlags(t *testing.T) { + cli := struct { + Flag1 bool `short:"t"` + Cmd struct { + Flag2 bool `short:"t"` + } `cmd:""` + }{} + _, err := kong.New(&cli) + require.EqualError(t, err, "duplicate short flag -t") +}