From fbef8da7c343bd404e68e6fbd66324fc222addaa Mon Sep 17 00:00:00 2001 From: rsteube Date: Wed, 21 Sep 2022 21:38:50 +0200 Subject: [PATCH] use carapace-pflag --- docs/src/carapace-spec/command/flags.md | 4 +- example/nonposix.yaml | 15 +++++++ flag.go | 54 ++++++++++++++++++++----- flag_test.go | 24 +++++++++++ go.mod | 4 +- go.sum | 4 +- spec_test.go | 21 ++++++++++ 7 files changed, 111 insertions(+), 15 deletions(-) create mode 100644 example/nonposix.yaml diff --git a/docs/src/carapace-spec/command/flags.md b/docs/src/carapace-spec/command/flags.md index 674f25e..c1c1daa 100644 --- a/docs/src/carapace-spec/command/flags.md +++ b/docs/src/carapace-spec/command/flags.md @@ -1,7 +1,6 @@ # Flags Flags are defined as a map of name and description. -The name can contain shorthand, longhand and modifiers matching this [regex](https://regex101.com/r/to7O2W/1). ```yaml flags: @@ -9,6 +8,9 @@ flags: -v=: shorthand with value --repeatable*: longhand repeatable -o, --optarg?: shorthand and longhand with optional argument + -np: non-posix shorthand + -np, -nonposix: non-posix shorthand and longhand + -np, --nonposix: non-posix shorthand mixed with posix longhand ``` ## Modifiers: diff --git a/example/nonposix.yaml b/example/nonposix.yaml new file mode 100644 index 0000000..de5bc1b --- /dev/null +++ b/example/nonposix.yaml @@ -0,0 +1,15 @@ +name: nonposix +description: +flags: + -opt, -optarg?: both nonposix + -styled=: nonpoxis shorthand + -mx, --mixed*: mixed repeatable +completion: + flag: + optarg: [1, 2, 3] + styled: + - "green\t\tgreen" + - "red\t\tred" + - "yellow\t\tyellow" + positional: + - [a, b, c] diff --git a/flag.go b/flag.go index 7556d8a..1528576 100644 --- a/flag.go +++ b/flag.go @@ -14,13 +14,15 @@ type flag struct { slice bool optarg bool value bool + nonposix bool } func parseFlag(s, usage string) (f flag) { - r := regexp.MustCompile(`^(?P-[^-])?(, )?(?P--[^ =*?]*)?(?P[=*?]*)$`) + r := regexp.MustCompile(`^(?P-[^-][^ =*?]*)?(, )?(?P-[-]?[^ =*?]*)?(?P[=*?]*)$`) matches := findNamedMatches(r, s) - f.longhand = strings.TrimPrefix(matches["longhand"], "--") + f.longhand = strings.TrimLeft(matches["longhand"], "-") + f.nonposix = matches["longhand"] != "" && !strings.HasPrefix(matches["longhand"], "--") f.shorthand = strings.TrimPrefix(matches["shorthand"], "-") f.usage = usage f.slice = strings.Contains(matches["modifier"], "*") @@ -38,29 +40,61 @@ func (f flag) addTo(flagSet *pflag.FlagSet) { if f.longhand != "" && f.shorthand != "" { if f.value { if f.slice { - flagSet.StringSliceP(f.longhand, f.shorthand, []string{}, f.usage) + if !f.nonposix { + flagSet.StringSliceP(f.longhand, f.shorthand, []string{}, f.usage) + } else { + flagSet.StringSliceN(f.longhand, f.shorthand, []string{}, f.usage) + } } else { - flagSet.StringP(f.longhand, f.shorthand, "", f.usage) + if !f.nonposix { + flagSet.StringP(f.longhand, f.shorthand, "", f.usage) + } else { + flagSet.StringN(f.longhand, f.shorthand, "", f.usage) + } } } else { if f.slice { - flagSet.CountP(f.longhand, f.shorthand, f.usage) + if !f.nonposix { + flagSet.CountP(f.longhand, f.shorthand, f.usage) + } else { + flagSet.CountN(f.longhand, f.shorthand, f.usage) + } } else { - flagSet.BoolP(f.longhand, f.shorthand, false, f.usage) + if !f.nonposix { + flagSet.BoolP(f.longhand, f.shorthand, false, f.usage) + } else { + flagSet.BoolN(f.longhand, f.shorthand, false, f.usage) + } } } } else if f.longhand != "" { if f.value { if f.slice { - flagSet.StringSlice(f.longhand, []string{}, f.usage) + if !f.nonposix { + flagSet.StringSlice(f.longhand, []string{}, f.usage) + } else { + flagSet.StringSliceS(f.longhand, f.longhand, []string{}, f.usage) + } } else { - flagSet.String(f.longhand, "", f.usage) + if !f.nonposix { + flagSet.String(f.longhand, "", f.usage) + } else { + flagSet.StringS(f.longhand, f.longhand, "", f.usage) + } } } else { if f.slice { - flagSet.Count(f.longhand, f.usage) + if !f.nonposix { + flagSet.Count(f.longhand, f.usage) + } else { + flagSet.CountS(f.longhand, f.longhand, f.usage) + } } else { - flagSet.Bool(f.longhand, false, f.usage) + if !f.nonposix { + flagSet.Bool(f.longhand, false, f.usage) + } else { + flagSet.BoolS(f.longhand, f.longhand, false, f.usage) + } } } } else if f.shorthand != "" { diff --git a/flag_test.go b/flag_test.go index 4deaef9..22b6b2c 100644 --- a/flag_test.go +++ b/flag_test.go @@ -17,6 +17,8 @@ func TestParseFlag(t *testing.T) { f := parseFlag(id, usage) if !reflect.DeepEqual(f, expected) { t.Error(usage) + t.Logf("expected: %#v", expected) + t.Logf("actual: %#v", f) } flagSet := pflag.NewFlagSet("test", pflag.PanicOnError) @@ -91,4 +93,26 @@ func TestParseFlag(t *testing.T) { optarg: true, }) + test("nonposix shorthand", "-short", flag{ + shorthand: "short", + }) + + test("nonposix shorthand optarg", "-short?", flag{ + shorthand: "short", + value: true, + optarg: true, + }) + + test("nonposix both", "-short, -long*", flag{ + shorthand: "short", + longhand: "long", + slice: true, + nonposix: true, + }) + + test("nonposix mixed", "-short, --long", flag{ + shorthand: "short", + longhand: "long", + nonposix: false, + }) } diff --git a/go.mod b/go.mod index 06de1e1..34472bc 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,6 @@ module github.com/rsteube/carapace-spec go 1.18 -replace github.com/spf13/pflag => github.com/cornfeedhobo/pflag v1.1.0 - require ( github.com/rsteube/carapace v0.24.0 github.com/spf13/cobra v1.5.0 @@ -12,3 +10,5 @@ require ( ) require github.com/inconshreveable/mousetrap v1.0.0 // indirect + +replace github.com/spf13/pflag => github.com/rsteube/carapace-pflag v0.0.4 diff --git a/go.sum b/go.sum index 4cd2487..7f98d07 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,10 @@ -github.com/cornfeedhobo/pflag v1.1.0 h1:hZ356pzRepv6EbQ3M5Yx0ZyvQnTj8rgGKm6PCTFy2kc= -github.com/cornfeedhobo/pflag v1.1.0/go.mod h1:ROo/cqBpAh84jplPcXiI5HTjyLmtp04WaPKkHC18E6U= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/rsteube/carapace v0.24.0 h1:LOGXJPhlMjwWI550b6OniKuUNpMNzH1BSHRYDK2FR+c= github.com/rsteube/carapace v0.24.0/go.mod h1:JjsAq3W3rvWEIg0FkOxT0HUNQjnboP/T0S8Khof9ZWU= +github.com/rsteube/carapace-pflag v0.0.4 h1:Onb0cLNLxg1xJr2EsMlBldAI5KkybrvZ89b5cRElZXI= +github.com/rsteube/carapace-pflag v0.0.4/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= diff --git a/spec_test.go b/spec_test.go index 78f5be2..020c0b0 100644 --- a/spec_test.go +++ b/spec_test.go @@ -12,6 +12,9 @@ import ( //go:embed example/example.yaml var example string +//go:embed example/nonposix.yaml +var nonposix string + func TestSpec(t *testing.T) { if out := execute(t, example, "example", "sub1", "--styled", ""); !strings.Contains(out, "cyan") { t.Error(out) @@ -50,6 +53,24 @@ func TestSpec(t *testing.T) { } } +func TestSpecNonposix(t *testing.T) { + if out := execute(t, nonposix, "nonposix", ""); !strings.Contains(out, "a") { + t.Error(out) + } + + if out := execute(t, nonposix, "nonposix", "-"); !strings.Contains(out, "-styled") { + t.Error(out) + } + + if out := execute(t, nonposix, "nonposix", "-mx", "--"); !strings.Contains(out, "--mixed") { + t.Error(out) + } + + if out := execute(t, nonposix, "nonposix", "-opt="); !strings.Contains(out, "1") { + t.Error(out) + } +} + func execute(t *testing.T, spec string, args ...string) string { var stdout, stderr bytes.Buffer var c Command