package cli import ( "errors" "fmt" "os" "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/lang" "coopcloud.tech/abra/pkg/log" charmLog "github.com/charmbracelet/log" "github.com/leonelquinteros/gotext" "github.com/spf13/cobra" "github.com/spf13/cobra/doc" ) func Run(version, commit string) { rootCmd := &cobra.Command{ Use: gotext.Get("abra [cmd] [args] [flags]"), Short: gotext.Get("The Co-op Cloud command-line utility belt 🎩🐇"), Version: fmt.Sprintf("%s-%s", version, commit[:7]), ValidArgs: []string{ gotext.Get("app"), gotext.Get("autocomplete"), gotext.Get("catalogue"), gotext.Get("man"), gotext.Get("recipe"), gotext.Get("server"), gotext.Get("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(gotext.Get("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) } if internal.Locale != "" { // FIXME(d1): get list of valid locales from pkg/locales/* switch internal.Locale { case "es": default: return errors.New(gotext.Get("unsupported --lang: %s (want: es)", internal.Locale)) } } systemLocale := lang.GetLocale() if internal.Locale == "" && systemLocale != "" { // FIXME(d1): validate system locale also (as above FIXME) internal.Locale = systemLocale } if internal.Locale == "" { // NOTE(d1): fallback when no --lang= / LANG= internal.Locale = "en" } // NOTE(d1): only required to load locale when not using en_ // N.B we don't even bother with a _ (country code) atm for en because fuck it if internal.Locale != "en" { if err := lang.LoadLocale(internal.Locale); err != nil { return errors.New(gotext.Get("unable to load supported language %s: %s", internal.Locale, err)) } } log.Debug(gotext.Get( "abra version: %s, commit: %s, lang: %s", version, formatter.SmallSHA(commit), internal.Locale, )) return nil }, } rootCmd.CompletionOptions.DisableDefaultCmd = true manCommand := &cobra.Command{ Use: gotext.Get("man [flags]"), Aliases: []string{"m"}, Short: gotext.Get("Generate manpage"), Example: gotext.Get(` # 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(gotext.Get("unable to proceed, %s does not exist?", manDir)) } err := doc.GenManTree(rootCmd, header, manDir) if err != nil { log.Fatal(err) } log.Info(gotext.Get("don't forget to run 'sudo mandb'")) }, } rootCmd.PersistentFlags().BoolVarP( &internal.Debug, "debug", "d", false, gotext.Get("show debug messages"), ) rootCmd.PersistentFlags().BoolVarP( &internal.NoInput, "no-input", "n", false, gotext.Get("toggle non-interactive mode"), ) rootCmd.PersistentFlags().BoolVarP( &internal.Offline, "offline", "o", false, gotext.Get("prefer offline & filesystem access"), ) rootCmd.PersistentFlags().BoolVarP( &internal.IgnoreEnvVersion, "ignore-env-version", "i", false, gotext.Get("ignore .env version checkout"), ) rootCmd.PersistentFlags().StringVarP( &internal.Locale, "lang", "l", "", // FIXME(d1): provide supported list of language via *.po file listing gotext.Get("force select language (supported: XXX)"), ) catalogue.CatalogueCommand.AddCommand( catalogue.CatalogueGenerateCommand, ) 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) } }