From b6533bf681531cd7618e86cff4d3c3d702ef9338 Mon Sep 17 00:00:00 2001 From: Gabe Cook Date: Sat, 16 Nov 2024 00:28:33 -0600 Subject: [PATCH] chore: Move shell completion flag to cobrax library --- cmd/cmd.go | 4 --- cmd/cmd_test.go | 8 ----- cmd/completion.go | 26 --------------- cmd/completion_test.go | 48 --------------------------- docs/yampl.md | 2 +- go.mod | 4 +-- go.sum | 8 ++--- internal/config/completions.go | 12 ------- internal/config/flags.go | 8 ++--- internal/config/load.go | 3 +- internal/generate/completions/main.go | 20 ++++------- 11 files changed, 20 insertions(+), 123 deletions(-) delete mode 100644 cmd/completion.go delete mode 100644 cmd/completion_test.go diff --git a/cmd/cmd.go b/cmd/cmd.go index 480efa8..dfa80f7 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -60,10 +60,6 @@ func run(cmd *cobra.Command, args []string) error { return err } - if conf.Completion != "" { - return completion(cmd, conf.Completion) - } - cmd.SilenceUsage = true if len(args) == 0 { diff --git a/cmd/cmd_test.go b/cmd/cmd_test.go index ae140c5..6f1d191 100644 --- a/cmd/cmd_test.go +++ b/cmd/cmd_test.go @@ -44,14 +44,6 @@ func Test_run(t *testing.T) { require.Error(t, run(cmd, []string{})) }) - t.Run("completion flag enabled", func(t *testing.T) { - cmd := New() - if err := cmd.Flags().Set(config.CompletionFlag, "zsh"); !assert.NoError(t, err) { - return - } - require.NoError(t, run(cmd, []string{})) - }) - t.Run("has config", func(t *testing.T) { cmd := New() conf, ok := config.FromContext(cmd.Context()) diff --git a/cmd/completion.go b/cmd/completion.go deleted file mode 100644 index 5dec1c1..0000000 --- a/cmd/completion.go +++ /dev/null @@ -1,26 +0,0 @@ -package cmd - -import ( - "errors" - "fmt" - - "github.com/clevyr/yampl/internal/config" - "github.com/spf13/cobra" -) - -var ErrInvalidShell = errors.New("invalid shell") - -func completion(cmd *cobra.Command, shell string) error { - switch shell { - case config.Bash: - return cmd.Root().GenBashCompletion(cmd.OutOrStdout()) - case config.Zsh: - return cmd.Root().GenZshCompletion(cmd.OutOrStdout()) - case config.Fish: - return cmd.Root().GenFishCompletion(cmd.OutOrStdout(), true) - case config.Powershell: - return cmd.Root().GenPowerShellCompletionWithDesc(cmd.OutOrStdout()) - default: - return fmt.Errorf("%w: %s", ErrInvalidShell, shell) - } -} diff --git a/cmd/completion_test.go b/cmd/completion_test.go deleted file mode 100644 index 16cc0d6..0000000 --- a/cmd/completion_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package cmd - -import ( - "io" - "testing" - - "github.com/clevyr/yampl/internal/config" - "github.com/spf13/cobra" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func Test_completion(t *testing.T) { - r, w := io.Pipe() - _ = r.Close() - - type args struct { - cmd *cobra.Command - shell string - } - tests := []struct { - name string - w io.Writer - args args - wantErr require.ErrorAssertionFunc - }{ - {"bash", io.Discard, args{New(), "bash"}, require.NoError}, - {"bash error", w, args{New(), "bash"}, require.Error}, - {"zsh", io.Discard, args{New(), "zsh"}, require.NoError}, - {"zsh error", w, args{New(), "zsh"}, require.Error}, - {"fish", io.Discard, args{New(), "fish"}, require.NoError}, - {"fish error", w, args{New(), "fish"}, require.Error}, - {"powershell", io.Discard, args{New(), "powershell"}, require.NoError}, - {"powershell error", w, args{New(), "powershell"}, require.Error}, - {"other", io.Discard, args{New(), "other"}, require.Error}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tt.args.cmd.SetOut(tt.w) - - if err := tt.args.cmd.Flags().Set(config.CompletionFlag, tt.args.shell); !assert.NoError(t, err) { - return - } - err := completion(tt.args.cmd, tt.args.shell) - tt.wantErr(t, err) - }) - } -} diff --git a/docs/yampl.md b/docs/yampl.md index 59eb924..045ff11 100644 --- a/docs/yampl.md +++ b/docs/yampl.md @@ -14,7 +14,7 @@ yampl [files | dirs] [-v key=value...] [flags] ### Options ``` - --completion string Output command-line completion code for the specified shell. Can be 'bash', 'zsh', 'fish', or 'powershell'. + --completion string Generate the autocompletion script for the specified shell (one of bash, zsh, fish, powershell) -h, --help help for yampl --ignore-template-errors Continue processing a file even if a template fails --ignore-unset-errors Exit with an error if a template variable is not set (default true) diff --git a/go.mod b/go.mod index 79b21d9..5e6069b 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/clevyr/yampl go 1.23.2 require ( - gabe565.com/utils v0.0.0-20241111053222-0f59399cbb3c + gabe565.com/utils v0.0.0-20241116061915-abe2278ecd5c github.com/Masterminds/sprig/v3 v3.3.0 github.com/dmarkham/enumer v1.5.10 github.com/lmittmann/tint v1.0.5 @@ -23,7 +23,7 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.18.0 // indirect - github.com/goccy/go-yaml v1.13.7 // indirect + github.com/goccy/go-yaml v1.13.9 // indirect github.com/google/uuid v1.6.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect diff --git a/go.sum b/go.sum index 7730b7c..8646a93 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -gabe565.com/utils v0.0.0-20241111053222-0f59399cbb3c h1:xKxZ9fGvYYihnqbyt1OE5Giz+rDQf5junHUxmvkFBfw= -gabe565.com/utils v0.0.0-20241111053222-0f59399cbb3c/go.mod h1:ekV9VNVFXI1E8niHsgfb76RQHP2oJH2zYaCw1cEWrhA= +gabe565.com/utils v0.0.0-20241116061915-abe2278ecd5c h1:1rmGsS/Sbm85ZELLkfOtXJ99v3YHdmqvkhMDLteLUug= +gabe565.com/utils v0.0.0-20241116061915-abe2278ecd5c/go.mod h1:1WioSVukwGZYG4Q0LJBnRhgYyVljmW2Izl+RW36ALUc= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= @@ -22,8 +22,8 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/goccy/go-yaml v1.13.7 h1:5k2i973KptPV1mur30XMXwGepDmskip4gA2zHWzWmOY= -github.com/goccy/go-yaml v1.13.7/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/goccy/go-yaml v1.13.9 h1:D/LhDa7E5HS/iYxSZzikUSHt1U9q/TeymVBJwodaglc= +github.com/goccy/go-yaml v1.13.9/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= diff --git a/internal/config/completions.go b/internal/config/completions.go index 0051cfb..58443ae 100644 --- a/internal/config/completions.go +++ b/internal/config/completions.go @@ -6,13 +6,6 @@ import ( "github.com/spf13/cobra" ) -const ( - Bash = "bash" - Zsh = "zsh" - Fish = "fish" - Powershell = "powershell" -) - func (c *Config) RegisterCompletions(cmd *cobra.Command) { if err := errors.Join( cmd.RegisterFlagCompletionFunc(InplaceFlag, BoolCompletion), @@ -33,11 +26,6 @@ func (c *Config) RegisterCompletions(cmd *cobra.Command) { return LogFormatStrings(), cobra.ShellCompDirectiveNoFileComp }, ), - cmd.RegisterFlagCompletionFunc(CompletionFlag, - func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { - return []string{Bash, Zsh, Fish, Powershell}, cobra.ShellCompDirectiveNoFileComp - }, - ), ); err != nil { panic(err) } diff --git a/internal/config/flags.go b/internal/config/flags.go index 41614b1..35d3b3a 100644 --- a/internal/config/flags.go +++ b/internal/config/flags.go @@ -5,6 +5,8 @@ import ( "errors" "log/slog" + "gabe565.com/utils/cobrax" + "gabe565.com/utils/must" "github.com/spf13/cobra" ) @@ -25,8 +27,6 @@ const ( LogLevelFlag = "log-level" LogFormatFlag = "log-format" - CompletionFlag = "completion" - // Deprecated: Replaced by VarFlag ValueFlag = "value" // Deprecated: Removed. Yampl will always recurse if a given path is a directory @@ -36,6 +36,8 @@ const ( ) func (c *Config) RegisterFlags(cmd *cobra.Command) { + must.Must(cobrax.RegisterCompletionFlag(cmd)) + cmd.Flags().Var(c.valuesStringToString, ValueFlag, "Define a template variable. Can be used more than once.") cmd.Flags().BoolVarP(&c.Inplace, InplaceFlag, "i", c.Inplace, "Edit files in place") @@ -52,8 +54,6 @@ func (c *Config) RegisterFlags(cmd *cobra.Command) { cmd.Flags().StringVarP(&c.LogLevel, LogLevelFlag, "l", c.LogLevel, "Log level (trace, debug, info, warn, error, fatal, panic)") cmd.Flags().StringVar(&c.LogFormat, LogFormatFlag, c.LogFormat, "Log format (auto, color, plain, json)") - cmd.Flags().StringVar(&c.Completion, CompletionFlag, c.Completion, "Output command-line completion code for the specified shell. Can be 'bash', 'zsh', 'fish', or 'powershell'.") - // Deprecated cmd.Flags().VarP(c.valuesStringToString, VarFlag, "v", "Define a template variable. Can be used more than once.") cmd.Flags().BoolP(RecursiveFlag, "r", true, "Recursively update yaml files in the given directory") diff --git a/internal/config/load.go b/internal/config/load.go index 30cd9aa..79ea441 100644 --- a/internal/config/load.go +++ b/internal/config/load.go @@ -6,6 +6,7 @@ import ( "slices" "strings" + "gabe565.com/utils/cobrax" "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -21,7 +22,7 @@ func Load(cmd *cobra.Command) (*Config, error) { } IgnoredEnvs := []string{ - CompletionFlag, + cobrax.FlagCompletion, } var errs []error diff --git a/internal/generate/completions/main.go b/internal/generate/completions/main.go index 0e71959..42a2866 100644 --- a/internal/generate/completions/main.go +++ b/internal/generate/completions/main.go @@ -6,15 +6,10 @@ import ( "os" "path/filepath" + "gabe565.com/utils/cobrax" "github.com/clevyr/yampl/cmd" ) -const ( - shellBash = "bash" - shellZsh = "zsh" - shellFish = "fish" -) - func main() { if err := os.RemoveAll("completions"); err != nil { panic(err) @@ -24,23 +19,22 @@ func main() { var buf bytes.Buffer rootCmd.SetOut(&buf) - for _, shell := range []string{shellBash, shellZsh, shellFish} { - rootCmd.SetArgs([]string{"--completion=" + shell}) - if err := rootCmd.Execute(); err != nil { + for _, shell := range []cobrax.Shell{cobrax.Bash, cobrax.Zsh, cobrax.Fish} { + if err := cobrax.GenCompletion(rootCmd, shell); err != nil { panic(err) } - path := filepath.Join("completions", shell) + path := filepath.Join("completions", string(shell)) if err := os.MkdirAll(path, 0o777); err != nil { panic(err) } switch shell { - case shellBash: + case cobrax.Bash: path = filepath.Join(path, rootCmd.Name()) - case shellZsh: + case cobrax.Zsh: path = filepath.Join(path, "_"+rootCmd.Name()) - case shellFish: + case cobrax.Fish: path = filepath.Join(path, rootCmd.Name()+".fish") }