204 lines
5.7 KiB
Go
204 lines
5.7 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: `
|
|
Set up auto-completion in your shell by downloading the relevant files and
|
|
laying out what additional information must be loaded. Supported shells are as
|
|
follows: bash, fish, fizsh & zsh.
|
|
|
|
Example:
|
|
|
|
abra autocomplete 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,
|
|
"fish": 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 auto-completion
|
|
sudo mkdir /etc/bash_completion.d/
|
|
sudo cp %s /etc/bash_completion.d/abra
|
|
echo "source /etc/bash_completion.d/abra" >> ~/.bashrc
|
|
# To test, run the following: "abra app <hit tab key>" - you should see command completion!
|
|
`, autocompletionFile))
|
|
case "zsh":
|
|
fmt.Println(fmt.Sprintf(`
|
|
# Run the following commands to install auto-completion
|
|
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
|
|
# To test, run the following: "abra app <hit tab key>" - you should see command completion!
|
|
`, autocompletionFile))
|
|
case "fish":
|
|
fmt.Println(fmt.Sprintf(`
|
|
# Run the following commands to install auto-completion
|
|
sudo mkdir -p /etc/fish/completions
|
|
sudo cp %s /etc/fish/completions/abra
|
|
echo "source /etc/fish/completions/abra" >> ~/.config/fish/config.fish
|
|
# To test, run the following: "abra app <hit tab key>" - you should see command completion!
|
|
`, autocompletionFile))
|
|
}
|
|
|
|
return nil
|
|
},
|
|
}
|
|
|
|
// UpgradeCommand upgrades abra in-place.
|
|
var UpgradeCommand = cli.Command{
|
|
Name: "upgrade",
|
|
Aliases: []string{"u"},
|
|
Usage: "Upgrade Abra itself",
|
|
Description: `
|
|
Upgrade Abra in-place with the latest stable or release candidate.
|
|
|
|
Pass "-r/--rc" to install the latest release candidate. Please bear in mind
|
|
that it may contain catastrophic bugs. 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),
|
|
path.Join(config.BACKUP_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)
|
|
}
|
|
}
|