diff --git a/cli/commands.go b/cli/commands.go index 3fe64c26..5aa16adb 100644 --- a/cli/commands.go +++ b/cli/commands.go @@ -354,10 +354,7 @@ func GetKubeConfig(c *cli.Context) error { return nil } +// Shell starts a new subshell with the KUBECONFIG pointing to the selected cluster func Shell(c *cli.Context) error { - if c.String("shell") != "bash" { - return fmt.Errorf("%s is not supported. Only bash is supported", c.String("shell")) - } - - return bashShell(c.String("name"), c.String("command")) + return subShell(c.String("name"), c.String("shell"), c.String("command")) } diff --git a/cli/shell.go b/cli/shell.go index 7139a11e..6e20c3b3 100644 --- a/cli/shell.go +++ b/cli/shell.go @@ -4,25 +4,74 @@ import ( "fmt" "os" "os/exec" + "path" ) -func bashShell(cluster string, command string) error { +type shell struct { + Name string + Options []string + Prompt string + Env map[string]string +} + +var shells = map[string]shell{ + "bash": { + Name: "bash", + Options: []string{ + "--noprofile", // don't load .profile/.bash_profile + "--norc", // don't load .bashrc + }, + Prompt: "PS1", + }, + "zsh": { + Name: "zsh", + Options: []string{ + "--no-rcs", // don't load .zshrc + }, + Prompt: "PROMPT", + }, +} + +// subShell +func subShell(cluster, shell, command string) error { + + // check if the selected shell is supported + if shell == "auto" { + shell = path.Base(os.Getenv("SHELL")) + } + + supported := false + for supportedShell := range shells { + if supportedShell == shell { + supported = true + } + } + if !supported { + return fmt.Errorf("ERROR: selected shell [%s] is not supported", shell) + } + + // get kubeconfig for selected cluster kubeConfigPath, err := getKubeConfig(cluster) if err != nil { return err } + // check if we're already in a subshell subShell := os.ExpandEnv("$__K3D_CLUSTER__") if len(subShell) > 0 { return fmt.Errorf("Error: Already in subshell of cluster %s", subShell) } - bashPath, err := exec.LookPath("bash") + // get path of shell executable + shellPath, err := exec.LookPath(shell) if err != nil { return err } - cmd := exec.Command(bashPath, "--noprofile", "--norc") + // set shell specific options (command line flags) + shellOptions := shells[shell].Options + + cmd := exec.Command(shellPath, shellOptions...) if len(command) > 0 { cmd.Args = append(cmd.Args, "-c", command) @@ -35,7 +84,7 @@ func bashShell(cluster string, command string) error { cmd.Stderr = os.Stderr // Set up Promot - setPS1 := fmt.Sprintf("PS1=[%s}%s", cluster, os.Getenv("PS1")) + setPrompt := fmt.Sprintf("%s=[%s} %s", shells[shell].Prompt, cluster, os.Getenv(shells[shell].Prompt)) // Set up KUBECONFIG setKube := fmt.Sprintf("KUBECONFIG=%s", kubeConfigPath) @@ -43,7 +92,7 @@ func bashShell(cluster string, command string) error { // Declare subshell subShell = fmt.Sprintf("__K3D_CLUSTER__=%s", cluster) - newEnv := append(os.Environ(), setPS1, setKube, subShell) + newEnv := append(os.Environ(), setPrompt, setKube, subShell) cmd.Env = newEnv diff --git a/main.go b/main.go index 51386f3d..64ebe3d0 100644 --- a/main.go +++ b/main.go @@ -61,8 +61,8 @@ func main() { }, cli.StringFlag{ Name: "shell, s", - Value: "bash", - Usage: "Sub shell type. Only bash is supported. (default bash)", + Value: "auto", + Usage: "which shell to use. One of [auto, bash, zsh]", }, }, Action: run.Shell,