cli: standardize on printJSON for indented JSON output · Entire
cli: standardize on printJSON for indented JSON output
9346b6f·
Soph·2w ago·9 files·+26 added/-66 removed
Package cli had five copies of encode-with-SetIndent — printJSON, writeJSON, and three per-report wrappers. Keep printJSON (already the most used, in corecmd/status) and route the token/attribution reports and test fixtures through it. Encode-failure wording unifies to "encode output".
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Sessions
351ee2316125View transcript
Changes
9
cmd/entire/cli
Mattribution.go+3/-13
- Mcheckpoint_tokens.go+1/-11
- Mgrant_wiring_test.go+1/-1
- Mlist_pagination_test.go+2/-2
- Mrepo_clone_test.go+1/-1
- Mrepo_mirror_test.go+6/-6
- Mresolveref_test.go+10/-10
- Msession_tokens.go+1/-11
- Mtokens_profile.go+1/-11
3 unmodified lines
4
5
6
7
7
8
9
224 unmodified lines
234
235
236
238
237
238
239
240
24 unmodified lines
265
266
267
269
268
269
270
271
20 unmodified lines
292
293
294
296
295
296
297
298
1126 unmodified lines
1425
1426
1427
1429
1430
1431
1432
1433
1434
1435
1436
1437
3 unmodified lines
"bufio"
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
224 unmodified lines
}
if opts.JSON {
return writeJSON(w, result)
return printJSON(w, result)
}
renderAttributionBlame(w, result, opts.LineFlag, opts.Long)
return nil
24 unmodified lines
if !hasLine {
if opts.JSON {
return writeJSON(w, result)
return printJSON(w, result)
}
renderAttributionFileWhy(w, result)
return nil
20 unmodified lines
Line: *selected,
Checkpoints: checkpointContextsForLines([]attributionLine{*selected}, result.Checkpoints),
}
return writeJSON(w, payload)
return printJSON(w, payload)
}
renderAttributionLineWhy(w, result.File, *selected)
return nil
1126 unmodified lines
func isZeroCommit(sha string) bool {
return sha == "" || strings.Trim(sha, "0") == ""
}
func writeJSON(w io.Writer, value any) error {
encoder := json.NewEncoder(w)
encoder.SetIndent("", " ")
if err := encoder.Encode(value); err != nil {
return fmt.Errorf("encode json: %w", err)
}
return nil
}
Mcmd/entire/cli/attribution.go+3/-13
1 unmodified line
2
3
4
5
5
6
7
116 unmodified lines
124
125
126
128
127
128
129
130
414 unmodified lines
545
546
547
549
550
551
552
553
554
555
556
557
548
549
550
1 unmodified line
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
116 unmodified lines
}
if jsonOutput {
return writeCheckpointTokensJSON(cmd.OutOrStdout(), report)
return printJSON(cmd.OutOrStdout(), report)
}
if agentBrief {
writeCheckpointTokensAgentBrief(cmd.OutOrStdout(), report)
414 unmodified lines
return "Total tokens include cache/context replay; use the cache/context replay delta below before treating total direction as work saved or added."
}
func writeCheckpointTokensJSON(w io.Writer, report checkpointTokensReport) error {
enc := json.NewEncoder(w)
enc.SetIndent("", " ")
if err := enc.Encode(report); err != nil {
return fmt.Errorf("failed to encode checkpoint token report: %w", err)
}
return nil
}
func writeCheckpointTokensText(w io.Writer, report checkpointTokensReport) {
fmt.Fprintln(w, "Checkpoint tokens")
fmt.Fprintln(w)
Mcmd/entire/cli/checkpoint_tokens.go+1/-11
29 unmodified lines
30
31
32
33
33
34
35
36
29 unmodified lines
return func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet && strings.Contains(r.URL.Path, "/identity/handles/") {
w.Header().Set("Content-Type", "application/json")
if err := writeJSON(w, &coreapi.ResolvedIdentity{
if err := printJSON(w, &coreapi.ResolvedIdentity{
AccountId: wiringGranteeULID,
Provider: providerGitHub,
Handle: "alice",
Mcmd/entire/cli/grant_wiring_test.go+1/-1
34 unmodified lines
35
36
37
38
38
39
40
41
47 unmodified lines
89
90
91
92
92
93
94
95
34 unmodified lines
default:
t.Errorf("unexpected cursor %q", cursor)
}
if err := writeJSON(w, &body); err != nil {
if err := printJSON(w, &body); err != nil {
t.Errorf("encode orgs: %v", err)
}
}))
47 unmodified lines
default:
t.Errorf("unexpected pageToken %q", token)
if err := writeJSON(w, &body); err != nil {
if err := printJSON(w, &body); err != nil {
t.Errorf("encode mirrors: %v", err)
}
}))
Mcmd/entire/cli/list_pagination_test.go+2/-2
200 unmodified lines
201
202
203
204
204
205
206
207
200 unmodified lines
{Owner: "entirehq", Repo: "entire-api", ClusterHost: "aws-eu-west-1.entire.io"},
{Owner: "entirehq", Repo: "entire-cli", ClusterHost: "aws-us-east-2.entire.io"},
}}
if err := writeJSON(w, body); err != nil {
if err := printJSON(w, body); err != nil {
t.Errorf("encode response: %v", err)
}
}))
Mcmd/entire/cli/repo_clone_test.go+1/-1
141 unmodified lines
142
143
144
145
145
146
147
148
149
150
151
151
152
153
154
172 unmodified lines
327
328
329
330
330
331
332
333
334
334
335
336
337
248 unmodified lines
586
587
588
589
589
590
591
592
17 unmodified lines
610
611
612
613
613
614
615
616
141 unmodified lines
return
}
w.WriteHeader(http.StatusCreated)
if err := writeJSON(w, created); err != nil {
if err := printJSON(w, created); err != nil {
t.Errorf("encode created response: %v", err)
}
}
case r.Method == http.MethodGet && strings.HasPrefix(r.URL.Path, "/api/v1/mirrors/"):
m := &coreapi.Mirror{}
m.Status = coreapi.NewOptMirrorStatus(coreapi.MirrorStatusReady)
if err := writeJSON(w, m); err != nil {
if err := printJSON(w, m); err != nil {
t.Errorf("encode mirror response: %v", err)
}
}
default:
172 unmodified lines
w.Header().Set("Content-Type", "application/json")
switch r.URL.Path {
case "/api/v1/mirrors/available":
if err := writeJSON(w, &coreapi.ListAvailableMirrorsOutputBody{Available: available}); err != nil {
if err := printJSON(w, &coreapi.ListAvailableMirrorsOutputBody{Available: available}); err != nil {
t.Errorf("encode available response: %v", err)
}
case mirrorsAPIPath:
if err := writeJSON(w, &coreapi.ListMirrorsOutputBody{Mirrors: mirrors}); err != nil {
if err := printJSON(w, &coreapi.ListMirrorsOutputBody{Mirrors: mirrors}); err != nil {
t.Errorf("encode mirrors response: %v", err)
}
default:
248 unmodified lines
c, _ := resolveTestClient(t, func(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
gotCluster, gotProvider, gotOwner = q.Get("cluster"), q.Get("provider"), q.Get("owner")
if err := writeJSON(w, &coreapi.ListMirrorsOutputBody{Mirrors: []coreapi.Mirror{
if err := printJSON(w, &coreapi.ListMirrorsOutputBody{Mirrors: []coreapi.Mirror{
{MirrorId: otherULID, Owner: "entirehq", Repo: "other", ClusterHost: "aws-eu-central-1.entire.io"},
{MirrorId: mirrorULID, Owner: "entirehq", Repo: "entire-api", ClusterHost: "aws-eu-central-1.entire.io"},
}}); err != nil {
t.Errorf("encode mirrors: %v", err)
}
}))
17 unmodified lines
t.Run("no matching repo is a friendly error", func(t *testing.T) {
t.Parallel()
c, _ := resolveTestClient(t, func(w http.ResponseWriter, _ *http.Request) {
if err := writeJSON(w, &coreapi.ListMirrorsOutputBody{Mirrors: []coreapi.Mirror{
if err := printJSON(w, &coreapi.ListMirrorsOutputBody{Mirrors: []coreapi.Mirror{
{MirrorId: otherULID, Owner: "entirehq", Repo: "other", ClusterHost: "aws-eu-central-1.entire.io"},
}}); err != nil {
t.Errorf("encode mirrors: %v", err)
}
}))
Mcmd/entire/cli/repo_mirror_test.go+6/-6
68 unmodified lines
69 70 71 72 72 73 74 75 15 unmodified lines
91 92 93 94 94 95 96 97 31 unmodified lines
129 130 131 132 132 133 134 135 15 unmodified lines
151 152 153 154 154 155 156 157 51 unmodified lines
209 210 211 212 212 213 214 215 17 unmodified lines
233 234 235 236 236 237 238 239 28 unmodified lines
268 269 270 271 271 272 273 274 12 unmodified lines
287 288 289 290 290 291 292 293 23 unmodified lines
317 318 319 320 320 321 322 323 44 unmodified lines
368 369 370 371 371 372 373 374
68 unmodified lines
var gotName string c, calls := resolveTestClient(t, func(w http.ResponseWriter, r *http.Request) { gotName = r.URL.Query().Get("name") if err := writeJSON(w, &coreapi.ListOrgsOutputBody{Org: coreapi.NewOptOrg(coreapi.Org{ID: ulidOrgGlobex, Name: "globex"})}); err != nil { if err := printJSON(w, &coreapi.ListOrgsOutputBody{Org: coreapi.NewOptOrg(coreapi.Org{ID: ulidOrgGlobex, Name: "globex"})}); err != nil { t.Errorf("encode org: %v", err) } }) 15 unmodified lines
t.Run("unknown name is a friendly error", func(t *testing.T) { t.Parallel() c, _ := resolveTestClient(t, func(w http.ResponseWriter, _ *http.Request) { if err := writeJSON(w, &coreapi.ListOrgsOutputBody{}); err != nil { if err := printJSON(w, &coreapi.ListOrgsOutputBody{}); err != nil { t.Errorf("encode empty: %v", err) } }) 31 unmodified lines
var gotName string c, calls := resolveTestClient(t, func(w http.ResponseWriter, r *http.Request) { gotName = r.URL.Query().Get("name") if err := writeJSON(w, &coreapi.ListProjectsOutputBody{Project: matched}); err != nil { if err := printJSON(w, &coreapi.ListProjectsOutputBody{Project: matched}); err != nil { t.Errorf("encode project: %v", err) } }) 15 unmodified lines
t.Run("unknown name is a friendly error", func(t *testing.T) { t.Parallel() c, _ := resolveTestClient(t, func(w http.ResponseWriter, _ *http.Request) { if err := writeJSON(w, &coreapi.ListProjectsOutputBody{}); err != nil { if err := printJSON(w, &coreapi.ListProjectsOutputBody{}); err != nil { t.Errorf("encode empty: %v", err) } }) 51 unmodified lines
// which is only populated for an unfiltered page. Reading repos
// here was the COR-699 bug, so the fixture must mirror the real
// server's singular field to keep that regression covered.
if err := writeJSON(w, &coreapi.ListProjectReposOutputBody{Repo: coreapi.NewOptRepo(coreapi.Repo{ID: ulidRepoWeb, Name: "web"})}); err != nil {
if err := printJSON(w, &coreapi.ListProjectReposOutputBody{Repo: coreapi.NewOptRepo(coreapi.Repo{ID: ulidRepoWeb, Name: "web"})}); err != nil {
t.Errorf("encode repo: %v", err)
}
})
17 unmodified lines
t.Run("unknown name is a friendly error", func(t *testing.T) { t.Parallel() c, _ := resolveTestClient(t, func(w http.ResponseWriter, _ *http.Request) { if err := writeJSON(w, &coreapi.ListProjectReposOutputBody{}); err != nil { if err := printJSON(w, &coreapi.ListProjectReposOutputBody{}); err != nil { t.Errorf("encode empty: %v", err) } }) 28 unmodified lines
t.Run("handle resolves via exactly one call", func(t *testing.T) { t.Parallel() c, calls := resolveTestClient(t, func(w http.ResponseWriter, _ *http.Request) { if err := writeJSON(w, &coreapi.ResolvedIdentity{AccountId: ulidResolvedAcct, Provider: "github", Handle: "alice"}); err != nil { if err := printJSON(w, &coreapi.ResolvedIdentity{AccountId: ulidResolvedAcct, Provider: "github", Handle: "alice"}); err != nil { t.Errorf("encode identity: %v", err) } }) 12 unmodified lines
t.Run("empty resolved account id is an error", func(t *testing.T) { t.Parallel() c, _ := resolveTestClient(t, func(w http.ResponseWriter, _ *http.Request) { if err := writeJSON(w, &coreapi.ResolvedIdentity{AccountId: "", Provider: "github", Handle: "alice"}); err != nil { if err := printJSON(w, &coreapi.ResolvedIdentity{AccountId: "", Provider: "github", Handle: "alice"}); err != nil { t.Errorf("encode identity: %v", err) } }) 23 unmodified lines
t.Run("handle resolves to the provider user id in one call", func(t *testing.T) { t.Parallel() c, calls := resolveTestClient(t, func(w http.ResponseWriter, _ *http.Request) { if err := writeJSON(w, &coreapi.ResolvedIdentity{AccountId: ulidResolvedAcct, Provider: providerGitHub, Handle: "alice", ProviderUserId: "12345"}); err != nil { if err := printJSON(w, &coreapi.ResolvedIdentity{AccountId: ulidResolvedAcct, Provider: providerGitHub, Handle: "alice", ProviderUserId: "12345"}); err != nil { t.Errorf("encode identity: %v", err) } }) 44 unmodified lines
t.Run("empty provider user id is an error", func(t *testing.T) { t.Parallel() c, _ := resolveTestClient(t, func(w http.ResponseWriter, _ *http.Request) { if err := writeJSON(w, &coreapi.ResolvedIdentity{AccountId: ulidResolvedAcct, Provider: providerGitHub, Handle: "alice", ProviderUserId: ""}); err != nil { if err := printJSON(w, &coreapi.ResolvedIdentity{AccountId: ulidResolvedAcct, Provider: providerGitHub, Handle: "alice", ProviderUserId: ""}); err != nil { t.Errorf("encode identity: %v", err) } })