fix: address coderabbit review findings
Add revoked field to auth token JSON output. Fix remotes.go to use injected writer instead of fmt.Println. Remove dead cliRenderTitle calls in backup.go. Handle --json for empty secrets list. Document 'configured' status in bootstrap DTO. Enrich rollback list JSON with domain and current_tag context. Part of #98.
- commit
- 952bc8bbb5be87f1336f4d890915d6936d66cef7
- author
- brice · · 2026-03-13 20:59 UTC
- parent
- 3dcd86a
- signature
- unsigned
6 files · +22 -11
M internal/adapters/dto/admin_bootstrap.go +1 -1
| @@ -12,7 +12,7 @@ type BootstrapRequest struct { | |||
| 12 | 12 | // BootstrapStep represents the result of one bootstrap step. | |
| 13 | 13 | type BootstrapStep struct { | |
| 14 | 14 | Name string `json:"name"` | |
| 15 | - | Status string `json:"status"` // "created", "updated", "noop", "failed" | |
| 15 | + | Status string `json:"status"` // "created", "configured", "updated", "noop", "failed" | |
| 16 | 16 | } | |
| 17 | 17 | ||
| 18 | 18 | // BootstrapResponse represents the result of a bootstrap operation. | |
| @@ -12,7 +12,7 @@ type BootstrapRequest struct { | |||||
| 12 | // BootstrapStep represents the result of one bootstrap step. | 12 | // BootstrapStep represents the result of one bootstrap step. | ||
| 13 | type BootstrapStep struct { | 13 | type BootstrapStep struct { | ||
| 14 | Name string `json:"name"` | 14 | Name string `json:"name"` | ||
| 15 | - | Status string `json:"status"` // "created", "updated", "noop", "failed" | 15 | + | Status string `json:"status"` // "created", "configured", "updated", "noop", "failed" |
| 16 | } | 16 | } | ||
| 17 | 17 | ||||
| 18 | // BootstrapResponse represents the result of a bootstrap operation. | 18 | // BootstrapResponse represents the result of a bootstrap operation. | ||
M internal/adapters/in/cli/auth.go +1 -0
| @@ -558,6 +558,7 @@ func runTokenList(configPath string, out io.Writer, jsonOut bool) error { | |||
| 558 | 558 | "scopes": t.Scopes, | |
| 559 | 559 | "created_at": t.IssuedAt, | |
| 560 | 560 | "expires_at": expiresAt, | |
| 561 | + | "revoked": t.Revoked, | |
| 561 | 562 | }) | |
| 562 | 563 | } | |
| 563 | 564 | return writeJSON(out, payload) | |
| @@ -558,6 +558,7 @@ func runTokenList(configPath string, out io.Writer, jsonOut bool) error { | |||||
| 558 | "scopes": t.Scopes, | 558 | "scopes": t.Scopes, | ||
| 559 | "created_at": t.IssuedAt, | 559 | "created_at": t.IssuedAt, | ||
| 560 | "expires_at": expiresAt, | 560 | "expires_at": expiresAt, | ||
| 561 | + | "revoked": t.Revoked, | |||
| 561 | }) | 562 | }) | ||
| 562 | } | 563 | } | ||
| 563 | return writeJSON(out, payload) | 564 | return writeJSON(out, payload) | ||
M internal/adapters/in/cli/backup.go +2 -3
| @@ -33,7 +33,8 @@ instance when --remote targeting is configured.`, | |||
| 33 | 33 | ||
| 34 | 34 | func newBackupListCmd() *cobra.Command { | |
| 35 | 35 | var jsonOut bool | |
| 36 | - | _ = cliRenderTitle("Backups") | |
| 36 | + | ||
| 37 | + | cliRenderTitle("Backups") | |
| 37 | 38 | ||
| 38 | 39 | cmd := &cobra.Command{ | |
| 39 | 40 | Use: "list [domain]", | |
| @@ -77,8 +78,6 @@ func printBackupJobs(out io.Writer, jobs []dto.BackupJob, jsonOut bool) error { | |||
| 77 | 78 | return writeJSON(out, jobs) | |
| 78 | 79 | } | |
| 79 | 80 | ||
| 80 | - | _ = cliRenderTitle("Backups") | |
| 81 | - | ||
| 82 | 81 | if err := cliWriteLine(out, cliRenderTitle("Backups")); err != nil { | |
| 83 | 82 | return err | |
| 84 | 83 | } | |
| @@ -33,7 +33,8 @@ instance when --remote targeting is configured.`, | |||||
| 33 | 33 | ||||
| 34 | func newBackupListCmd() *cobra.Command { | 34 | func newBackupListCmd() *cobra.Command { | ||
| 35 | var jsonOut bool | 35 | var jsonOut bool | ||
| 36 | - | _ = cliRenderTitle("Backups") | 36 | + | |
| 37 | + | cliRenderTitle("Backups") | |||
| 37 | 38 | ||||
| 38 | cmd := &cobra.Command{ | 39 | cmd := &cobra.Command{ | ||
| 39 | Use: "list [domain]", | 40 | Use: "list [domain]", | ||
| @@ -77,8 +78,6 @@ func printBackupJobs(out io.Writer, jobs []dto.BackupJob, jsonOut bool) error { | |||||
| 77 | return writeJSON(out, jobs) | 78 | return writeJSON(out, jobs) | ||
| 78 | } | 79 | } | ||
| 79 | 80 | ||||
| 80 | - | _ = cliRenderTitle("Backups") | |||
| 81 | - | ||||
| 82 | if err := cliWriteLine(out, cliRenderTitle("Backups")); err != nil { | 81 | if err := cliWriteLine(out, cliRenderTitle("Backups")); err != nil { | ||
| 83 | return err | 82 | return err | ||
| 84 | } | 83 | } | ||
M internal/adapters/in/cli/remotes.go +6 -6
| @@ -62,10 +62,10 @@ func runRemotesList(out io.Writer, jsonOut bool) error { | |||
| 62 | 62 | if jsonOut { | |
| 63 | 63 | return writeJSON(out, []map[string]any{}) | |
| 64 | 64 | } | |
| 65 | - | fmt.Println(styles.Theme.Muted.Render("No remotes configured")) | |
| 66 | - | fmt.Println() | |
| 67 | - | fmt.Println("Add a remote with:") | |
| 68 | - | fmt.Println(styles.Theme.Bold.Render(" gordon remotes add <name> <url>")) | |
| 65 | + | fmt.Fprintln(out, styles.Theme.Muted.Render("No remotes configured")) | |
| 66 | + | fmt.Fprintln(out) | |
| 67 | + | fmt.Fprintln(out, "Add a remote with:") | |
| 68 | + | fmt.Fprintln(out, styles.Theme.Bold.Render(" gordon remotes add <name> <url>")) | |
| 69 | 69 | return nil | |
| 70 | 70 | } | |
| 71 | 71 | ||
| @@ -88,8 +88,8 @@ func runRemotesList(out io.Writer, jsonOut bool) error { | |||
| 88 | 88 | return writeJSON(out, payload) | |
| 89 | 89 | } | |
| 90 | 90 | ||
| 91 | - | fmt.Println(styles.Theme.Title.Render("Saved Remotes")) | |
| 92 | - | fmt.Println() | |
| 91 | + | fmt.Fprintln(out, styles.Theme.Title.Render("Saved Remotes")) | |
| 92 | + | fmt.Fprintln(out) | |
| 93 | 93 | ||
| 94 | 94 | rows := make([][]string, 0, len(names)) | |
| 95 | 95 | for _, name := range names { | |
| @@ -62,10 +62,10 @@ func runRemotesList(out io.Writer, jsonOut bool) error { | |||||
| 62 | if jsonOut { | 62 | if jsonOut { | ||
| 63 | return writeJSON(out, []map[string]any{}) | 63 | return writeJSON(out, []map[string]any{}) | ||
| 64 | } | 64 | } | ||
| 65 | - | fmt.Println(styles.Theme.Muted.Render("No remotes configured")) | 65 | + | fmt.Fprintln(out, styles.Theme.Muted.Render("No remotes configured")) |
| 66 | - | fmt.Println() | 66 | + | fmt.Fprintln(out) |
| 67 | - | fmt.Println("Add a remote with:") | 67 | + | fmt.Fprintln(out, "Add a remote with:") |
| 68 | - | fmt.Println(styles.Theme.Bold.Render(" gordon remotes add <name> <url>")) | 68 | + | fmt.Fprintln(out, styles.Theme.Bold.Render(" gordon remotes add <name> <url>")) |
| 69 | return nil | 69 | return nil | ||
| 70 | } | 70 | } | ||
| 71 | 71 | ||||
| @@ -88,8 +88,8 @@ func runRemotesList(out io.Writer, jsonOut bool) error { | |||||
| 88 | return writeJSON(out, payload) | 88 | return writeJSON(out, payload) | ||
| 89 | } | 89 | } | ||
| 90 | 90 | ||||
| 91 | - | fmt.Println(styles.Theme.Title.Render("Saved Remotes")) | 91 | + | fmt.Fprintln(out, styles.Theme.Title.Render("Saved Remotes")) |
| 92 | - | fmt.Println() | 92 | + | fmt.Fprintln(out) |
| 93 | 93 | ||||
| 94 | rows := make([][]string, 0, len(names)) | 94 | rows := make([][]string, 0, len(names)) | ||
| 95 | for _, name := range names { | 95 | for _, name := range names { | ||
M internal/adapters/in/cli/rollback.go +5 -1
| @@ -120,7 +120,11 @@ func runRollbackList(ctx context.Context, w io.Writer, rollbackDomain string, js | |||
| 120 | 120 | ||
| 121 | 121 | func printRollbackTags(w io.Writer, rollbackDomain, currentTag string, tags []string, jsonOut bool) error { | |
| 122 | 122 | if jsonOut { | |
| 123 | - | return writeJSON(w, tags) | |
| 123 | + | return writeJSON(w, map[string]any{ | |
| 124 | + | "domain": rollbackDomain, | |
| 125 | + | "current_tag": currentTag, | |
| 126 | + | "tags": tags, | |
| 127 | + | }) | |
| 124 | 128 | } | |
| 125 | 129 | ||
| 126 | 130 | if _, err := fmt.Fprintf(w, "Available tags for %s:\n", styles.Theme.Bold.Render(rollbackDomain)); err != nil { | |
| @@ -120,7 +120,11 @@ func runRollbackList(ctx context.Context, w io.Writer, rollbackDomain string, js | |||||
| 120 | 120 | ||||
| 121 | func printRollbackTags(w io.Writer, rollbackDomain, currentTag string, tags []string, jsonOut bool) error { | 121 | func printRollbackTags(w io.Writer, rollbackDomain, currentTag string, tags []string, jsonOut bool) error { | ||
| 122 | if jsonOut { | 122 | if jsonOut { | ||
| 123 | - | return writeJSON(w, tags) | 123 | + | return writeJSON(w, map[string]any{ |
| 124 | + | "domain": rollbackDomain, | |||
| 125 | + | "current_tag": currentTag, | |||
| 126 | + | "tags": tags, | |||
| 127 | + | }) | |||
| 124 | } | 128 | } | ||
| 125 | 129 | ||||
| 126 | if _, err := fmt.Fprintf(w, "Available tags for %s:\n", styles.Theme.Bold.Render(rollbackDomain)); err != nil { | 130 | if _, err := fmt.Fprintf(w, "Available tags for %s:\n", styles.Theme.Bold.Render(rollbackDomain)); err != nil { | ||
M internal/adapters/in/cli/secrets.go +7 -0
| @@ -75,6 +75,13 @@ func runSecretsListCmd(cmd *cobra.Command, args []string, jsonOut bool) error { | |||
| 75 | 75 | } | |
| 76 | 76 | ||
| 77 | 77 | if totalSecrets == 0 { | |
| 78 | + | if jsonOut { | |
| 79 | + | return writeJSON(cmd.OutOrStdout(), map[string]any{ | |
| 80 | + | "domain": secretDomain, | |
| 81 | + | "keys": []string{}, | |
| 82 | + | "attachments": []any{}, | |
| 83 | + | }) | |
| 84 | + | } | |
| 78 | 85 | fmt.Println(styles.Theme.Muted.Render(fmt.Sprintf("No secrets configured for %s", secretDomain))) | |
| 79 | 86 | return nil | |
| 80 | 87 | } | |
| @@ -75,6 +75,13 @@ func runSecretsListCmd(cmd *cobra.Command, args []string, jsonOut bool) error { | |||||
| 75 | } | 75 | } | ||
| 76 | 76 | ||||
| 77 | if totalSecrets == 0 { | 77 | if totalSecrets == 0 { | ||
| 78 | + | if jsonOut { | |||
| 79 | + | return writeJSON(cmd.OutOrStdout(), map[string]any{ | |||
| 80 | + | "domain": secretDomain, | |||
| 81 | + | "keys": []string{}, | |||
| 82 | + | "attachments": []any{}, | |||
| 83 | + | }) | |||
| 84 | + | } | |||
| 78 | fmt.Println(styles.Theme.Muted.Render(fmt.Sprintf("No secrets configured for %s", secretDomain))) | 85 | fmt.Println(styles.Theme.Muted.Render(fmt.Sprintf("No secrets configured for %s", secretDomain))) | ||
| 79 | return nil | 86 | return nil | ||
| 80 | } | 87 | } | ||