ref:main

Two competing JSON mechanisms, plus dead JSON branches in milestone.rs #38

closed Opened by cole.christensen@gmail.com

Links

No links yet.

release list --format json bypasses the global flag

src/commands/release.rs:8-12, 26-29, 269-272 defines its own OutputFormat enum. So anvil release list --format json works while anvil release list --json is silently ignored, and --format exists on this one command and nowhere else. It also serializes with to_string (compact) while output::print_json uses to_string_pretty — two JSON shapes from one CLI.

deploy status prints raw JSON in human mode

src/commands/deploy.rs:164-165:

output::header(&format!("Deployment status ({org}/{name})"));
println!("{}", serde_json::to_string_pretty(&resp)?);

A human gets an unformatted dump; and under --json the ANSI-bold header is emitted first, so the output is not valid JSON. Same fallback at release.rs:689 (changelog) and registry.rs:154 (token list prints an ad-hoc {id} {name} [{scopes}] line format, bypassing both the table renderer and JSON mode).

Unreachable duplicate JSON branches

src/commands/milestone.rs has three functions with duplicated is_json() blocks where the second can never run:

  • list():247-250 then identical :252-255
  • view():298-301 then identical :303-306
  • create():222-225 (print_json) then :234-237 (json_ok)

Because of the third, milestone create --json emits a bare server payload while milestone edit/close/reopen/delete --json emit {"ok":true,…} envelopes (:157, :178, :193) — inconsistent within one file.

Envelope inconsistency across mutations

Three shapes for “I mutated something”: json_ok("label", resp) (label.rs:168), json_ok("deleted", json!(id)) (label.rs:215, milestone.rs:194, board.rs:215), raw print_json (milestone.rs:223, pr.rs:539), and a hand-rolled {"ok":true,...} that does not use json_ok (requirement.rs:1849-1855).

Also: inconsistent handling of “you gave me no fields”

Exit 0 with a warning: pr.rs:526-529, issue.rs:554-557, release.rs:447-450. Exit 1 with an error: epic.rs:390-392, registry.rs:88-90, runner.rs:1815, :1952. No check at all (PATCHes an empty body): label edit (label.rs:175-205), milestone edit (milestone.rs:135-163).

Found during a CLI-wide consistency audit.

colechristensen cole.christensen@gmail.com commented 2026-07-26 20:07

Fixed by #48 (merged).

Verified on main:

  • release’s competing OutputFormat enum and --format flag are deleted — it routes through the global --json like everything else (one pretty-printed shape CLI-wide).
  • deploy status no longer prints a header + raw pretty-JSON dump; it renders fields via output::detail in human mode and echoes the payload under --json. Same for the release changelog and registry token list ad-hoc fallbacks.
  • The three duplicate/unreachable is_json blocks in milestone.rs are gone (0 is_json references remain in that file).
  • Envelope inconsistency is resolved by construction: Response::read / items / ok / deleted / gate are the only shapes, and mutations no longer double-nest the server envelope.

One sub-item not covered here: the “inconsistent handling of you gave me no fields” note (exit 0 + warn in pr/issue/release edit vs exit 1 elsewhere vs no check in label/milestone edit) is still present. That is a command-consistency issue rather than a JSON one — tracked under #35.