//! `issue-create --title [body sources] [--assignee ] [repo]` //! — create an issue. Prints the issue URL. use anyhow::Result; use clap::Args as ClapArgs; use serde_json::{Value, json}; use crate::body; use crate::client::Client; #[derive(ClapArgs)] pub struct Args { /// Issue title (required). #[arg(long)] title: String, /// Inline body text. #[arg(long, conflicts_with = "body_file")] body: Option, /// Read body from a file. `-` means stdin. #[arg(long = "body-file")] body_file: Option, /// Initial assignee login. #[arg(long)] assignee: Option, } /// # 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(); let mut payload = json!({ "title": args.title, "body": body }); if let Some(a) = args.assignee { payload["assignees"] = json!([a]); } let resp = client.post_json(&format!("/repos/{repo}/issues"), &payload)?; if let Some(url) = resp.get("html_url").and_then(Value::as_str) { println!("{url}"); } Ok(()) }