Repository: datreeio/datree
Pull request #237 (2021-10-26 05:18:16)

feat: Command auto completion option to terminal datreeio#183
Added the command auto-completion like datree [tab][tab] it will give all following commands version, completion, config, test...

```
$ datree [tab][tab]
completion  config      help        publish     test        version
```
To test follow the below steps:
1. compile code with `go build -o datree main.go`
2. `./datree completion -h` we will get a description of how to use the completion command for [bash|zsh|fish|powershell].
3. For example bash we will use 
`$ datree completion bash > /etc/bash_completion.d/datree`
`$ source /etc/bash_completion.d/datree`
4. Now you will get auto-completion of command like below
```
$ datree [tab][tab]
completion  config      help        publish     test        version
$ datree completion [tab][tab]
bash        fish        powershell  zsh
```


Patch:
diff --git a/cmd/completion/main.go b/cmd/completion/main.go
new file mode 100644
index 0000000..d71dba4
--- /dev/null
+++ b/cmd/completion/main.go
@@ -0,0 +1,85 @@
+package completion
+
+import (
+	"fmt"
+	"io"
+	"os"
+
+	"github.com/spf13/cobra"
+)
+
+var out io.Writer = os.Stdout
+
+func New() *cobra.Command {
+	var completionCmd = &cobra.Command{
+		Use:   "completion [bash|zsh|fish|powershell]",
+		Short: "Generate completion script for bash,zsh,fish,powershell",
+		Long: `To load completions:
+
+		Bash:
+		
+		  $ source <(datree completion bash)
+		
+		  # To load completions for each session, execute once:
+		  # Linux:
+		  $ datree completion bash > /etc/bash_completion.d/datree
+		  # macOS:
+		  $ datree completion bash > /usr/local/etc/bash_completion.d/datree
+		
+		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:
+		  $ datree completion zsh > "${fpath[1]}/_datree"
+		
+		  # You will need to start a new shell for this setup to take effect.
+		
+		fish:
+		
+		  $ datree completion fish | source
+		
+		  # To load completions for each session, execute once:
+		  $ datree completion fish > ~/.config/fish/completions/datree.fish
+		
+		PowerShell:
+		
+		  PS> datree completion powershell | Out-String | Invoke-Expression
+		
+		  # To load completions for every new session, run:
+		  PS> datree completion powershell > datree.ps1
+		  # and source this file from your PowerShell profile.
+		`,
+		DisableFlagsInUseLine: true,
+		ValidArgs:             []string{"bash", "zsh", "fish", "powershell"},
+		Args:                  cobra.ExactValidArgs(1),
+		Run: func(cmd *cobra.Command, args []string) {
+			switch args[0] {
+			case "bash":
+				err := cmd.Root().GenBashCompletion(out)
+				if err != nil {
+					fmt.Printf("Failed to generate bash script. Error : %v", err)
+				}
+			case "zsh":
+				err := cmd.Root().GenZshCompletion(out)
+				if err != nil {
+					fmt.Printf("Failed to generate zsh script. Error : %v", err)
+				}
+			case "fish":
+				err := cmd.Root().GenFishCompletion(out, true)
+				if err != nil {
+					fmt.Printf("Failed to generate fish script. Error : %v", err)
+				}
+			case "powershell":
+				err := cmd.Root().GenPowerShellCompletionWithDesc(out)
+				if err != nil {
+					fmt.Printf("Failed to generate powershell script. Error : %v", err)
+				}
+			}
+		},
+	}
+	return completionCmd
+}
diff --git a/cmd/root.go b/cmd/root.go
index e96bb97..bba8c48 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -4,6 +4,7 @@ import (
 	"github.com/datreeio/datree/bl/evaluation"
 	"github.com/datreeio/datree/bl/messager"
 	"github.com/datreeio/datree/bl/validation"
+	"github.com/datreeio/datree/cmd/completion"
 	"github.com/datreeio/datree/cmd/config"
 	"github.com/datreeio/datree/cmd/publish"
 	"github.com/datreeio/datree/cmd/test"
@@ -57,6 +58,8 @@ func init() {
 		Printer:          app.context.Printer,
 		PublishCliClient: app.context.CliClient,
 	}))
+
+	rootCmd.AddCommand(completion.New())
 }
 
 func Execute() error {


Test patch:
diff --git a/cmd/completion/main_test.go b/cmd/completion/main_test.go
new file mode 100644
index 0000000..3dabd05
--- /dev/null
+++ b/cmd/completion/main_test.go
@@ -0,0 +1,63 @@
+package completion
+
+import (
+	"bytes"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func Test_ExecuteCommand(t *testing.T) {
+
+	t.Run("Test Completion Bash", func(t *testing.T) {
+		cmd := New()
+		out = new(bytes.Buffer)
+
+		cmd.SetArgs([]string{"bash"})
+		cmd.Execute()
+
+		got := out.(*bytes.Buffer).Bytes()
+		expected := []byte(`# bash completion for completion`)
+
+		assert.Equal(t, string(expected), string(got)[:len(expected)])
+	})
+
+	t.Run("Test Completion Zsh", func(t *testing.T) {
+		cmd := New()
+		out = new(bytes.Buffer)
+
+		cmd.SetArgs([]string{"zsh"})
+		cmd.Execute()
+
+		got := out.(*bytes.Buffer).Bytes()
+		expected := []byte(`#compdef _completion completion`)
+
+		assert.Equal(t, string(expected), string(got)[:len(expected)])
+	})
+
+	t.Run("Test Completion Fish", func(t *testing.T) {
+		cmd := New()
+		out = new(bytes.Buffer)
+
+		cmd.SetArgs([]string{"fish"})
+		cmd.Execute()
+
+		got := out.(*bytes.Buffer).Bytes()
+		expected := []byte(`# fish completion for completion`)
+
+		assert.Equal(t, string(expected), string(got)[:len(expected)])
+	})
+
+	t.Run("Test Completion Powershell", func(t *testing.T) {
+		cmd := New()
+		out = new(bytes.Buffer)
+
+		cmd.SetArgs([]string{"powershell"})
+		cmd.Execute()
+
+		got := out.(*bytes.Buffer).Bytes()
+		expected := []byte(`# powershell completion for completion`)
+
+		assert.Equal(t, string(expected), string(got)[:len(expected)])
+	})
+}