func NewCommand(home string, docker client.CommonAPIClient, output terminal.Outputer) *cobra.Command {
	cmd := &cobra.Command{
		Use:     "ssh",
		Short:   "Opens a shell in a container.",
		Example: exampleText,
		ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
			cfg, err := config.Load(home)
			if err != nil {
				return nil, cobra.ShellCompDirectiveDefault
			}
			var options []string
			for _, s := range cfg.Sites {
				options = append(options, s.Hostname)
			}
			return options, cobra.ShellCompDirectiveNoFileComp
		},
		PreRunE: func(cmd *cobra.Command, args []string) error {
			if _, err := docker.Ping(cmd.Context()); err != nil {
				return fmt.Errorf("Couldn’t connect to Docker; please make sure Docker is running.")
			}
			return nil
		},
		RunE: func(cmd *cobra.Command, args []string) error {
			wd, err := os.Getwd()
			if err != nil {
				return err
			}
			cfg, err := config.Load(home)
			if err != nil {
				return err
			}
			var site string
			if len(args) > 0 {
				site = strings.TrimSpace(args[0])
			}
			filter := filters.NewArgs()
			filter.Add("label", containerlabels.Nitro)
			var containerID string
			switch ProxyContainer {
			case true:
				filter.Add("name", proxycontainer.ProxyName)
				containers, err := docker.ContainerList(cmd.Context(), types.ContainerListOptions{Filters: filter, All: true})
				if err != nil {
					return err
				}
				if len(containers) == 0 {
					return fmt.Errorf("no containers found")
				}
				if containers[0].State != "running" {
					for _, command := range cmd.Root().Commands() {
						if command.Use == "start" {
							if err := command.RunE(cmd, []string{}); err != nil {
								return err
							}
						}
					}
				}
				containerID = containers[0].ID
			default:
				sites := cfg.ListOfSitesByDirectory(home, wd)
				var options []string
				for _, s := range sites {
					options = append(options, s.Hostname)
				}
				switch site != "" {
				case true:
					for k, v := range options {
						if site == v {
							filter.Add("label", containerlabels.Host+"="+sites[k].Hostname)
							break
						}
					}
				default:
					switch len(sites) {
					case 0:
						selected, err := output.Select(cmd.InOrStdin(), "Select a site: ", options)
						if err != nil {
							return err
						}
						filter.Add("label", containerlabels.Host+"="+sites[selected].Hostname)
					case 1:
						output.Info("connecting to", sites[0].Hostname)
						filter.Add("label", containerlabels.Host+"="+sites[0].Hostname)
					default:
						selected, err := output.Select(cmd.InOrStdin(), "Select a site: ", options)
						if err != nil {
							return err
						}
						filter.Add("label", containerlabels.Host+"="+sites[selected].Hostname)
					}
				}
				containers, err := docker.ContainerList(cmd.Context(), types.ContainerListOptions{Filters: filter, All: true})
				if err != nil {
					return err
				}
				if len(containers) == 0 {
					return fmt.Errorf("unable to find an matching site")
				}
				if containers[0].State != "running" {
					for _, command := range cmd.Root().Commands() {
						if command.Use == "start" {
							if err := command.RunE(cmd, []string{}); err != nil {
								return err
							}
						}
					}
				}
				containerID = containers[0].ID
			}
			cli, err := exec.LookPath("docker")
			if err != nil {
				return err
			}
			var containerUser string
			if RootUser || ProxyContainer {
				containerUser = "root"
			} else {
				user, err := user.Current()
				if err != nil {
					return err
				}
				containerUser = fmt.Sprintf("%s:%s", user.Uid, user.Gid)
			}
			if containerUser == "root" {
				output.Info("using root… system changes are ephemeral…")
			}
			c := exec.Command(cli, "exec", "-u", containerUser, "-it", containerID, "sh")
			c.Stdin = cmd.InOrStdin()
			c.Stderr = cmd.ErrOrStderr()
			c.Stdout = cmd.OutOrStdout()
			return c.Run()
		},
	}
	cmd.Flags().BoolVar(&RootUser, "root", false, "connect as root user")
	cmd.Flags().BoolVar(&ProxyContainer, "proxy", false, "connect to proxy container")
	return cmd
}
NewCommand returns the ssh command to get a shell in a container. The command is context aware and if
it is not in a known project directory, it will provide a list of known sites to the user.
package ssh
import (
	"fmt"
	"os"
	"os/exec"
	"os/user"
	"strings"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/filters"
	"github.com/docker/docker/client"
	"github.com/spf13/cobra"
	"github.com/craftcms/nitro/pkg/config"
	"github.com/craftcms/nitro/pkg/containerlabels"
	"github.com/craftcms/nitro/pkg/proxycontainer"
	"github.com/craftcms/nitro/pkg/terminal"
)