refactor!: vertical render & UI/UX fixes

See coop-cloud/abra#454
This commit is contained in:
2024-12-28 15:30:43 +01:00
committed by decentral1se
parent b6573720ec
commit 97959ef5da
17 changed files with 352 additions and 184 deletions

View File

@ -46,7 +46,10 @@ ${FOO:<default>} syntax). "check" does not confirm or deny this for you.`,
}
table.
Headers("RECIPE ENV SAMPLE", "APP ENV").
Headers(
fmt.Sprintf("%s .env.sample", app.Recipe.Name),
fmt.Sprintf("%s.env", app.Name),
).
StyleFunc(func(row, col int) lipgloss.Style {
switch {
case col == 1:
@ -71,7 +74,9 @@ ${FOO:<default>} syntax). "check" does not confirm or deny this for you.`,
}
}
fmt.Println(table)
if err := formatter.PrintTable(table); err != nil {
log.Fatal(err)
}
},
}

View File

@ -110,19 +110,19 @@ Please note, "upgrade"/"rollback" do not support chaos operations.`,
// is because we need to deal with GetComposeFiles under the hood and these
// files change from version to version which therefore affects which
// secrets might be generated
version := deployMeta.Version
toDeployVersion := deployMeta.Version
if specificVersion != "" {
version = specificVersion
log.Debugf("choosing %s as version to deploy", version)
toDeployVersion = specificVersion
log.Debugf("choosing %s as version to deploy", toDeployVersion)
var err error
isChaosCommit, err = app.Recipe.EnsureVersion(version)
isChaosCommit, err = app.Recipe.EnsureVersion(toDeployVersion)
if err != nil {
log.Fatal(err)
}
if isChaosCommit {
log.Debugf("assuming '%s' is a chaos commit", version)
log.Debugf("assuming '%s' is a chaos commit", toDeployVersion)
internal.Chaos = true
}
}
@ -138,12 +138,8 @@ Please note, "upgrade"/"rollback" do not support chaos operations.`,
}
}
if deployMeta.IsDeployed {
if internal.Force || internal.Chaos {
warnMessages = append(warnMessages, fmt.Sprintf("%s is already deployed", app.Name))
} else {
log.Fatalf("%s is already deployed", app.Name)
}
if deployMeta.IsDeployed && !(internal.Force || internal.Chaos) {
log.Fatalf("%s is already deployed", app.Name)
}
if !internal.Chaos && specificVersion == "" {
@ -153,9 +149,9 @@ Please note, "upgrade"/"rollback" do not support chaos operations.`,
}
if len(versions) > 0 && !internal.Chaos {
version = versions[len(versions)-1]
log.Debugf("choosing %s as version to deploy", version)
if _, err := app.Recipe.EnsureVersion(version); err != nil {
toDeployVersion = versions[len(versions)-1]
log.Debugf("choosing %s as version to deploy", toDeployVersion)
if _, err := app.Recipe.EnsureVersion(toDeployVersion); err != nil {
log.Fatal(err)
}
} else {
@ -163,25 +159,22 @@ Please note, "upgrade"/"rollback" do not support chaos operations.`,
if err != nil {
log.Fatal(err)
}
version = formatter.SmallSHA(head.String())
warnMessages = append(warnMessages, fmt.Sprintf("no versions detected, using latest commit"))
toDeployVersion = formatter.SmallSHA(head.String())
}
}
chaosVersion := config.CHAOS_DEFAULT
toDeployChaosVersion := config.CHAOS_DEFAULT
if internal.Chaos {
warnMessages = append(warnMessages, "chaos mode engaged")
if isChaosCommit {
chaosVersion = specificVersion
toDeployChaosVersion = specificVersion
versionLabelLocal, err := app.Recipe.GetVersionLabelLocal()
if err != nil {
log.Fatal(err)
}
version = versionLabelLocal
toDeployVersion = versionLabelLocal
} else {
var err error
chaosVersion, err = app.Recipe.ChaosVersion()
toDeployChaosVersion, err = app.Recipe.ChaosVersion()
if err != nil {
log.Fatal(err)
}
@ -216,7 +209,7 @@ Please note, "upgrade"/"rollback" do not support chaos operations.`,
appPkg.ExposeAllEnv(stackName, compose, app.Env)
appPkg.SetRecipeLabel(compose, stackName, app.Recipe.Name)
appPkg.SetChaosLabel(compose, stackName, internal.Chaos)
appPkg.SetChaosVersionLabel(compose, stackName, chaosVersion)
appPkg.SetChaosVersionLabel(compose, stackName, toDeployChaosVersion)
appPkg.SetUpdateLabel(compose, stackName, app.Env)
envVars, err := appPkg.CheckEnv(app)
@ -239,13 +232,24 @@ Please note, "upgrade"/"rollback" do not support chaos operations.`,
log.Fatal(err)
}
} else {
warnMessages = append(warnMessages, "skipping domain checks as no DOMAIN=... configured for app")
log.Debug("skipping domain checks as no DOMAIN=... configured for app")
}
} else {
warnMessages = append(warnMessages, "skipping domain checks as requested")
log.Debug("skipping domain checks as requested")
}
if err := internal.DeployOverview(app, warnMessages, version, chaosVersion); err != nil {
deployedVersion := "N/A"
if deployMeta.IsDeployed {
deployedVersion = deployMeta.Version
}
if err := internal.DeployOverview(
app,
warnMessages,
deployedVersion,
deployMeta.ChaosVersion,
toDeployVersion,
toDeployChaosVersion); err != nil {
log.Fatal(err)
}
@ -267,9 +271,9 @@ Please note, "upgrade"/"rollback" do not support chaos operations.`,
}
}
app.Recipe.Version = version
if chaosVersion != config.CHAOS_DEFAULT {
app.Recipe.Version = chaosVersion
app.Recipe.Version = toDeployVersion
if toDeployChaosVersion != config.CHAOS_DEFAULT {
app.Recipe.Version = toDeployChaosVersion
}
log.Debugf("choosing %s as version to save to env file", app.Recipe.Version)
if err := app.WriteRecipeVersion(app.Recipe.Version, false); err != nil {

View File

@ -208,7 +208,7 @@ Use "--status/-S" flag to query all servers for the live deployment status.`,
serverStat := allStats[app.Server]
headers := []string{"RECIPE", "DOMAIN"}
headers := []string{"RECIPE", "DOMAIN", "SERVER"}
if status {
headers = append(headers, []string{
"STATUS",
@ -228,7 +228,7 @@ Use "--status/-S" flag to query all servers for the live deployment status.`,
var rows [][]string
for _, appStat := range serverStat.Apps {
row := []string{appStat.Recipe, appStat.Domain}
row := []string{appStat.Recipe, appStat.Domain, appStat.Server}
if status {
chaosStatus := appStat.Chaos
if chaosStatus != "unknown" {
@ -256,20 +256,8 @@ Use "--status/-S" flag to query all servers for the live deployment status.`,
table.Rows(rows...)
if len(rows) > 0 {
fmt.Println(table)
if status {
fmt.Println(fmt.Sprintf(
"SERVER: %s | TOTAL APPS: %v | VERSIONED: %v | UNVERSIONED: %v | LATEST : %v | UPGRADE: %v",
app.Server,
serverStat.AppCount,
serverStat.VersionCount,
serverStat.UnversionedCount,
serverStat.LatestCount,
serverStat.UpgradeCount,
))
} else {
log.Infof("SERVER: %s TOTAL APPS: %v", app.Server, serverStat.AppCount)
if err := formatter.PrintTable(table); err != nil {
log.Fatal(err)
}
if len(allStats) > 1 && len(rows) > 0 {
@ -279,12 +267,6 @@ Use "--status/-S" flag to query all servers for the live deployment status.`,
alreadySeen[app.Server] = true
}
if len(allStats) > 1 {
totalServers := formatter.BoldStyle.Render("TOTAL SERVERS")
totalApps := formatter.BoldStyle.Render("TOTAL APPS")
log.Infof("%s: %v | %s: %v ", totalServers, totalServersCount, totalApps, totalAppsCount)
}
},
}

View File

@ -64,7 +64,6 @@ var AppNewCommand = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
recipe := internal.ValidateRecipe(args, cmd.Name())
var recipeVersion string
if !internal.Chaos {
if err := recipe.EnsureIsClean(); err != nil {
log.Fatal(err)
@ -74,41 +73,47 @@ var AppNewCommand = &cobra.Command{
log.Fatal(err)
}
}
}
if len(args) == 2 {
recipeVersion = args[1]
}
var recipeVersion string
if len(args) == 2 {
recipeVersion = args[1]
}
if recipeVersion == "" {
recipeVersions, err := recipe.GetRecipeVersions()
if err != nil {
log.Fatal(err)
}
if len(recipeVersions) > 0 {
latest := recipeVersions[len(recipeVersions)-1]
for tag := range latest {
recipeVersion = tag
}
if _, err := recipe.EnsureVersion(recipeVersion); err != nil {
log.Fatal(err)
}
} else {
if err := recipe.EnsureLatest(); err != nil {
log.Fatal(err)
}
}
} else {
if _, err := recipe.EnsureVersion(recipeVersion); err != nil {
log.Fatal(err)
}
var recipeVersions recipePkg.RecipeVersions
if recipeVersion == "" {
var err error
recipeVersions, err = recipe.GetRecipeVersions()
if err != nil {
log.Fatal(err)
}
}
if internal.Chaos && recipeVersion == "" {
if len(recipeVersions) > 0 {
latest := recipeVersions[len(recipeVersions)-1]
for tag := range latest {
recipeVersion = tag
}
if _, err := recipe.EnsureVersion(recipeVersion); err != nil {
log.Fatal(err)
}
} else {
if err := recipe.EnsureLatest(); err != nil {
log.Fatal(err)
}
}
if !internal.Chaos && recipeVersion != "" {
if _, err := recipe.EnsureVersion(recipeVersion); err != nil {
log.Fatal(err)
}
}
chaosVersion := config.CHAOS_DEFAULT
if internal.Chaos {
var err error
recipeVersion, err = recipe.ChaosVersion()
chaosVersion, err = recipe.ChaosVersion()
if err != nil {
log.Fatal(err)
}
@ -187,37 +192,20 @@ var AppNewCommand = &cobra.Command{
newAppServer = "local"
}
table, err := formatter.CreateTable()
if err != nil {
log.Fatal(err)
}
headers := []string{"SERVER", "DOMAIN", "RECIPE", "VERSION"}
table.Headers(headers...)
table.Row(newAppServer, appDomain, recipe.Name, recipeVersion)
log.Infof("new app '%s' created 🌞", recipe.Name)
fmt.Println("")
fmt.Println(table)
fmt.Println("")
fmt.Println("Configure this app:")
fmt.Println(fmt.Sprintf("\n abra app config %s", appDomain))
fmt.Println("")
fmt.Println("Deploy this app:")
fmt.Println(fmt.Sprintf("\n abra app deploy %s", appDomain))
log.Infof("%s created successfully (version: %s, chaos: %s)", appDomain, recipeVersion, chaosVersion)
if len(appSecrets) > 0 {
fmt.Println("")
fmt.Println("Generated secrets:")
fmt.Println("")
fmt.Println(secretsTable)
rows := [][]string{}
for k, v := range appSecrets {
rows = append(rows, []string{k, v})
}
overview := formatter.CreateOverview("SECRETS OVERVIEW", rows)
fmt.Println(overview)
log.Warnf(
"generated secrets %s shown again, please take note of them %s",
"secrets are %s shown again, please save them %s",
formatter.BoldStyle.Render("NOT"),
formatter.BoldStyle.Render("NOW"),
)

View File

@ -128,24 +128,35 @@ func showPSOutput(app appPkg.App, cl *dockerClient.Client, deployedVersion, chao
allContainerStats[containerStats["service"]] = containerStats
// NOTE(d1): don't clobber these variables for --machine output
dVersion := deployedVersion
cVersion := chaosVersion
if containerStats["service"] != "app" {
// NOTE(d1): don't repeat info which only relevant for the "app" service
dVersion = ""
cVersion = ""
}
row := []string{
containerStats["service"],
containerStats["image"],
containerStats["created"],
dVersion,
cVersion,
containerStats["status"],
containerStats["state"],
containerStats["ports"],
}
rows = append(rows, row)
}
if internal.MachineReadable {
jsonstring, err := json.Marshal(allContainerStats)
rendered, err := json.Marshal(allContainerStats)
if err != nil {
log.Fatal("unable to convert to JSON: %s", err)
}
fmt.Println(string(jsonstring))
fmt.Println(string(rendered))
return
}
@ -157,19 +168,18 @@ func showPSOutput(app appPkg.App, cl *dockerClient.Client, deployedVersion, chao
headers := []string{
"SERVICE",
"IMAGE",
"CREATED",
"VERSION",
"CHAOS",
"STATUS",
"STATE",
"PORTS",
}
table.
Headers(headers...).
Rows(rows...)
fmt.Println(table)
log.Infof("VERSION: %s CHAOS: %s", deployedVersion, chaosVersion)
if err := formatter.PrintTable(table); err != nil {
log.Fatal(err)
}
}
func init() {

View File

@ -127,7 +127,9 @@ var AppSecretGenerateCommand = &cobra.Command{
return
}
fmt.Println(table)
if err := formatter.PrintTable(table); err != nil {
log.Fatal(err)
}
log.Warnf(
"generated secrets %s shown again, please take note of them %s",
@ -394,7 +396,10 @@ var AppSecretLsCommand = &cobra.Command{
return
}
fmt.Println(table)
if err := formatter.PrintTable(table); err != nil {
log.Fatal(err)
}
return
}

View File

@ -63,7 +63,7 @@ var AppServicesCommand = &cobra.Command{
log.Fatal(err)
}
headers := []string{"SERVICE (SHORT)", "SERVICE (LONG)", "IMAGE"}
headers := []string{"SERVICE (SHORT)", "SERVICE (LONG)"}
table.Headers(headers...)
var rows [][]string
@ -80,7 +80,6 @@ var AppServicesCommand = &cobra.Command{
row := []string{
serviceShortName,
serviceLongName,
formatter.RemoveSha(container.Image),
}
rows = append(rows, row)
@ -89,7 +88,9 @@ var AppServicesCommand = &cobra.Command{
table.Rows(rows...)
if len(rows) > 0 {
fmt.Println(table)
if err := formatter.PrintTable(table); err != nil {
log.Fatal(err)
}
}
},
}

View File

@ -59,7 +59,10 @@ Passing "--prune/-p" does not remove those volumes.`,
chaosVersion = deployMeta.ChaosVersion
}
if err := internal.DeployOverview(app, []string{}, deployMeta.Version, chaosVersion); err != nil {
if err := internal.UndeployOverview(
app,
deployMeta.Version,
chaosVersion); err != nil {
log.Fatal(err)
}

View File

@ -2,7 +2,6 @@ package app
import (
"context"
"fmt"
"coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/autocomplete"
@ -43,7 +42,7 @@ var AppVolumeListCommand = &cobra.Command{
log.Fatal(err)
}
headers := []string{"name", "created", "mounted"}
headers := []string{"NAME", "ON SERVER"}
table, err := formatter.CreateTable()
if err != nil {
@ -54,14 +53,16 @@ var AppVolumeListCommand = &cobra.Command{
var rows [][]string
for _, volume := range volumes {
row := []string{volume.Name, volume.CreatedAt, volume.Mountpoint}
row := []string{volume.Name, volume.Mountpoint}
rows = append(rows, row)
}
table.Rows(rows...)
if len(rows) > 0 {
fmt.Println(table)
if err := formatter.PrintTable(table); err != nil {
log.Fatal(err)
}
return
}