Add --json to read-only commands (pr checks/files/commits/diff, secret/variable list) #112

Closed
opened 2026-06-11 00:08:49 +00:00 by stephen · 0 comments
Owner

Task

Add --json output to the read-only commands automation reaches for, routing the already-typed structs through output::print_json exactly as pr view / issue view do:

  • fj pr checks (combined_status: state, total_count, per-check statuses[]) — the canonical CI-gating query.
  • fj pr files (status, filename, additions, deletions).
  • fj pr commits (sha, subject, author).
  • fj pr diff — emit { "diff": "<text>" } (or document it as intentionally text-only and reject the flag explicitly).
  • fj secret list and fj variable list — emit [{name, updated_at, ...}] so config can be diffed.

Add a test asserting every view/inspect/list subcommand either accepts --json or is explicitly allow-listed as text-only, so the surface cannot silently regress.

Source: rasterstate/fj#109.

Priority

p1. fj pr checks --json | jq '.state' is the merge-gate / agent "is this PR green?" query; pr files --json backs path-scoped policy; secret/variable list --json back config diffing. These are the surfaces automation scripts first, and --json-fields (a global flag) is meaningless on them today because no JSON exists to project. High scripting-reliability and gh-parity value.

Reason

Each handler already builds structured data in memory and then flattens it to a table/text with no JSON branch (src/cli/pr_inspect.rs, src/cli/workflow_secret.rs, src/cli/workflow_variable.rs). The inconsistency is also internal and trap-like: pr view/issue view accept --json, so a scripter assumes the rest of pr does, builds a wrapper, and hits error: unexpected argument '--json' at runtime. gh returns JSON for all of these.

Acceptance

  • fj pr checks --json emits the combined-status struct (state, total_count, statuses).
  • fj pr files --json and fj pr commits --json emit the per-file / per-commit arrays.
  • fj pr diff --json either returns { "diff": "..." } or rejects with a clear "text-only" message (decision recorded in the help text).
  • fj secret list --json and fj variable list --json emit name/updated_at arrays.
  • --json-fields projection works against each new JSON output (it flows through print_json).
  • A regression test asserts every view/inspect/list subcommand accepts --json or is allow-listed text-only.
  • Wiremock coverage for the new JSON paths; cargo fmt --check, cargo clippy --all-targets --all-features -- -D warnings, cargo test --all pass.

Dependencies

None. API responses are already typed; this is surfacing them through the existing print_json path. Can be split per-command if sized down, but pr checks and secret/variable list are the highest-value first cuts.

Size

M

## Task Add `--json` output to the read-only commands automation reaches for, routing the already-typed structs through `output::print_json` exactly as `pr view` / `issue view` do: - `fj pr checks` (`combined_status`: state, total_count, per-check `statuses[]`) — the canonical CI-gating query. - `fj pr files` (status, filename, additions, deletions). - `fj pr commits` (sha, subject, author). - `fj pr diff` — emit `{ "diff": "<text>" }` (or document it as intentionally text-only and reject the flag explicitly). - `fj secret list` and `fj variable list` — emit `[{name, updated_at, ...}]` so config can be diffed. Add a test asserting every `view`/inspect/`list` subcommand either accepts `--json` or is explicitly allow-listed as text-only, so the surface cannot silently regress. Source: `rasterstate/fj#109`. ## Priority p1. `fj pr checks --json | jq '.state'` is the merge-gate / agent "is this PR green?" query; `pr files --json` backs path-scoped policy; `secret`/`variable list --json` back config diffing. These are the surfaces automation scripts first, and `--json-fields` (a global flag) is meaningless on them today because no JSON exists to project. High scripting-reliability and gh-parity value. ## Reason Each handler already builds structured data in memory and then flattens it to a table/text with no JSON branch (`src/cli/pr_inspect.rs`, `src/cli/workflow_secret.rs`, `src/cli/workflow_variable.rs`). The inconsistency is also internal and trap-like: `pr view`/`issue view` accept `--json`, so a scripter assumes the rest of `pr` does, builds a wrapper, and hits `error: unexpected argument '--json'` at runtime. `gh` returns JSON for all of these. ## Acceptance - [ ] `fj pr checks --json` emits the combined-status struct (state, total_count, statuses). - [ ] `fj pr files --json` and `fj pr commits --json` emit the per-file / per-commit arrays. - [ ] `fj pr diff --json` either returns `{ "diff": "..." }` or rejects with a clear "text-only" message (decision recorded in the help text). - [ ] `fj secret list --json` and `fj variable list --json` emit name/updated_at arrays. - [ ] `--json-fields` projection works against each new JSON output (it flows through `print_json`). - [ ] A regression test asserts every view/inspect/list subcommand accepts `--json` or is allow-listed text-only. - [ ] Wiremock coverage for the new JSON paths; `cargo fmt --check`, `cargo clippy --all-targets --all-features -- -D warnings`, `cargo test --all` pass. ## Dependencies None. API responses are already typed; this is surfacing them through the existing `print_json` path. Can be split per-command if sized down, but `pr checks` and `secret`/`variable list` are the highest-value first cuts. ## Size M
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rasterstate/fj#112
No description provided.