package cli import ( "errors" "fmt" "io" "net/http" "os" "path" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/config" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" ) // downloadFile downloads a file brah func downloadFile(filepath string, url string) (err error) { out, err := os.Create(filepath) if err != nil { return err } defer out.Close() resp, err := http.Get(url) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return fmt.Errorf("bad status: %s", resp.Status) } _, err = io.Copy(out, resp.Body) if err != nil { return err } return nil } // AutoCompleteCommand helps people set up auto-complete in their shells var AutoCompleteCommand = &cli.Command{ Name: "autocomplete", Usage: "Help set up shell autocompletion", Aliases: []string{"ac"}, Description: ` This command helps set up autocompletion in your shell by downloading the relevant autocompletion files and laying out what additional information must be loaded. Example: abra autocomplete bash Supported shells are as follows: fizsh zsh bash `, ArgsUsage: "", Action: func(c *cli.Context) error { shellType := c.Args().First() if shellType == "" { internal.ShowSubcommandHelpAndError(c, errors.New("no shell provided")) } supportedShells := map[string]bool{ "bash": true, "zsh": true, "fizsh": true, } if _, ok := supportedShells[shellType]; !ok { logrus.Fatalf("%s is not a supported shell right now, sorry", shellType) } if shellType == "fizsh" { shellType = "zsh" // handled the same on the autocompletion side } autocompletionDir := path.Join(config.ABRA_DIR, "autocompletion") if err := os.Mkdir(autocompletionDir, 0644); err != nil { if !os.IsExist(err) { logrus.Fatal(err) } logrus.Debugf("'%s' already created, moving on...", autocompletionDir) } autocompletionFile := path.Join(config.ABRA_DIR, "autocompletion", shellType) if _, err := os.Stat(autocompletionFile); err != nil && os.IsNotExist(err) { url := fmt.Sprintf("https://git.coopcloud.tech/coop-cloud/abra/raw/branch/main/scripts/autocomplete/%s", shellType) logrus.Infof("fetching %s", url) if err := downloadFile(autocompletionFile, url); err != nil { logrus.Fatal(err) } } switch shellType { case "bash": fmt.Println(fmt.Sprintf(` # Run the following commands to install autocompletion sudo mkdir /etc/bash/completion.d/ sudo cp %s /etc/bash_completion.d/abra echo "source /etc/bash/completion.d/abra" >> ~/.bashrc `, autocompletionFile)) case "zsh": fmt.Println(fmt.Sprintf(` # Run the following commands to install autocompletion sudo mkdir /etc/zsh/completion.d/ sudo cp %s /etc/zsh/completion.d/abra echo "PROG=abra\n_CLI_ZSH_AUTOCOMPLETE_HACK=1\nsource /etc/zsh/completion.d/abra" >> ~/.zshrc `, autocompletionFile)) } return nil }, }