From 263e77c8038664968e0d9ad3f3e88966e08b397e Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Wed, 2 Jun 2021 19:19:20 -0400 Subject: [PATCH] add completion function for generating shell completions --- ChangeLog.md | 6 ++++ README.md | 1 + cmd/completion.go | 75 ++++++++++++++++++++++++++++++++++++++++ cmd/root.go | 1 + validators/validators.go | 29 +++++++++++----- 5 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 cmd/completion.go diff --git a/ChangeLog.md b/ChangeLog.md index 0204d15..1823b2a 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,11 @@ # Changelog +## Version 0.8.0 +* add `completion` function to generate shell completion scripts + +## Version 0.7.0 +* enable colorized output by default if stdout is a TTY + ## Version 0.6.1 * fix bug in `endpoint create` which caused a panic diff --git a/README.md b/README.md index 3fb444c..e403826 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ The Svix CLI supports the following commands: | message | List & create messages | | message-attempt | List, lookup & resend message attempts | | verify | Verify the signature of a webhook message | +| completion | Generate completion script | | version | Get the version of the Svix CLI | | help | Help about any command | diff --git a/cmd/completion.go b/cmd/completion.go new file mode 100644 index 0000000..1ffe2c7 --- /dev/null +++ b/cmd/completion.go @@ -0,0 +1,75 @@ +package cmd + +import ( + "os" + + "github.com/spf13/cobra" + "github.com/svixhq/svix-cli/validators" +) + +type completionCmd struct { + cmd *cobra.Command +} + +func newCompletionCmd() *completionCmd { + return &completionCmd{ + cmd: &cobra.Command{ + Use: "completion [bash|zsh|fish|powershell]", + Short: "Generate completion script", + Long: `To load completions: + +Bash: + + $ source <(svix completion bash) + + # To load completions for each session, execute once: + # Linux: + $ svix completion bash > /etc/bash_completion.d/svix + # macOS: + $ svix completion bash > /usr/local/etc/bash_completion.d/svix + +Zsh: + + # If shell completion is not already enabled in your environment, + # you will need to enable it. You can execute the following once: + + $ echo "autoload -U compinit; compinit" >> ~/.zshrc + + # To load completions for each session, execute once: + $ svix completion zsh > "${fpath[1]}/_svix" + + # You will need to start a new shell for this setup to take effect. + +fish: + + $ svix completion fish | source + + # To load completions for each session, execute once: + $ svix completion fish > ~/.config/fish/completions/svix.fish + +PowerShell: + + PS> svix completion powershell | Out-String | Invoke-Expression + + # To load completions for every new session, run: + PS> svix completion powershell > svix.ps1 + # and source this file from your PowerShell profile. +`, + DisableFlagsInUseLine: true, + ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, + Args: validators.ExactValidArgs(1), + Run: func(cmd *cobra.Command, args []string) { + switch args[0] { + case "bash": + cobra.CheckErr(cmd.Root().GenBashCompletion(os.Stdout)) + case "zsh": + cobra.CheckErr(cmd.Root().GenZshCompletion(os.Stdout)) + case "fish": + cobra.CheckErr(cmd.Root().GenFishCompletion(os.Stdout, true)) + case "powershell": + cobra.CheckErr(cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)) + } + }, + }, + } +} diff --git a/cmd/root.go b/cmd/root.go index 379e1c1..fb34032 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -52,6 +52,7 @@ func init() { rootCmd.AddCommand(newMessageCmd().cmd) rootCmd.AddCommand(newMessageAttemptCmd().cmd) rootCmd.AddCommand(newVerifyCmd().cmd) + rootCmd.AddCommand(newCompletionCmd().cmd) } // initConfig reads in config file and ENV variables if set. diff --git a/validators/validators.go b/validators/validators.go index 76090be..d86b7cb 100644 --- a/validators/validators.go +++ b/validators/validators.go @@ -37,17 +37,30 @@ func RangeArgs(min int, max int) cobra.PositionalArgs { func ExactArgs(n int) cobra.PositionalArgs { return func(cmd *cobra.Command, args []string) error { if len(args) != n { - msg := "`%s`requires %d args, received %d. Run `%s --help` for usage information." if n == 1 { - msg = "`%s`requires 1 arg, received %d. Run `%s --help` for usage information." + return fmt.Errorf("`%s` requires 1 arg, received %d. Run `%s --help` for usage information.", + cmd.CommandPath(), + len(args), + cmd.CommandPath(), + ) + } else { + return fmt.Errorf("`%s` requires %d args, received %d. Run `%s --help` for usage information.", + cmd.CommandPath(), + n, + len(args), + cmd.CommandPath(), + ) } - return fmt.Errorf(msg, - cmd.CommandPath(), - n, - len(args), - cmd.CommandPath(), - ) } return nil } } + +func ExactValidArgs(n int) cobra.PositionalArgs { + return func(cmd *cobra.Command, args []string) error { + if err := ExactArgs(n)(cmd, args); err != nil { + return err + } + return cobra.OnlyValidArgs(cmd, args) + } +}