From 4815badedc73d7396fa955e1137234fd352354f8 Mon Sep 17 00:00:00 2001 From: Gabe Cook Date: Sat, 16 Nov 2024 00:47:53 -0600 Subject: [PATCH] chore: Move shell completion flag to cobrax library --- cmd/cmd.go | 6 +--- cmd/completion.go | 26 --------------- cmd/completion_test.go | 47 --------------------------- docs/cli-of-life.md | 2 +- go.mod | 2 +- go.sum | 4 +-- internal/config/completion.go | 16 --------- internal/config/flags.go | 10 +++--- internal/generate/completions/main.go | 8 ++--- 9 files changed, 14 insertions(+), 107 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 a5d5ff7..b67c1c6 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -34,7 +34,7 @@ func New(opts ...cobrax.Option) *cobra.Command { config.InitLog(slog.LevelInfo) conf := config.New() - conf.RegisterFlags(cmd.Flags()) + conf.RegisterFlags(cmd) must.Must(config.RegisterCompletion(cmd)) cmd.SetContext(config.NewContext(context.Background(), conf)) @@ -59,10 +59,6 @@ func run(cmd *cobra.Command, args []string) error { panic("command missing config") } - if conf.Completion != "" { - return completion(cmd, conf.Completion) - } - slog.Info("cli-of-life", "version", cobrax.GetVersion(cmd), "commit", cobrax.GetCommit(cmd)) if len(args) == 1 { diff --git a/cmd/completion.go b/cmd/completion.go deleted file mode 100644 index ab372b7..0000000 --- a/cmd/completion.go +++ /dev/null @@ -1,26 +0,0 @@ -package cmd - -import ( - "errors" - "fmt" - - "gabe565.com/cli-of-life/internal/config" - "github.com/spf13/cobra" -) - -var ErrInvalidShell = errors.New("invalid shell") - -func completion(cmd *cobra.Command, shell string) error { - switch shell { - case config.ShellBash: - return cmd.Root().GenBashCompletion(cmd.OutOrStdout()) - case config.ShellZsh: - return cmd.Root().GenZshCompletion(cmd.OutOrStdout()) - case config.ShellFish: - return cmd.Root().GenFishCompletion(cmd.OutOrStdout(), true) - case config.ShellPowerShell: - 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 5793953..0000000 --- a/cmd/completion_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package cmd - -import ( - "io" - "testing" - - "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("completion", tt.args.shell); !assert.NoError(t, err) { - return - } - err := completion(tt.args.cmd, tt.args.shell) - tt.wantErr(t, err) - }) - } -} diff --git a/docs/cli-of-life.md b/docs/cli-of-life.md index 80c87b4..d5a71ac 100644 --- a/docs/cli-of-life.md +++ b/docs/cli-of-life.md @@ -10,7 +10,7 @@ cli-of-life [file | url] [flags] ``` --cache-limit int Maximum number of entries to keep cached. Higher values will use more memory, but less CPU. (default 10000000) - --completion string Output command-line completion code for the specified shell (one of: bash, zsh, fish, powershell) + --completion string Generate the autocompletion script for the specified shell (one of bash, zsh, fish, powershell) -h, --help help for cli-of-life --play Play on startup --rule-string string Rule string to use. This will be ignored if a pattern file is loaded. (default "B3/S23") diff --git a/go.mod b/go.mod index bfb5e36..4f1311c 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module gabe565.com/cli-of-life go 1.23.3 require ( - gabe565.com/utils v0.0.0-20241113080130-5627e2628c07 + gabe565.com/utils v0.0.0-20241116061915-abe2278ecd5c github.com/PuerkitoBio/goquery v1.10.0 github.com/charmbracelet/bubbles v0.20.0 github.com/charmbracelet/bubbletea v1.2.2 diff --git a/go.sum b/go.sum index d85789b..26b1fc9 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -gabe565.com/utils v0.0.0-20241113080130-5627e2628c07 h1:1TGslYPWSlhS6i55gimuXFKPsGNdYY/58tQaXfmsfmM= -gabe565.com/utils v0.0.0-20241113080130-5627e2628c07/go.mod h1:1WioSVukwGZYG4Q0LJBnRhgYyVljmW2Izl+RW36ALUc= +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/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/PuerkitoBio/goquery v1.10.0 h1:6fiXdLuUvYs2OJSvNRqlNPoBm6YABE226xrbavY5Wv4= diff --git a/internal/config/completion.go b/internal/config/completion.go index 3373071..912ed74 100644 --- a/internal/config/completion.go +++ b/internal/config/completion.go @@ -7,17 +7,6 @@ import ( "github.com/spf13/cobra" ) -const ( - ShellBash = "bash" - ShellZsh = "zsh" - ShellFish = "fish" - ShellPowerShell = "powershell" -) - -func shells() []string { - return []string{ShellBash, ShellZsh, ShellFish, ShellPowerShell} -} - func RegisterCompletion(cmd *cobra.Command) error { return errors.Join( cmd.RegisterFlagCompletionFunc(RuleStringFlag, @@ -27,10 +16,5 @@ func RegisterCompletion(cmd *cobra.Command) error { ), cmd.RegisterFlagCompletionFunc(PlayFlag, cobra.NoFileCompletions), cmd.RegisterFlagCompletionFunc(CacheLimitFlag, cobra.NoFileCompletions), - cmd.RegisterFlagCompletionFunc(CompletionFlag, - func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { - return shells(), cobra.ShellCompDirectiveNoFileComp - }, - ), ) } diff --git a/internal/config/flags.go b/internal/config/flags.go index 288ad6e..4f300ca 100644 --- a/internal/config/flags.go +++ b/internal/config/flags.go @@ -3,17 +3,16 @@ package config import ( "bytes" "log/slog" - "strings" + "gabe565.com/utils/cobrax" "gabe565.com/utils/must" - "github.com/spf13/pflag" + "github.com/spf13/cobra" ) const ( RuleStringFlag = "rule-string" PlayFlag = "play" CacheLimitFlag = "cache-limit" - CompletionFlag = "completion" // Deprecated: Pass file as positional argument instead FileFlag = "file" @@ -21,11 +20,12 @@ const ( URLFlag = "url" ) -func (c *Config) RegisterFlags(fs *pflag.FlagSet) { +func (c *Config) RegisterFlags(cmd *cobra.Command) { + must.Must(cobrax.RegisterCompletionFlag(cmd)) + fs := cmd.Flags() fs.StringVar(&c.RuleString, RuleStringFlag, c.RuleString, "Rule string to use. This will be ignored if a pattern file is loaded.") fs.BoolVar(&c.Play, PlayFlag, c.Play, "Play on startup") fs.IntVar(&c.CacheLimit, CacheLimitFlag, c.CacheLimit, "Maximum number of entries to keep cached. Higher values will use more memory, but less CPU.") - fs.StringVar(&c.Completion, CompletionFlag, c.Completion, "Output command-line completion code for the specified shell (one of: "+strings.Join(shells(), ", ")+")") fs.StringVarP(&c.Pattern, FileFlag, "f", c.Pattern, "Load a pattern file") fs.StringVar(&c.Pattern, URLFlag, c.Pattern, "Load a pattern URL") diff --git a/internal/generate/completions/main.go b/internal/generate/completions/main.go index b796bef..e9ff023 100644 --- a/internal/generate/completions/main.go +++ b/internal/generate/completions/main.go @@ -8,6 +8,7 @@ import ( "time" "gabe565.com/cli-of-life/cmd" + "gabe565.com/utils/cobrax" flag "github.com/spf13/pflag" ) @@ -39,13 +40,12 @@ func main() { var buf bytes.Buffer rootCmd.SetOut(&buf) - for _, shell := range []string{"bash", "zsh", "fish"} { - 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) } - f, err := os.Create(filepath.Join("completions", name+"."+shell)) + f, err := os.Create(filepath.Join("completions", name+"."+string(shell))) if err != nil { panic(err) }