Partial implementation of machine readable output.

- Implement global flag for machine readable output.
- Add machine readable output (as JSON) to list command.
This commit is contained in:
Cassowary 2022-12-03 23:09:45 -08:00 committed by Gitea
parent 47f3d2638b
commit 82866cd213
2 changed files with 91 additions and 72 deletions

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"encoding/json"
"fmt" "fmt"
"sort" "sort"
"strings" "strings"
@ -39,22 +40,22 @@ var listAppServerFlag = &cli.StringFlag{
} }
type appStatus struct { type appStatus struct {
server string Server string `json:"server"`
recipe string Recipe string `json:"recipe"`
appName string AppName string `json:"appName"`
domain string Domain string `json:"domain"`
status string Status string `json:"status"`
version string Version string `json:"version"`
upgrade string Upgrade string `json:"upgrade"`
} }
type serverStatus struct { type serverStatus struct {
apps []appStatus Apps []appStatus `json:"apps"`
appCount int AppCount int `json:"appCount"`
versionCount int VersionCount int `json:"versionCount"`
unversionedCount int UnversionedCount int `json:"unversionedCount"`
latestCount int LatestCount int `json:"latestCount"`
upgradeCount int UpgradeCount int `json:"upgradeCount"`
} }
var appListCommand = cli.Command{ var appListCommand = cli.Command{
@ -71,6 +72,7 @@ can take some time.
`, `,
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag, internal.DebugFlag,
internal.MachineReadableFlag,
statusFlag, statusFlag,
listAppServerFlag, listAppServerFlag,
recipeFlag, recipeFlag,
@ -135,7 +137,7 @@ can take some time.
} }
appStats := appStatus{} appStats := appStatus{}
stats.appCount++ stats.AppCount++
totalAppsCount++ totalAppsCount++
if status { if status {
@ -150,13 +152,13 @@ can take some time.
if statusMeta["status"] != "" { if statusMeta["status"] != "" {
status = statusMeta["status"] status = statusMeta["status"]
} }
stats.versionCount++ stats.VersionCount++
} else { } else {
stats.unversionedCount++ stats.UnversionedCount++
} }
appStats.status = status appStats.Status = status
appStats.version = version appStats.Version = version
var newUpdates []string var newUpdates []string
if version != "unknown" { if version != "unknown" {
@ -184,81 +186,88 @@ can take some time.
if len(newUpdates) == 0 { if len(newUpdates) == 0 {
if version == "unknown" { if version == "unknown" {
appStats.upgrade = "unknown" appStats.Upgrade = "unknown"
} else { } else {
appStats.upgrade = "latest" appStats.Upgrade = "latest"
stats.latestCount++ stats.LatestCount++
} }
} else { } else {
newUpdates = internal.ReverseStringList(newUpdates) newUpdates = internal.ReverseStringList(newUpdates)
appStats.upgrade = strings.Join(newUpdates, "\n") appStats.Upgrade = strings.Join(newUpdates, "\n")
stats.upgradeCount++ stats.UpgradeCount++
} }
} }
appStats.server = app.Server appStats.Server = app.Server
appStats.recipe = app.Recipe appStats.Recipe = app.Recipe
appStats.appName = app.Name appStats.AppName = app.Name
appStats.domain = app.Domain appStats.Domain = app.Domain
stats.apps = append(stats.apps, appStats) stats.Apps = append(stats.Apps, appStats)
} }
allStats[app.Server] = stats allStats[app.Server] = stats
} }
if internal.MachineReadable {
alreadySeen := make(map[string]bool) jsonstring, err := json.Marshal(allStats)
for _, app := range apps { if err != nil {
if _, ok := alreadySeen[app.Server]; ok { fmt.Println("Error marshalling data to JSON:")
continue fmt.Println(err)
} else {
fmt.Println(string(jsonstring))
} }
} else {
serverStat := allStats[app.Server] alreadySeen := make(map[string]bool)
for _, app := range apps {
tableCol := []string{"recipe", "domain"} if _, ok := alreadySeen[app.Server]; ok {
if status { continue
tableCol = append(tableCol, []string{"status", "version", "upgrade"}...)
}
table := formatter.CreateTable(tableCol)
for _, appStat := range serverStat.apps {
tableRow := []string{appStat.recipe, appStat.domain}
if status {
tableRow = append(tableRow, []string{appStat.status, appStat.version, appStat.upgrade}...)
} }
table.Append(tableRow)
}
if table.NumLines() > 0 { serverStat := allStats[app.Server]
table.Render()
tableCol := []string{"recipe", "domain"}
if status { if status {
fmt.Println(fmt.Sprintf( tableCol = append(tableCol, []string{"status", "version", "upgrade"}...)
"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 {
fmt.Println(fmt.Sprintf("server: %s | total apps: %v", app.Server, serverStat.appCount))
} }
table := formatter.CreateTable(tableCol)
for _, appStat := range serverStat.Apps {
tableRow := []string{appStat.Recipe, appStat.Domain}
if status {
tableRow = append(tableRow, []string{appStat.Status, appStat.Version, appStat.Upgrade}...)
}
table.Append(tableRow)
}
if table.NumLines() > 0 {
table.Render()
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 {
fmt.Println(fmt.Sprintf("server: %s | total apps: %v", app.Server, serverStat.AppCount))
}
}
if len(allStats) > 1 && table.NumLines() > 0 {
fmt.Println() // newline separator for multiple servers
}
alreadySeen[app.Server] = true
} }
if len(allStats) > 1 && table.NumLines() > 0 { if len(allStats) > 1 {
fmt.Println() // newline separator for multiple servers fmt.Println(fmt.Sprintf("total servers: %v | total apps: %v ", totalServersCount, totalAppsCount))
} }
alreadySeen[app.Server] = true
} }
if len(allStats) > 1 {
fmt.Println(fmt.Sprintf("total servers: %v | total apps: %v ", totalServersCount, totalAppsCount))
}
return nil return nil
}, },
} }

View File

@ -243,6 +243,16 @@ var DebugFlag = &cli.BoolFlag{
Usage: "Show DEBUG messages", Usage: "Show DEBUG messages",
} }
// MachineReadable stores the variable from MachineReadableFlag
var MachineReadable bool
// MachineReadableFlag turns on/off machine readable output where supported
var MachineReadableFlag = &cli.BoolFlag{
Name: "machine, m",
Destination: &MachineReadable,
Usage: "Output in a machine-readable format (where supported)",
}
// RC signifies the latest release candidate // RC signifies the latest release candidate
var RC bool var RC bool