//! `issue ` — issue-scoped sub-commands. Wraps the per-verb modules //! under an `issue` parent so `hive-forge issue close 42`, `issue create …`, //! etc. read as kind-namespaced commands. The generic verbs that also work on //! PRs (view/comment/comments/close/reopen/labels/assign/timeline) kind-check the //! number is an issue first (`assert_kind`); the issue-only verbs are //! kind-correct by construction. The flat `issue-*` + bare generic verbs stay //! as hidden back-compat aliases (see `main.rs`). use anyhow::Result; use clap::{Args as ClapArgs, Subcommand}; use crate::client::Client; use crate::verbs::{self, Kind, assert_kind}; #[derive(ClapArgs)] pub struct Args { #[command(subcommand)] cmd: Cmd, } #[derive(Subcommand)] enum Cmd { /// Show issue metadata as JSON. Show(verbs::issue::Args), /// Create an issue. Create(verbs::issue_create::Args), /// Edit an issue's title / body / state / milestone. Edit(verbs::issue_edit::Args), /// Show title + body + comments. View(verbs::view::Args), /// Post a comment on the issue. Comment(verbs::comment::Args), /// List comments on the issue. Comments(verbs::comments::Args), /// Close the issue. Close(verbs::close::Args), /// Reopen a closed issue. Reopen(verbs::reopen::Args), /// List / add / remove labels. Labels(verbs::labels::Args), /// Assign or unassign a user. Assign(verbs::assign::Args), /// List timeline events. Timeline(verbs::timeline::Args), } pub fn run(client: &Client, args: Args) -> Result<()> { match args.cmd { // Issue-only verbs. Cmd::Show(a) => verbs::issue::run(client, a), Cmd::Create(a) => verbs::issue_create::run(client, a), Cmd::Edit(a) => verbs::issue_edit::run(client, a), // Generics shared with `pr` — verify the number is an issue first. Cmd::View(a) => { assert_kind(client, a.number, Kind::Issue)?; verbs::view::run(client, a) } Cmd::Comment(a) => { assert_kind(client, a.number, Kind::Issue)?; verbs::comment::run(client, a) } Cmd::Comments(a) => { assert_kind(client, a.number, Kind::Issue)?; verbs::comments::run(client, a) } Cmd::Close(a) => { assert_kind(client, a.number, Kind::Issue)?; verbs::close::run(client, a) } Cmd::Reopen(a) => { assert_kind(client, a.number, Kind::Issue)?; verbs::reopen::run(client, a) } Cmd::Labels(a) => { assert_kind(client, a.number, Kind::Issue)?; verbs::labels::run(client, a) } Cmd::Assign(a) => { assert_kind(client, a.number, Kind::Issue)?; verbs::assign::run(client, a) } Cmd::Timeline(a) => { assert_kind(client, a.number, Kind::Issue)?; verbs::timeline::run(client, a) } } }