hive-forge: add # Errors docs on every verb's pub fn run (closes #816)

systemic gap argus flagged on PR #798 (timeline verb). every `pub fn
run` in hive-forge/src/verbs/*.rs lacked a `# Errors` block —
violates Rust API guidelines + obscures the failure surface for
operators reading the source.

uniform doc per verb category:
- pure GET + print verbs: "transport error from the Forgejo REST call
  + I/O error from stdout"
- body-from-file verbs (comment/comment_edit/issue_create/issue_edit/
  pr_create): adds 'I/O error from --body-file/stdin input'
- file-upload verbs (attach-issue, attach-comment): adds 'file
  read/exist check'
- pr_create: also mentions the --push shellout

23 `pub fn run` signatures touched. no behaviour change; pure
documentation sweep. cargo test green (38 tests).
This commit is contained in:
damocles 2026-05-31 15:57:19 +02:00 committed by mara
commit 1195bfbe11
23 changed files with 130 additions and 0 deletions

View file

@ -21,6 +21,11 @@ pub struct Args {
remove: bool,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
let current = client.get_json(&format!("/repos/{repo}/issues/{}", args.number))?;

View file

@ -26,6 +26,12 @@ pub struct CommentArgs {
file: PathBuf,
}
/// # Errors
///
/// Returns an error if the input file doesn't exist or can't be
/// read. Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the browser download URL to stdout.
pub fn run_issue(client: &Client, args: IssueArgs) -> Result<()> {
if !args.file.is_file() {
bail!(
@ -42,6 +48,12 @@ pub fn run_issue(client: &Client, args: IssueArgs) -> Result<()> {
Ok(())
}
/// # Errors
///
/// Returns an error if the input file doesn't exist or can't be
/// read. Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the browser download URL to stdout.
pub fn run_comment(client: &Client, args: CommentArgs) -> Result<()> {
if !args.file.is_file() {
bail!(

View file

@ -12,6 +12,11 @@ pub struct Args {
pattern: Option<String>,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
let v = client.get_json(&format!("/repos/{repo}/branches?limit=100"))?;

View file

@ -13,6 +13,11 @@ pub struct Args {
number: u64,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
let resp = client.patch_json(

View file

@ -21,6 +21,12 @@ pub struct Args {
body_file: Option<String>,
}
/// # Errors
///
/// Propagates any I/O error from the body input (`--body-file`,
/// stdin), any transport error from the Forgejo REST call (network
/// unreachable, 4xx/5xx response, token missing/invalid), and any
/// I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let body = body::resolve_required(args.body.as_deref(), args.body_file.as_deref(), "comment")?;
let repo = client.repo();

View file

@ -21,6 +21,12 @@ pub struct Args {
body_file: Option<String>,
}
/// # Errors
///
/// Propagates any I/O error from the body input (`--body-file`,
/// stdin), any transport error from the Forgejo REST call (network
/// unreachable, 4xx/5xx response, token missing/invalid), and any
/// I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let body = body::resolve_required(
args.body.as_deref(),

View file

@ -14,6 +14,11 @@ pub struct Args {
id: u64,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
let v = client.get_json(&format!("/repos/{repo}/issues/comments/{}", args.id))?;

View file

@ -45,6 +45,11 @@ pub struct Args {
tail: Option<usize>,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
let comments = match args.tail {

View file

@ -30,6 +30,11 @@ pub struct Args {
full: bool,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
let diff = client.get_text(&format!("/repos/{repo}/pulls/{}.diff", args.number), "text/plain")?;

View file

@ -13,6 +13,11 @@ pub struct Args {
number: u64,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
let v = client.get_json(&format!("/repos/{repo}/issues/{}", args.number))?;

View file

@ -24,6 +24,12 @@ pub struct Args {
assignee: Option<String>,
}
/// # Errors
///
/// Propagates any I/O error from the body input (`--body-file`,
/// stdin), any transport error from the Forgejo REST call (network
/// unreachable, 4xx/5xx response, token missing/invalid), and any
/// I/O error from writing the issue URL to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let body = body::resolve(args.body.as_deref(), args.body_file.as_deref())?.unwrap_or_default();
let repo = client.repo();

View file

@ -46,6 +46,12 @@ pub struct Args {
milestone: Option<u64>,
}
/// # Errors
///
/// Propagates any I/O error from the body input (`--body-file`,
/// stdin), any transport error from the Forgejo REST call (network
/// unreachable, 4xx/5xx response, token missing/invalid), and any
/// I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
// Body is partial: only update the body field if a source was
// actually given. Piped stdin without --body/--body-file leaves

View file

@ -32,6 +32,11 @@ enum Action {
},
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
match args.action.unwrap_or(Action::List) {

View file

@ -116,6 +116,13 @@ struct AssignmentsArgs {
user: Option<String>,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout. Subcommand
/// dispatches go through the same per-query helpers and inherit
/// the same surfaces.
pub fn run(client: &Client, args: Args) -> Result<()> {
match args.sub {
Sub::Unassigned(a) => run_unassigned(client, a),

View file

@ -86,6 +86,11 @@ pub struct Args {
limit: u64,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
let mut path = format!(

View file

@ -37,6 +37,11 @@ enum Action {
},
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
match args.action.unwrap_or(Action::List) {

View file

@ -13,6 +13,11 @@ pub struct Args {
number: u64,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
let v = client.get_json(&format!("/repos/{repo}/pulls/{}", args.number))?;

View file

@ -51,6 +51,13 @@ pub struct Args {
remote: String,
}
/// # Errors
///
/// Propagates any I/O error from the body input (`--body-file`,
/// stdin) or the `--push` shellout to git, any transport error from
/// the Forgejo REST call (network unreachable, 4xx/5xx response,
/// token missing/invalid), and any I/O error from writing the PR
/// URL to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let body = body::resolve(args.body.as_deref(), args.body_file.as_deref())?.unwrap_or_default();
if args.push {

View file

@ -13,6 +13,11 @@ pub struct Args {
number: u64,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
let v = client.get_json(&format!("/repos/{repo}/pulls/{}/reviews", args.number))?;

View file

@ -21,6 +21,11 @@ pub struct Args {
unwatch: bool,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
if args.unwatch {

View file

@ -32,6 +32,11 @@ pub struct Args {
limit: u64,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
let v = client.get_json(&format!(

View file

@ -13,6 +13,11 @@ pub struct Args {
reference: String,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
// Try branch first; the bash helper silently treats failure as

View file

@ -13,6 +13,11 @@ pub struct Args {
number: u64,
}
/// # Errors
///
/// Propagates any transport error from the Forgejo REST call
/// (network unreachable, 4xx/5xx response, token missing/invalid)
/// and any I/O error from writing the response to stdout.
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
let issue = client.get_json(&format!("/repos/{repo}/issues/{}", args.number))?;