From 5553cbde87ecf974ee7529fef6f4d041a37d217a Mon Sep 17 00:00:00 2001 From: Matt Witkowski Date: Mon, 27 Nov 2023 19:16:22 -0500 Subject: [PATCH] Add auto complete. (#1762) * Add auto complete. * Add tests for auto complete. * Change some text. * Update changelog. * Update test to remove branch since it's already included. --- CHANGELOG.md | 1 + cmd/provenanced/cmd/cmd_test.go | 54 +++++++++++++++++++++++++++++++++ cmd/provenanced/cmd/root.go | 36 ++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69a269994e..8e84d77e40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features * Add CLI commands for the exchange module endpoints and queries [#1701](https://github.com/provenance-io/provenance/issues/1701). +* Add CLI command to generate autocomplete shell scripts [#1762](https://github.com/provenance-io/provenance/pull/1762). ### Improvements diff --git a/cmd/provenanced/cmd/cmd_test.go b/cmd/provenanced/cmd/cmd_test.go index c15c9024d1..923e821394 100644 --- a/cmd/provenanced/cmd/cmd_test.go +++ b/cmd/provenanced/cmd/cmd_test.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" "github.com/provenance-io/provenance/cmd/provenanced/cmd" + "github.com/provenance-io/provenance/testutil/assertions" ) func TestInitCmd(t *testing.T) { @@ -24,3 +25,56 @@ func TestInitCmd(t *testing.T) { err := cmd.Execute(rootCmd) require.NoError(t, err) } + +func TestGenAutoCompleteCmd(t *testing.T) { + home := t.TempDir() + + tests := []struct { + name string + args []string + err string + }{ + { + name: "failure - missing arg", + err: "accepts 1 arg(s), received 0", + }, + { + name: "failure - too many args", + args: []string{"bash", "fish"}, + err: "accepts 1 arg(s), received 2", + }, + { + name: "failure - invalid shell type", + args: []string{"badshellname"}, + err: "shell badshellname is not supported", + }, + { + name: "success - works with bash", + args: []string{"bash"}, + }, + { + name: "success - works with zsh", + args: []string{"zsh"}, + }, + { + name: "success - works with fish", + args: []string{"fish"}, + }, + { + name: "success - works with powershell", + args: []string{"powershell"}, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + args := []string{"--home", home, "enable-cli-autocomplete"} + args = append(args, tc.args...) + + rootCmd, _ := cmd.NewRootCmd(false) + rootCmd.SetArgs(args) + err := cmd.Execute(rootCmd) + assertions.AssertErrorValue(t, err, tc.err, "should have the correct output value") + }) + } +} diff --git a/cmd/provenanced/cmd/root.go b/cmd/provenanced/cmd/root.go index da030bcbdb..91d1d3c50b 100644 --- a/cmd/provenanced/cmd/root.go +++ b/cmd/provenanced/cmd/root.go @@ -101,6 +101,7 @@ func NewRootCmd(sealConfig bool) (*cobra.Command, params.EncodingConfig) { return nil }, } + genAutoCompleteCmd(rootCmd) initRootCmd(rootCmd, encodingConfig) overwriteFlagDefaults(rootCmd, map[string]string{ flags.FlagChainID: "", @@ -180,6 +181,41 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { startCmd.SilenceUsage = true } +// genAutoCompleteCmd creates the command for autocomplete. +func genAutoCompleteCmd(rootCmd *cobra.Command) { + rootCmd.AddCommand(&cobra.Command{ + Use: "enable-cli-autocomplete [bash|zsh|fish|powershell]", + Short: "Generates autocomplete scripts for the provenanced binary", + Long: `To configure your shell to load completions for each session, add to your profile: + +# bash example +echo '. <(provenanced enable-cli-autocomplete bash)' >> ~/.bash_profile +source ~/.bash_profile + +# zsh example +echo '. <(provenanced enable-cli-autocomplete zsh)' >> ~/.zshrc +source ~/.zshrc +`, + DisableFlagsInUseLine: true, + ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + switch args[0] { + case "bash": + return cmd.Root().GenBashCompletion(os.Stdout) + case "zsh": + return cmd.Root().GenZshCompletion(os.Stdout) + case "fish": + return cmd.Root().GenFishCompletion(os.Stdout, true) + case "powershell": + return cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) + } + + return fmt.Errorf("shell %s is not supported", args[0]) + }, + }) +} + func addModuleInitFlags(startCmd *cobra.Command) { crisis.AddModuleInitFlags(startCmd) }