275 lines
6.9 KiB
Go
275 lines
6.9 KiB
Go
package cli
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"coopcloud.tech/abra/cli/app"
|
|
"coopcloud.tech/abra/cli/catalogue"
|
|
"coopcloud.tech/abra/cli/internal"
|
|
"coopcloud.tech/abra/cli/recipe"
|
|
"coopcloud.tech/abra/cli/server"
|
|
"coopcloud.tech/abra/pkg/config"
|
|
"coopcloud.tech/abra/pkg/formatter"
|
|
"coopcloud.tech/abra/pkg/i18n"
|
|
"coopcloud.tech/abra/pkg/log"
|
|
charmLog "github.com/charmbracelet/log"
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/cobra/doc"
|
|
)
|
|
|
|
var (
|
|
// translators: `abra` usage template. please translate only words like
|
|
// "Aliases" and "Example" and nothing inside the {{ ... }}
|
|
usageTemplate = i18n.G(`Usage:{{if .Runnable}}
|
|
{{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
|
|
{{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
|
|
|
|
Aliases:
|
|
{{.NameAndAliases}}{{end}}{{if .HasExample}}
|
|
|
|
Examples:
|
|
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
|
|
|
|
Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
|
|
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
|
|
|
|
Flags:
|
|
{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
|
|
|
|
Global Flags:
|
|
{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
|
|
|
|
Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
|
|
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
|
|
|
|
Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
|
|
`)
|
|
)
|
|
|
|
func Run(version, commit string) {
|
|
rootCmd := &cobra.Command{
|
|
// translators: `abra` binary name
|
|
Use: i18n.G("abra [cmd] [args] [flags]"),
|
|
// translators: Short description for `abra` binary
|
|
Short: i18n.G("The Co-op Cloud command-line utility belt 🎩🐇"),
|
|
// translators: Long description for `abra` binary. This needs to be
|
|
// translated in the same way as the Short description so that everything
|
|
// matches up
|
|
Long: i18n.G(`The Co-op Cloud command-line utility belt 🎩🐇
|
|
|
|
Config:
|
|
$ABRA_DIR: %s`, config.ABRA_DIR),
|
|
Version: fmt.Sprintf("%s-%s", version, commit[:7]),
|
|
ValidArgs: []string{
|
|
// translators: `abra app` command for autocompletion
|
|
i18n.G("app"),
|
|
// translators: `abra autocomplete` command for autocompletion
|
|
i18n.G("autocomplete"),
|
|
// translators: `abra catalogue` command for autocompletion
|
|
i18n.G("catalogue"),
|
|
// translators: `abra man` command for autocompletion
|
|
i18n.G("man"),
|
|
// translators: `abra recipe` command for autocompletion
|
|
i18n.G("recipe"),
|
|
// translators: `abra server` command for autocompletion
|
|
i18n.G("server"),
|
|
// translators: `abra upgrade` command for autocompletion
|
|
i18n.G("upgrade"),
|
|
},
|
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
|
dirs := []map[string]os.FileMode{
|
|
{config.ABRA_DIR: 0764},
|
|
{config.SERVERS_DIR: 0700},
|
|
{config.RECIPES_DIR: 0764},
|
|
{config.LOGS_DIR: 0764},
|
|
}
|
|
|
|
for _, dir := range dirs {
|
|
for path, perm := range dir {
|
|
if err := os.Mkdir(path, perm); err != nil {
|
|
if !os.IsExist(err) {
|
|
return errors.New(i18n.G("unable to create %s: %s", path, err))
|
|
}
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
|
|
log.Logger.SetStyles(charmLog.DefaultStyles())
|
|
charmLog.SetDefault(log.Logger)
|
|
|
|
if internal.MachineReadable {
|
|
log.SetOutput(os.Stderr)
|
|
}
|
|
|
|
if internal.Debug {
|
|
log.SetLevel(log.DebugLevel)
|
|
log.SetOutput(os.Stderr)
|
|
log.SetReportCaller(true)
|
|
}
|
|
|
|
log.Debug(i18n.G(
|
|
"abra version: %s, commit: %s, lang: %s",
|
|
version, formatter.SmallSHA(commit), i18n.Locale,
|
|
))
|
|
|
|
return nil
|
|
},
|
|
}
|
|
|
|
rootCmd.CompletionOptions.DisableDefaultCmd = true
|
|
rootCmd.SetUsageTemplate(usageTemplate)
|
|
|
|
// translators: `abra man` aliases. use a comma separated list of aliases
|
|
// with no spaces in between
|
|
manAliases := i18n.G("m")
|
|
|
|
manCommand := &cobra.Command{
|
|
// translators: `man` command
|
|
Use: i18n.G("man [flags]"),
|
|
Aliases: strings.Split(manAliases, ","),
|
|
// translators: Short description for `man` command
|
|
Short: i18n.G("Generate manpage"),
|
|
Example: i18n.G(` # generate the man pages into /usr/local/share/man/man1
|
|
abra_path=$(which abra) # pass abra absolute path to sudo below
|
|
sudo $abra_path man
|
|
sudo mandb
|
|
|
|
# read the man pages
|
|
man abra
|
|
man abra-app-deploy`),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
header := &doc.GenManHeader{
|
|
Title: "ABRA",
|
|
Section: "1",
|
|
}
|
|
|
|
manDir := "/usr/local/share/man/man1"
|
|
if _, err := os.Stat(manDir); os.IsNotExist(err) {
|
|
log.Fatal(i18n.G("unable to proceed, %s does not exist?", manDir))
|
|
}
|
|
|
|
err := doc.GenManTree(rootCmd, header, manDir)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
log.Info(i18n.G("don't forget to run 'sudo mandb'"))
|
|
},
|
|
}
|
|
|
|
rootCmd.PersistentFlags().BoolVarP(
|
|
&internal.Debug,
|
|
"debug",
|
|
"d",
|
|
false,
|
|
i18n.G("show debug messages"),
|
|
)
|
|
|
|
rootCmd.PersistentFlags().BoolVarP(
|
|
&internal.NoInput,
|
|
"no-input",
|
|
"n",
|
|
false,
|
|
i18n.G("toggle non-interactive mode"),
|
|
)
|
|
|
|
rootCmd.PersistentFlags().BoolVarP(
|
|
&internal.Offline,
|
|
"offline",
|
|
"o",
|
|
false,
|
|
i18n.G("prefer offline & filesystem access"),
|
|
)
|
|
|
|
catalogue.CatalogueCommand.AddCommand(
|
|
catalogue.CatalogueGenerateCommand,
|
|
catalogue.CatalogueSyncCommand,
|
|
)
|
|
|
|
server.ServerCommand.AddCommand(
|
|
server.ServerAddCommand,
|
|
server.ServerListCommand,
|
|
server.ServerPruneCommand,
|
|
server.ServerRemoveCommand,
|
|
)
|
|
|
|
recipe.RecipeCommand.AddCommand(
|
|
recipe.RecipeDiffCommand,
|
|
recipe.RecipeFetchCommand,
|
|
recipe.RecipeLintCommand,
|
|
recipe.RecipeListCommand,
|
|
recipe.RecipeNewCommand,
|
|
recipe.RecipeReleaseCommand,
|
|
recipe.RecipeResetCommand,
|
|
recipe.RecipeSyncCommand,
|
|
recipe.RecipeUpgradeCommand,
|
|
recipe.RecipeVersionCommand,
|
|
)
|
|
|
|
rootCmd.AddCommand(
|
|
UpgradeCommand,
|
|
AutocompleteCommand,
|
|
manCommand,
|
|
app.AppCommand,
|
|
catalogue.CatalogueCommand,
|
|
server.ServerCommand,
|
|
recipe.RecipeCommand,
|
|
)
|
|
|
|
app.AppCmdCommand.AddCommand(
|
|
app.AppCmdListCommand,
|
|
)
|
|
|
|
app.AppSecretCommand.AddCommand(
|
|
app.AppSecretGenerateCommand,
|
|
app.AppSecretInsertCommand,
|
|
app.AppSecretRmCommand,
|
|
app.AppSecretLsCommand,
|
|
)
|
|
|
|
app.AppVolumeCommand.AddCommand(
|
|
app.AppVolumeListCommand,
|
|
app.AppVolumeRemoveCommand,
|
|
)
|
|
|
|
app.AppBackupCommand.AddCommand(
|
|
app.AppBackupListCommand,
|
|
app.AppBackupDownloadCommand,
|
|
app.AppBackupCreateCommand,
|
|
app.AppBackupSnapshotsCommand,
|
|
)
|
|
|
|
app.AppCommand.AddCommand(
|
|
app.AppBackupCommand,
|
|
app.AppCheckCommand,
|
|
app.AppCmdCommand,
|
|
app.AppConfigCommand,
|
|
app.AppCpCommand,
|
|
app.AppDeployCommand,
|
|
app.AppListCommand,
|
|
app.AppLogsCommand,
|
|
app.AppNewCommand,
|
|
app.AppPsCommand,
|
|
app.AppRemoveCommand,
|
|
app.AppRestartCommand,
|
|
app.AppRestoreCommand,
|
|
app.AppRollbackCommand,
|
|
app.AppRunCommand,
|
|
app.AppSecretCommand,
|
|
app.AppServicesCommand,
|
|
app.AppUndeployCommand,
|
|
app.AppUpgradeCommand,
|
|
app.AppVolumeCommand,
|
|
app.AppLabelsCommand,
|
|
app.AppEnvCommand,
|
|
)
|
|
|
|
if err := rootCmd.Execute(); err != nil {
|
|
os.Exit(1)
|
|
}
|
|
}
|