diff --git a/README.md b/README.md index ef33d992..373ed637 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,16 @@ Download binaries from [GitHub Releases](https://github.com/Infisical/cli/releas - **[Commands Reference](https://infisical.com/docs/cli/commands)** - All available commands - **[FAQ](https://infisical.com/docs/cli/faq)** - Common questions and troubleshooting +## Shell Integration + +To automatically run selected Zsh commands through `infisical run`, add this to your `.zshrc`: + +```zsh +eval "$(infisical shell-init zsh)" +``` + +The integration wraps commands beginning with `npm`, `pnpm`, `bun`, or `node`. + ## Contributing We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. diff --git a/packages/cmd/shell_init.go b/packages/cmd/shell_init.go new file mode 100644 index 00000000..544db0de --- /dev/null +++ b/packages/cmd/shell_init.go @@ -0,0 +1,48 @@ +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +const zshShellInit = `# Infisical automatic command wrapper +if [[ -o interactive ]]; then + _infisical_auto_run_prefixes=(npm pnpm bun node) + + _infisical_auto_run_accept_line() { + local command="${BUFFER%%[[:space:]]*}" + local prefix + + for prefix in "${_infisical_auto_run_prefixes[@]}"; do + if [[ "$command" == "$prefix" ]]; then + BUFFER="infisical run -- $BUFFER" + break + fi + done + + zle .accept-line + } + + zle -N accept-line _infisical_auto_run_accept_line +fi +` + +var shellInitCmd = &cobra.Command{ + Use: "shell-init [zsh]", + Short: "prints shell integration for automatically injecting secrets", + Args: cobra.ExactArgs(1), + DisableFlagsInUseLine: true, + RunE: func(cmd *cobra.Command, args []string) error { + if args[0] != "zsh" { + return fmt.Errorf("unsupported shell %q, supported shells: zsh", args[0]) + } + + _, err := fmt.Fprint(cmd.OutOrStdout(), zshShellInit) + return err + }, +} + +func init() { + RootCmd.AddCommand(shellInitCmd) +} diff --git a/packages/cmd/shell_init_test.go b/packages/cmd/shell_init_test.go new file mode 100644 index 00000000..0f2aef35 --- /dev/null +++ b/packages/cmd/shell_init_test.go @@ -0,0 +1,19 @@ +package cmd + +import ( + "strings" + "testing" +) + +func TestZshShellInit(t *testing.T) { + for _, expected := range []string{ + "if [[ -o interactive ]]; then", + "_infisical_auto_run_prefixes=(npm pnpm bun node)", + "BUFFER=\"infisical run -- $BUFFER\"", + "zle .accept-line", + } { + if !strings.Contains(zshShellInit, expected) { + t.Errorf("shell initialization script does not contain %q", expected) + } + } +}