//! `issue-create --title [body sources] [--assignee ] //! [--label ]... [repo]` — create an issue. Prints the issue URL. use anyhow::Result; use clap::Args as ClapArgs; use forgejo_api::structs::CreateIssueOption; use crate::body; use crate::client::Client; use crate::verbs::labels; #[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, /// Label name to attach, repeatable (e.g. `--label area/ops --label /// type/bug`). Same spelling `labels add` accepts. An unresolved name /// errors out (before the issue is created) rather than silently /// attaching fewer labels than asked for. #[arg(long = "label")] labels: Vec, } /// # Errors /// /// Propagates any I/O error from the body input (`--body-file`, /// stdin), an absent or whitespace-only body (an issue's body *is* /// the issue per this repo's contribution guidance — an empty one is /// never intentional, only ever the signature of a mistake upstream, /// e.g. a heredoc that bound to the wrong command in a pipeline), any /// transport error from the Forgejo REST call (network unreachable, /// 4xx/5xx response, token missing/invalid, the `--label` lookup's /// own list-labels call), an unresolved `--label` name, and any I/O /// error from writing the issue URL to stdout. pub fn run(client: &Client, args: Args) -> Result<()> { let body = body::resolve_required( args.body.as_deref(), args.body_file.as_deref(), "issue-create", )?; let (owner, name) = client.owner_repo()?; let label_ids = if args.labels.is_empty() { None } else { let all = labels::repo_labels(client)?; Some(labels::resolve_ids(&all, &args.labels)?) }; let payload = CreateIssueOption { assignee: None, assignees: args.assignee.map(|a| vec![a]), body: Some(body), closed: None, due_date: None, labels: label_ids, milestone: None, r#ref: None, title: args.title, }; let issue = client .api() .issue_create_issue(owner, name, payload) .send()?; if let Some(url) = issue.html_url { println!("{url}"); } Ok(()) }