From d11c9537b60cfc083415c72ca29a894b5d3dee92 Mon Sep 17 00:00:00 2001 From: damocles Date: Fri, 9 Oct 2026 12:44:46 +0200 Subject: [PATCH] =?UTF-8?q?hive-forge:=20drop=20subscription=20--ignore=20?= =?UTF-8?q?entirely=20=E2=80=94=20Forgejo=20only=20has=20watch/unwatch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/tools/forge-cli.md | 3 +- hive-forge/src/verbs/subscription.rs | 85 ++++------------------------ 2 files changed, 13 insertions(+), 75 deletions(-) diff --git a/docs/tools/forge-cli.md b/docs/tools/forge-cli.md index 3aec91ea..8c9e5a31 100644 --- a/docs/tools/forge-cli.md +++ b/docs/tools/forge-cli.md @@ -1278,8 +1278,7 @@ Get/set this user's watch subscription on a repo, or --list all watched repos ###### **Options:** * `--watch` — Subscribe (watch the repo) -* `--ignore` — Unsupported: Forgejo's subscription endpoint can't mark a repo ignored without also watching it. Always refuses with an error -* `--unwatch` — Unsubscribe (clear watch + ignore) +* `--unwatch` — Unsubscribe (stop watching) * `--list` — List every repo the current user watches (ignores `[repo]`) diff --git a/hive-forge/src/verbs/subscription.rs b/hive-forge/src/verbs/subscription.rs index bdf7eca2..461eed68 100644 --- a/hive-forge/src/verbs/subscription.rs +++ b/hive-forge/src/verbs/subscription.rs @@ -1,7 +1,12 @@ -//! `subscription [--watch|--ignore|--unwatch|--list] [repo]` — get or -//! set the current user's watch subscription for a repo, or list every -//! repo the user watches (`--list`, for auditing the notification -//! firehose). +//! `subscription [--watch|--unwatch|--list] [repo]` — get or set the +//! current user's watch subscription for a repo, or list every repo the +//! user watches (`--list`, for auditing the notification firehose). +//! +//! There is deliberately no `--ignore`: Forgejo's subscription endpoint +//! has no way to mark a repo ignored without also watching it (its PUT +//! takes no body), so a mute flag here can only ever be subscribe or +//! unsubscribe under the hood. Rather than keep a flag that refuses with +//! an error, this verb just exposes the two states Forgejo actually has. use anyhow::Result; use clap::Args as ClapArgs; @@ -11,21 +16,11 @@ use crate::client::{Client, is_not_found}; use crate::verbs::print_json; #[derive(ClapArgs)] -#[allow( - clippy::struct_excessive_bools, - reason = "mutually-exclusive clap action flags (group = \"action\"); an \ - enum would drop the --watch/--ignore/--unwatch/--list flag \ - ergonomics agents already use" -)] pub struct Args { /// Subscribe (watch the repo). #[arg(long, group = "action")] watch: bool, - /// Unsupported: Forgejo's subscription endpoint can't mark a repo - /// ignored without also watching it. Always refuses with an error. - #[arg(long, group = "action")] - ignore: bool, - /// Unsubscribe (clear watch + ignore). + /// Unsubscribe (stop watching). #[arg(long, group = "action")] unwatch: bool, /// List every repo the current user watches (ignores `[repo]`). @@ -33,39 +28,14 @@ pub struct Args { list: bool, } -/// Refuse `--ignore`. Forgejo's PUT subscription endpoint takes no body — -/// it always subscribes (watch), with no way to mark a repo ignored -/// without also watching it. The old raw client sent a -/// `{subscribed, ignored}` body which the server ignored, so `--ignore` -/// silently behaved like `--watch` (the opposite of what it promises) -/// instead of failing. Refuse instead of lying about what happened. A -/// free function (rather than inlined in `run`) so the refusal itself — -/// not just a string constant — is unit-testable without a real `Client`: -/// it fires before any API call is made. -/// -/// # Errors -/// Always errors when `args.ignore` is set; otherwise always `Ok`. -fn reject_ignore(args: &Args) -> Result<()> { - if args.ignore { - anyhow::bail!( - "subscription --ignore is not supported: Forgejo's subscription \ - endpoint has no way to mark a repo ignored without also \ - watching it. Use --unwatch to stop watching, or --watch if \ - muted-but-watched is what you actually want." - ); - } - Ok(()) -} - /// Run the `subscription` verb: `--list` all watched repos, set the -/// current repo's watch (`--watch` / `--ignore` / `--unwatch`), or get -/// its current state. +/// current repo's watch (`--watch` / `--unwatch`), or get its current +/// state. /// /// # Errors /// Propagates transport / non-2xx errors from the Forgejo client calls /// and from `print_json`. pub fn run(client: &Client, args: Args) -> Result<()> { - reject_ignore(&args)?; if args.list { // List every repo the authed user watches, so an agent can audit // its notification firehose and decide what to `--unwatch`. Not @@ -123,34 +93,3 @@ pub fn run(client: &Client, args: Args) -> Result<()> { Err(e) => Err(e.into()), } } - -#[cfg(test)] -mod tests { - use super::{Args, reject_ignore}; - - #[test] - fn ignore_is_rejected_pointing_at_unwatch() { - let args = Args { - watch: false, - ignore: true, - unwatch: false, - list: false, - }; - let err = reject_ignore(&args).expect_err("--ignore must be refused"); - let msg = err.to_string(); - assert!(msg.contains("--unwatch")); - assert!(msg.contains("--watch")); - assert!(msg.contains("not supported")); - } - - #[test] - fn watch_is_not_rejected() { - let args = Args { - watch: true, - ignore: false, - unwatch: false, - list: false, - }; - assert!(reject_ignore(&args).is_ok()); - } -}