From 0564611c18e332c7006c37307f5002b971b4ce69 Mon Sep 17 00:00:00 2001 From: Thanatat Tamtan Date: Sun, 30 Aug 2026 13:23:52 +0700 Subject: [PATCH] chore: switch JSON to encoding/json/v2 CLI -ojson output, credential store, login/logout, and GitHub update checks use encoding/json/v2. Indented output uses jsontext.WithIndent plus a trailing newline to match the old Encoder. Pins github.com/deploys-app/api to the json/v2 + omitzero contract. --- Requested via Grok Work Prompter: ACS Prompter: ACS --- go.mod | 2 +- go.sum | 4 ++-- internal/auth/login.go | 6 +++--- internal/auth/login_test.go | 18 +++++++++--------- internal/auth/logout.go | 2 +- internal/auth/store.go | 7 ++++--- internal/runner/notification.go | 2 +- internal/runner/runner.go | 12 ++++++++---- internal/runner/update.go | 4 ++-- 9 files changed, 31 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 10fea73..463e473 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/deploys-app/deploys go 1.27.0 require ( - github.com/deploys-app/api v0.0.0-20260825022438-e754ba162e9f + github.com/deploys-app/api v0.0.0-20260830061839-bca440a0d649 github.com/moonrhythm/toon v0.0.0-20260702100246-6fcdad0a6a12 golang.org/x/mod v0.37.0 golang.org/x/oauth2 v0.14.0 diff --git a/go.sum b/go.sum index b8bb4d7..d037080 100644 --- a/go.sum +++ b/go.sum @@ -9,8 +9,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:W github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deploys-app/api v0.0.0-20260825022438-e754ba162e9f h1:zTvca8Pg0vLeKp5BMvkehMKOgq5uZ1ghtjvAk3CoCFQ= -github.com/deploys-app/api v0.0.0-20260825022438-e754ba162e9f/go.mod h1:QN5lioYbGyxSstxlyrvXrERJch7S2hnNCMNOVAu/6K0= +github.com/deploys-app/api v0.0.0-20260830061839-bca440a0d649 h1:hRNcjk6SNLvn7l4ZwvB4GcvtfeKzXK/vKxNJ6U2WKR0= +github.com/deploys-app/api v0.0.0-20260830061839-bca440a0d649/go.mod h1:QN5lioYbGyxSstxlyrvXrERJch7S2hnNCMNOVAu/6K0= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= diff --git a/internal/auth/login.go b/internal/auth/login.go index fea359e..d20e820 100644 --- a/internal/auth/login.go +++ b/internal/auth/login.go @@ -6,7 +6,7 @@ import ( "crypto/sha256" "crypto/subtle" "encoding/base64" - "encoding/json" + "encoding/json/v2" "errors" "fmt" "io" @@ -172,7 +172,7 @@ func discoverMetadata(ctx context.Context, authBase string) (metadata, error) { if resp.StatusCode != http.StatusOK { return m, fmt.Errorf("discover auth server: status %d", resp.StatusCode) } - if err := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)).Decode(&m); err != nil { + if err := json.UnmarshalRead(io.LimitReader(resp.Body, 1<<20), &m); err != nil { return m, fmt.Errorf("discover auth server: %w", err) } @@ -266,7 +266,7 @@ func registerClient(ctx context.Context, regEndpoint string) (string, error) { var out struct { ClientID string `json:"client_id"` } - if err := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)).Decode(&out); err != nil { + if err := json.UnmarshalRead(io.LimitReader(resp.Body, 1<<20), &out); err != nil { return "", fmt.Errorf("register client: %w", err) } if out.ClientID == "" { diff --git a/internal/auth/login_test.go b/internal/auth/login_test.go index c26286f..8a90590 100644 --- a/internal/auth/login_test.go +++ b/internal/auth/login_test.go @@ -4,7 +4,7 @@ import ( "context" "crypto/sha256" "encoding/base64" - "encoding/json" + "encoding/json/v2" "fmt" "net/http" "net/http/httptest" @@ -24,7 +24,7 @@ func fakeAuthServer(t *testing.T) (*httptest.Server, *authProbe) { var base string // set after the server starts mux.HandleFunc("/.well-known/oauth-authorization-server", func(w http.ResponseWriter, r *http.Request) { - json.NewEncoder(w).Encode(map[string]any{ + json.MarshalWrite(w, map[string]any{ "issuer": base, "authorization_endpoint": base + "/authorize", "token_endpoint": base + "/token", @@ -37,7 +37,7 @@ func fakeAuthServer(t *testing.T) (*httptest.Server, *authProbe) { mux.HandleFunc("/register", func(w http.ResponseWriter, r *http.Request) { probe.registered++ w.WriteHeader(http.StatusCreated) - json.NewEncoder(w).Encode(map[string]any{"client_id": "test-client"}) + json.MarshalWrite(w, map[string]any{"client_id": "test-client"}) }) mux.HandleFunc("/authorize", func(w http.ResponseWriter, r *http.Request) { q := r.URL.Query() @@ -57,7 +57,7 @@ func fakeAuthServer(t *testing.T) (*httptest.Server, *authProbe) { probe.mu.Unlock() if reject != "" && r.Form.Get("client_id") == reject { w.WriteHeader(http.StatusUnauthorized) - json.NewEncoder(w).Encode(map[string]string{"error": "invalid_client"}) + json.MarshalWrite(w, map[string]string{"error": "invalid_client"}) return } code := r.Form.Get("code") @@ -68,11 +68,11 @@ func fakeAuthServer(t *testing.T) (*httptest.Server, *authProbe) { sum := sha256.Sum256([]byte(verifier)) if verifier == "" || base64.RawURLEncoding.EncodeToString(sum[:]) != want { w.WriteHeader(http.StatusBadRequest) - json.NewEncoder(w).Encode(map[string]string{"error": "invalid_grant"}) + json.MarshalWrite(w, map[string]string{"error": "invalid_grant"}) return } probe.exchanged = true - json.NewEncoder(w).Encode(map[string]any{ + json.MarshalWrite(w, map[string]any{ "access_token": "deploys-api.test", "token_type": "Bearer", "expires_in": 604800, @@ -235,7 +235,7 @@ func TestDiscoverMetadataRejectsCrossOrigin(t *testing.T) { // Endpoints that are not same-origin as the issuer must be rejected so a // metadata doc cannot repoint the token endpoint at an exfiltration host. srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - json.NewEncoder(w).Encode(map[string]any{ + json.MarshalWrite(w, map[string]any{ "issuer": "http://127.0.0.1:1", // wrong issuer "authorization_endpoint": "https://evil.example/authorize", "token_endpoint": "https://evil.example/token", @@ -257,9 +257,9 @@ func TestRevoke(t *testing.T) { var body struct { Token string `json:"token"` } - json.NewDecoder(r.Body).Decode(&body) + json.UnmarshalRead(r.Body, &body) got = body.Token - json.NewEncoder(w).Encode(map[string]any{"ok": true}) + json.MarshalWrite(w, map[string]any{"ok": true}) })) defer srv.Close() diff --git a/internal/auth/logout.go b/internal/auth/logout.go index 4e2b2ef..9331c96 100644 --- a/internal/auth/logout.go +++ b/internal/auth/logout.go @@ -2,7 +2,7 @@ package auth import ( "context" - "encoding/json" + "encoding/json/v2" "fmt" "net/http" "strings" diff --git a/internal/auth/store.go b/internal/auth/store.go index 764270c..0abf42c 100644 --- a/internal/auth/store.go +++ b/internal/auth/store.go @@ -11,7 +11,8 @@ package auth import ( "crypto/rand" "encoding/hex" - "encoding/json" + "encoding/json/jsontext" + "encoding/json/v2" "errors" "fmt" "os" @@ -223,7 +224,7 @@ func (c *Credentials) Save() error { if err := prepareDir(filepath.Dir(path)); err != nil { return err } - b, err := json.MarshalIndent(c, "", " ") + b, err := json.Marshal(c, jsontext.WithIndent(" ")) if err != nil { return err } @@ -305,7 +306,7 @@ func SaveClientID(authBase, clientID string) error { } cc.Version = schemaVersion cc.Clients[authBase] = clientID - b, err := json.MarshalIndent(&cc, "", " ") + b, err := json.Marshal(&cc, jsontext.WithIndent(" ")) if err != nil { return err } diff --git a/internal/runner/notification.go b/internal/runner/notification.go index b217cb9..fd2d7a8 100644 --- a/internal/runner/notification.go +++ b/internal/runner/notification.go @@ -2,7 +2,7 @@ package runner import ( "context" - "encoding/json" + "encoding/json/v2" "errors" "fmt" "time" diff --git a/internal/runner/runner.go b/internal/runner/runner.go index 1ad4dda..2d909fe 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -2,7 +2,8 @@ package runner import ( "context" - "encoding/json" + "encoding/json/jsontext" + "encoding/json/v2" "errors" "flag" "fmt" @@ -54,9 +55,12 @@ func (rn Runner) print(v any) error { case "yaml": return yaml.NewEncoder(rn.output()).Encode(v) case "json": - enc := json.NewEncoder(rn.output()) - enc.SetIndent("", " ") - return enc.Encode(v) + b, err := json.Marshal(v, jsontext.WithIndent(" ")) + if err != nil { + return err + } + _, err = fmt.Fprintln(rn.output(), string(b)) + return err case "toon": b, err := toon.Marshal(v) if err != nil { diff --git a/internal/runner/update.go b/internal/runner/update.go index 1cc9c59..43fdbc3 100644 --- a/internal/runner/update.go +++ b/internal/runner/update.go @@ -2,7 +2,7 @@ package runner import ( "context" - "encoding/json" + "encoding/json/v2" "errors" "flag" "fmt" @@ -165,7 +165,7 @@ func fetchLatestVersion(ctx context.Context, url string) (string, error) { var body struct { TagName string `json:"tag_name"` } - if err := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)).Decode(&body); err != nil { + if err := json.UnmarshalRead(io.LimitReader(resp.Body, 1<<20), &body); err != nil { return "", err } if body.TagName == "" {