From 8db1cbd20422eb0e8539f026139c6591378c0ef6 Mon Sep 17 00:00:00 2001 From: damocles Date: Mon, 3 Aug 2026 01:44:36 +0200 Subject: [PATCH] hive-forge: add pr edit, reusing issue edit's shared /issues endpoint --- docs/tools/forge.md | 1 + hive-forge/src/main.rs | 2 +- hive-forge/src/verbs/issue_edit.rs | 9 ++++++--- hive-forge/src/verbs/pr_cmd.rs | 15 +++++++++++---- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/docs/tools/forge.md b/docs/tools/forge.md index 2e50a5eb..8de53cc6 100644 --- a/docs/tools/forge.md +++ b/docs/tools/forge.md @@ -52,6 +52,7 @@ hive-forge labels 42 add feature hive-forge issue-create --title "..." --body "..." hive-forge issue-create --title "..." --body "..." --label area/ops --label type/bug # repeatable hive-forge issue-edit 42 --title "new title" +hive-forge pr edit 42 --title "new title" # same edit, PR-kind-validated hive-forge pr 42 # PR metadata as JSON hive-forge pr-create --title "..." --head my-branch --push # also `git push forge my-branch` hive-forge pr-create --title "..." --head my-branch --label area/ops # repeatable, same as issue-create diff --git a/hive-forge/src/main.rs b/hive-forge/src/main.rs index 6a7ea892..0226ca80 100644 --- a/hive-forge/src/main.rs +++ b/hive-forge/src/main.rs @@ -75,7 +75,7 @@ enum Verb { /// Edit an issue's title, body, state, or milestone. #[command(hide = true)] IssueEdit(verbs::issue_edit::Args), - /// PR-scoped commands: `pr …`. + /// PR-scoped commands: `pr …`. Pr(verbs::pr_cmd::Args), /// List a PR's commits as JSON (sha, message, author date, author). #[command(hide = true)] diff --git a/hive-forge/src/verbs/issue_edit.rs b/hive-forge/src/verbs/issue_edit.rs index f51496ee..d94989de 100644 --- a/hive-forge/src/verbs/issue_edit.rs +++ b/hive-forge/src/verbs/issue_edit.rs @@ -1,6 +1,9 @@ //! `issue-edit [--title ] [body sources] [--state s] //! [--milestone id] [repo]` — partial update of an issue. Fields not -//! provided are left unchanged. +//! provided are left unchanged. Also backs `pr edit`: Forgejo serves +//! both kinds off the same `/issues/` endpoint, so this is shared +//! as-is — `pr_cmd.rs` wires it in with a `Kind::Pr` check, the same +//! pattern `close`/`reopen`/`labels` already use. use anyhow::Result; use clap::{Args as ClapArgs, ValueEnum}; @@ -28,8 +31,8 @@ impl StateArg { #[derive(ClapArgs)] pub struct Args { - /// Issue number. - number: u64, + /// Issue (or PR — shares the same `/issues/` endpoint) number. + pub(crate) number: u64, /// New title (omit to leave unchanged). #[arg(long)] title: Option, diff --git a/hive-forge/src/verbs/pr_cmd.rs b/hive-forge/src/verbs/pr_cmd.rs index ce627bff..f0c99539 100644 --- a/hive-forge/src/verbs/pr_cmd.rs +++ b/hive-forge/src/verbs/pr_cmd.rs @@ -1,10 +1,10 @@ //! `pr ` — PR-scoped sub-commands. Wraps the per-verb modules under a //! `pr` parent so `hive-forge pr close 42`, `pr status --pr 42`, etc. read as //! kind-namespaced commands. The generic verbs that also work on issues -//! (view/comment/comments/close/reopen/labels/assign-committer/timeline) kind-check the number -//! is a PR first (`assert_kind`); the PR-only verbs hit `/pulls/…` and are -//! kind-correct by construction. The flat `pr-*` + bare generic verbs stay as -//! hidden back-compat aliases (see `main.rs`). +//! (view/comment/comments/close/reopen/edit/labels/assign-committer/timeline) +//! kind-check the number is a PR first (`assert_kind`); the PR-only verbs +//! hit `/pulls/…` and are kind-correct by construction. The flat `pr-*` + +//! bare generic verbs stay as hidden back-compat aliases (see `main.rs`). use anyhow::Result; use clap::{Args as ClapArgs, Subcommand}; @@ -38,6 +38,9 @@ enum Cmd { Diff(verbs::diff::Args), /// Show title + body + comments. View(verbs::view::Args), + /// Edit the PR's title / body / state / milestone. Fields not passed + /// are left unchanged. + Edit(verbs::issue_edit::Args), /// Post a comment on the PR. Comment(verbs::comment::Args), /// List comments on the PR. @@ -71,6 +74,10 @@ pub fn run(client: &Client, args: Args) -> Result<()> { assert_kind(client, a.number, Kind::Pr)?; verbs::view::run(client, a) } + Cmd::Edit(a) => { + assert_kind(client, a.number, Kind::Pr)?; + verbs::issue_edit::run(client, a) + } Cmd::Comment(a) => { assert_kind(client, a.number, Kind::Pr)?; verbs::comment::run(client, a)