Watch
0
0
Fork
You've already forked hyperhive
0

hive-forge: dedup the --json refusal into refuse_json(), test it, cover attachment-get/artifact-get too

This commit is contained in:
damocles 2026-10-04 08:10:43 +02:00
commit e18497bb70
8 changed files with 58 additions and 27 deletions

View file

@ -50,7 +50,7 @@ pub mod view;
use std::fmt::Write as _;
use anyhow::Result;
use anyhow::{Result, bail};
use forgejo_api::structs::{Attachment, Reaction};
use serde::Deserialize;
use serde_json::{Value, json};
@ -67,6 +67,19 @@ pub(crate) fn print_json(v: &Value) -> Result<()> {
Ok(())
}
/// Error out when the global `--json` flag is set on a verb that has no
/// structured output to give it — a silently-ignored flag reads as "this is
/// JSON" when it is actually prose or raw bytes, which is worse than a loud
/// refusal. `why` names what the verb prints instead, e.g. `"only the plain
/// name list"`; `verb` is the subcommand name as the operator typed it
/// (`"branches"`, `"pr diff"`, …), for the error message.
pub(crate) fn refuse_json(json_mode: bool, verb: &str, why: &str) -> Result<()> {
if json_mode {
bail!("hive-forge {verb}: --json is not supported for this verb — {why}");
}
Ok(())
}
/// Format an optional timestamp as its RFC 3339 string — the shape the
/// raw API emitted, so output stays stable across the typed-client
/// port. `None` (and the never-in-practice unformattable timestamp)
@ -580,7 +593,20 @@ pub(crate) fn attachment_json(assets: Option<&[Attachment]>) -> Vec<Value> {
#[cfg(test)]
mod tests {
use super::{NullableVec, pct_encode, reviewed_older_head};
use super::{NullableVec, pct_encode, refuse_json, reviewed_older_head};
#[test]
fn refuse_json_bails_with_the_verb_and_reason() {
let err = refuse_json(true, "branches", "only the plain name list").unwrap_err();
let msg = err.to_string();
assert!(msg.contains("branches"), "{msg}");
assert!(msg.contains("only the plain name list"), "{msg}");
}
#[test]
fn refuse_json_passes_through_when_json_mode_is_off() {
assert!(refuse_json(false, "branches", "only the plain name list").is_ok());
}
#[test]
fn nullable_vec_treats_a_json_null_as_empty() {