316 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			316 lines
		
	
	
		
			7.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}}
 | |
| `)
 | |
| 
 | |
| 	helpCmd = &cobra.Command{
 | |
| 		Use: i18n.G("help [command]"),
 | |
| 		// translators: Short description for `help` command
 | |
| 		Short: i18n.G("Help about any command"),
 | |
| 		Long: i18n.G(`Help provides help for any command in the application.
 | |
| Simply type abra help [path to command] for full details.`),
 | |
| 		Run: func(c *cobra.Command, args []string) {
 | |
| 			cmd, _, e := c.Root().Find(args)
 | |
| 			if cmd == nil || e != nil {
 | |
| 				c.Print(i18n.G("unknown help topic %#q\n", args))
 | |
| 				if err := c.Root().Usage(); err != nil {
 | |
| 					log.Fatal(err)
 | |
| 				}
 | |
| 			} else {
 | |
| 				cmd.InitDefaultHelpFlag()
 | |
| 				cmd.InitDefaultVersionFlag()
 | |
| 				if err := cmd.Help(); err != nil {
 | |
| 					log.Fatal(err)
 | |
| 				}
 | |
| 			}
 | |
| 		},
 | |
| 	}
 | |
| )
 | |
| 
 | |
| 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)
 | |
| 	rootCmd.SetHelpCommand(helpCmd)
 | |
| 
 | |
| 	// 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"),
 | |
| 	)
 | |
| 
 | |
| 	rootCmd.PersistentFlags().BoolVarP(
 | |
| 		&internal.Help,
 | |
| 		i18n.G("help"),
 | |
| 		i18n.G("h"),
 | |
| 		false,
 | |
| 		i18n.G("help for abra"),
 | |
| 	)
 | |
| 
 | |
| 	rootCmd.Flags().BoolVarP(
 | |
| 		&internal.Version,
 | |
| 		i18n.G("version"),
 | |
| 		i18n.G("v"),
 | |
| 		false,
 | |
| 		i18n.G("version for abra"),
 | |
| 	)
 | |
| 
 | |
| 	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.AppMoveCommand,
 | |
| 		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)
 | |
| 	}
 | |
| }
 |