refactor: route command JSON output through PrintJSON helper
Summary
- Migrate all 21 remaining inline
json.Marshal/json.NewEncoder+ manual stdout-write call sites toIOStreams.PrintJSON. The helper was added in ba8e90ef to fix thenilslice →nullserialization bug, but only about half the commands adopted it; the rest kept marshaling inline. After this MR, every command's JSON output flows through one path. - Add a
forbidigogolangci-lint rule that bansjson.Marshal,json.MarshalIndent, andjson.NewEncoderoutside the helper, so this drift can't re-accumulate. - Annotate 10 legitimate non-stdout call sites (HTTP request bodies, on-disk caches, the git credential helper protocol,
git/stacked.gostorage, andPrintJSONitself) with//nolint:forbidigoplus a one-line reason.
Behavior change
Output for commands that previously pretty-printed JSON is now compact (single-line). The affected commands are variable export, mr note list, token create, cluster agent get-token, and workitems list. The bytes are semantically identical JSON, so any consumer (jq, scripts, parsers) behaves the same; only human-eyeballing the raw output changes. This brings them in line with every other command, which was already compact.
Test plan
-
go test ./...passes locally (verified) -
golangci-lint run ./...reports 0 issues locally (verified) - Spot-check a migrated command in JSON mode: e.g.
+ "glab mr list -F json | jq '.[0].iid'" +produces a sensible result - Spot-check a non-stdout
+ "json.Marshal" +site (e.g.+ "glab api projects/" +) still functions — those paths build HTTP request bodies, not user output
Edited by Kai Armstrong