forked from toolshed/abra
		
	
		
			
				
	
	
		
			202 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Package cli provides the interface for the command-line.
 | 
						|
package cli
 | 
						|
 | 
						|
import (
 | 
						|
	"errors"
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"os/exec"
 | 
						|
	"path"
 | 
						|
 | 
						|
	"coopcloud.tech/abra/cli/app"
 | 
						|
	"coopcloud.tech/abra/cli/catalogue"
 | 
						|
	"coopcloud.tech/abra/cli/internal"
 | 
						|
	"coopcloud.tech/abra/cli/recipe"
 | 
						|
	"coopcloud.tech/abra/cli/record"
 | 
						|
	"coopcloud.tech/abra/cli/server"
 | 
						|
	"coopcloud.tech/abra/pkg/autocomplete"
 | 
						|
	"coopcloud.tech/abra/pkg/config"
 | 
						|
	"coopcloud.tech/abra/pkg/web"
 | 
						|
	"github.com/sirupsen/logrus"
 | 
						|
	"github.com/urfave/cli"
 | 
						|
)
 | 
						|
 | 
						|
// AutoCompleteCommand helps people set up auto-complete in their shells
 | 
						|
var AutoCompleteCommand = cli.Command{
 | 
						|
	Name:    "autocomplete",
 | 
						|
	Aliases: []string{"ac"},
 | 
						|
	Usage:   "Configure shell autocompletion (recommended)",
 | 
						|
	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: "<shell>",
 | 
						|
	Flags: []cli.Flag{
 | 
						|
		internal.DebugFlag,
 | 
						|
	},
 | 
						|
	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, 0764); err != nil {
 | 
						|
			if !os.IsExist(err) {
 | 
						|
				logrus.Fatal(err)
 | 
						|
			}
 | 
						|
			logrus.Debugf("%s already created", 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 := web.GetFile(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
 | 
						|
# And finally run "abra app ps <hit tab key>" to test things are working, you should see app domains listed!
 | 
						|
`, 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
 | 
						|
# And finally run "abra app ps <hit tab key>" to test things are working, you should see app domains listed!
 | 
						|
`, autocompletionFile))
 | 
						|
		}
 | 
						|
 | 
						|
		return nil
 | 
						|
	},
 | 
						|
}
 | 
						|
 | 
						|
// UpgradeCommand upgrades abra in-place.
 | 
						|
var UpgradeCommand = cli.Command{
 | 
						|
	Name:    "upgrade",
 | 
						|
	Aliases: []string{"u"},
 | 
						|
	Usage:   "Upgrade Abra itself",
 | 
						|
	Description: `
 | 
						|
This command allows you to upgrade Abra in-place with the latest stable or
 | 
						|
release candidate.
 | 
						|
 | 
						|
If you would like to install the latest release candidate, please pass the
 | 
						|
"--rc" option. Please bear in mind that the latest release candidate may have
 | 
						|
some catastrophic bugs contained in it. In any case, thank you very much for
 | 
						|
the testing efforts!
 | 
						|
`,
 | 
						|
	Flags: []cli.Flag{internal.RCFlag},
 | 
						|
	Action: func(c *cli.Context) error {
 | 
						|
		mainURL := "https://install.abra.coopcloud.tech"
 | 
						|
		cmd := exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash", mainURL))
 | 
						|
 | 
						|
		if internal.RC {
 | 
						|
			releaseCandidateURL := "https://git.coopcloud.tech/coop-cloud/abra/raw/branch/main/scripts/installer/installer"
 | 
						|
			cmd = exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash -s -- --rc", releaseCandidateURL))
 | 
						|
		}
 | 
						|
 | 
						|
		logrus.Debugf("attempting to run %s", cmd)
 | 
						|
 | 
						|
		if err := internal.RunCmd(cmd); err != nil {
 | 
						|
			logrus.Fatal(err)
 | 
						|
		}
 | 
						|
 | 
						|
		return nil
 | 
						|
	},
 | 
						|
}
 | 
						|
 | 
						|
func newAbraApp(version, commit string) *cli.App {
 | 
						|
	app := &cli.App{
 | 
						|
		Name: "abra",
 | 
						|
		Usage: `The Co-op Cloud command-line utility belt 🎩🐇
 | 
						|
    ____                           ____ _                 _
 | 
						|
   / ___|___         ___  _ __    / ___| | ___  _   _  __| |
 | 
						|
  | |   / _ \ _____ / _ \| '_ \  | |   | |/ _ \| | | |/ _' |
 | 
						|
  | |__| (_) |_____| (_) | |_) | | |___| | (_) | |_| | (_| |
 | 
						|
   \____\___/       \___/| .__/   \____|_|\___/ \__,_|\__,_|
 | 
						|
                         |_|
 | 
						|
`,
 | 
						|
		Version: fmt.Sprintf("%s-%s", version, commit[:7]),
 | 
						|
		Commands: []cli.Command{
 | 
						|
			app.AppCommand,
 | 
						|
			server.ServerCommand,
 | 
						|
			recipe.RecipeCommand,
 | 
						|
			catalogue.CatalogueCommand,
 | 
						|
			record.RecordCommand,
 | 
						|
			UpgradeCommand,
 | 
						|
			AutoCompleteCommand,
 | 
						|
		},
 | 
						|
		BashComplete: autocomplete.SubcommandComplete,
 | 
						|
	}
 | 
						|
 | 
						|
	app.EnableBashCompletion = true
 | 
						|
 | 
						|
	app.Before = func(c *cli.Context) error {
 | 
						|
		paths := []string{
 | 
						|
			config.ABRA_DIR,
 | 
						|
			path.Join(config.SERVERS_DIR),
 | 
						|
			path.Join(config.RECIPES_DIR),
 | 
						|
			path.Join(config.VENDOR_DIR),
 | 
						|
		}
 | 
						|
 | 
						|
		for _, path := range paths {
 | 
						|
			if err := os.Mkdir(path, 0764); err != nil {
 | 
						|
				if !os.IsExist(err) {
 | 
						|
					logrus.Fatal(err)
 | 
						|
				}
 | 
						|
				continue
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		logrus.Debugf("abra version %s, commit %s", version, commit)
 | 
						|
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	return app
 | 
						|
}
 | 
						|
 | 
						|
// RunApp runs CLI abra app.
 | 
						|
func RunApp(version, commit string) {
 | 
						|
	app := newAbraApp(version, commit)
 | 
						|
 | 
						|
	if err := app.Run(os.Args); err != nil {
 | 
						|
		logrus.Fatal(err)
 | 
						|
	}
 | 
						|
}
 |