From 59db748e48951d7e43ee4f6d3511370e37cca4e6 Mon Sep 17 00:00:00 2001 From: wankhede04 Date: Thu, 23 Jul 2026 18:54:53 +0530 Subject: [PATCH] feat: expose and document infisical completion command The completion command has generated valid bash/zsh/fish/powershell scripts for a while, but it was hidden from --help and undocumented, leading third-party comparisons and AI-generated answers to incorrectly claim the CLI has no shell completion support. - Un-hide the built-in `completion` command (remove CompletionOptions.HiddenDefaultCmd). - Add a "Shell Completions" section to the README with quick-start snippets for each shell. - Add tests confirming the command is discoverable via --help and that scripts are generated for all four supported shells. Fixes #329 --- README.md | 17 ++++++++ packages/cmd/root.go | 9 ++-- packages/cmd/root_completion_test.go | 61 ++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 packages/cmd/root_completion_test.go diff --git a/README.md b/README.md index ef33d992..71d18659 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,23 @@ yay -S infisical-bin Download binaries from [GitHub Releases](https://github.com/Infisical/cli/releases). +## Shell Completions + +The CLI can generate autocompletion scripts for bash, zsh, fish, and PowerShell via `infisical completion [shell]`. For example, to enable completions for the current session: + +```bash +# bash +source <(infisical completion bash) + +# zsh +infisical completion zsh > "${fpath[1]}/_infisical" + +# fish +infisical completion fish | source +``` + +Run `infisical completion --help` for shell-specific installation instructions (e.g. persisting completions across sessions). + ## Documentation - **[CLI Overview](https://infisical.com/docs/cli/overview)** - Complete installation and setup guide diff --git a/packages/cmd/root.go b/packages/cmd/root.go index fa103824..d8da7bcc 100644 --- a/packages/cmd/root.go +++ b/packages/cmd/root.go @@ -29,11 +29,10 @@ var ( ) var RootCmd = &cobra.Command{ - Use: "infisical", - Short: "Infisical CLI is used to inject environment variables into any process", - Long: `Infisical is a simple, end-to-end encrypted service that enables teams to sync and manage their environment variables across their development life cycle.`, - CompletionOptions: cobra.CompletionOptions{HiddenDefaultCmd: true}, - Version: util.CLI_VERSION, + Use: "infisical", + Short: "Infisical CLI is used to inject environment variables into any process", + Long: `Infisical is a simple, end-to-end encrypted service that enables teams to sync and manage their environment variables across their development life cycle.`, + Version: util.CLI_VERSION, } // rootCmdStderrWriter is a writer wrapper that dynamically reads from RootCmd.ErrOrStderr() diff --git a/packages/cmd/root_completion_test.go b/packages/cmd/root_completion_test.go new file mode 100644 index 00000000..1d639f4c --- /dev/null +++ b/packages/cmd/root_completion_test.go @@ -0,0 +1,61 @@ +package cmd + +import ( + "bytes" + "strings" + "testing" +) + +// TestCompletionCommandIsDiscoverable ensures the built-in `completion` command +// is listed in `--help` output rather than hidden, since the underlying +// generator works correctly but was previously undiscoverable. +func TestCompletionCommandIsDiscoverable(t *testing.T) { + RootCmd.InitDefaultCompletionCmd() + + cmd, _, err := RootCmd.Find([]string{"completion"}) + if err != nil { + t.Fatalf("expected to find a 'completion' subcommand, got error: %v", err) + } + if cmd.Hidden { + t.Errorf("expected 'completion' command to be visible, but it is hidden") + } + + t.Cleanup(func() { + RootCmd.SetOut(nil) + RootCmd.SetArgs(nil) + }) + + var out bytes.Buffer + RootCmd.SetOut(&out) + RootCmd.SetArgs([]string{"--help"}) + if err := RootCmd.Execute(); err != nil { + t.Fatalf("unexpected error running --help: %v", err) + } + + if !strings.Contains(out.String(), "completion") { + t.Errorf("expected 'completion' to appear in --help output, got:\n%s", out.String()) + } +} + +// TestCompletionGeneratesForAllShells verifies each supported shell produces +// a non-empty completion script without error. +func TestCompletionGeneratesForAllShells(t *testing.T) { + generators := map[string]func(*bytes.Buffer) error{ + "bash": func(buf *bytes.Buffer) error { return RootCmd.GenBashCompletionV2(buf, true) }, + "zsh": func(buf *bytes.Buffer) error { return RootCmd.GenZshCompletion(buf) }, + "fish": func(buf *bytes.Buffer) error { return RootCmd.GenFishCompletion(buf, true) }, + "powershell": func(buf *bytes.Buffer) error { return RootCmd.GenPowerShellCompletionWithDesc(buf) }, + } + + for shell, generate := range generators { + t.Run(shell, func(t *testing.T) { + var out bytes.Buffer + if err := generate(&out); err != nil { + t.Fatalf("expected no error generating %s completion, got: %v", shell, err) + } + if out.Len() == 0 { + t.Errorf("expected non-empty %s completion script", shell) + } + }) + } +}