Two competing JSON mechanisms, plus dead JSON branches in milestone.rs #38
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-250then identical:252-255view()—:298-301then identical:303-306create()—: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.
Fixed by #48 (merged).
Verified on main:
release’s competingOutputFormatenum and--formatflag are deleted — it routes through the global--jsonlike everything else (one pretty-printed shape CLI-wide).deploy statusno longer prints a header + raw pretty-JSON dump; it renders fields viaoutput::detailin human mode and echoes the payload under--json. Same for therelease changelogandregistry token listad-hoc fallbacks.- The three duplicate/unreachable
is_jsonblocks inmilestone.rsare gone (0is_jsonreferences remain in that file). - Envelope inconsistency is resolved by construction:
Response::read/items/ok/deleted/gateare 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.