From ddea5028ee8e31a9626ef1b2766d935513645d51 Mon Sep 17 00:00:00 2001 From: Awiteb Date: Sat, 24 May 2025 12:30:40 +0000 Subject: [PATCH] feat: Make the relays list optional Signed-off-by: Awiteb --- src/cli/commands/issue/new.rs | 1 - src/cli/commands/mod.rs | 15 +++++++-- src/cli/commands/reply.rs | 52 ++++++++++++++++++------------- src/cli/commands/repo/announce.rs | 2 ++ src/error.rs | 2 ++ 5 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/cli/commands/issue/new.rs b/src/cli/commands/issue/new.rs index 84aa217..9c51898 100644 --- a/src/cli/commands/issue/new.rs +++ b/src/cli/commands/issue/new.rs @@ -91,7 +91,6 @@ impl CommandRunner for NewArgs { let user_pubk = options.pubkey().await?; let naddr = utils::naddr_or_file(self.naddr.clone(), &utils::nostr_address_path()?)?; - client.add_relays(&options.relays).await; client.add_relays(&naddr.relays).await; let relays_list = client.user_relays_list(user_pubk).await?; diff --git a/src/cli/commands/mod.rs b/src/cli/commands/mod.rs index 0773551..93c50e7 100644 --- a/src/cli/commands/mod.rs +++ b/src/cli/commands/mod.rs @@ -33,7 +33,7 @@ use self::issue::IssueSubcommands; use self::reply::ReplyArgs; use self::repo::RepoSubcommands; use super::traits::CommandRunner; -use crate::error::N34Result; +use crate::error::{N34Error, N34Result}; /// The command-line interface options #[derive(Args, Clone)] @@ -48,8 +48,9 @@ pub struct CliOptions { /// Your Nostr secret key #[arg(short, long)] pub secret_key: Option, - /// Where your relays list. And repository relays if not included in naddr - #[arg(short, long, required = true)] + /// Fallbacks relay to write and read from it. Multiple relays can be + /// passed. + #[arg(short, long)] pub relays: Vec, /// Proof of Work difficulty when creatring events #[arg(long, default_value_t = 0)] @@ -99,6 +100,14 @@ impl CliOptions { } unreachable!("There is no other method until now") } + + /// Returns an error if there are no relays. + pub fn ensure_relays(&self) -> N34Result<()> { + if self.relays.is_empty() { + return Err(N34Error::EmptyRelays); + } + Ok(()) + } } impl fmt::Debug for CliOptions { diff --git a/src/cli/commands/reply.rs b/src/cli/commands/reply.rs index 3b88a05..a4aeb87 100644 --- a/src/cli/commands/reply.rs +++ b/src/cli/commands/reply.rs @@ -21,7 +21,7 @@ use nostr::{ event::{Event, EventBuilder, EventId, Kind, Tag}, filter::Filter, nips::{ - nip01::Metadata, + nip01::{Coordinate, Metadata}, nip19::{self, FromBech32, Nip19Coordinate, ToBech32}, }, types::RelayUrl, @@ -112,10 +112,21 @@ pub struct ReplyArgs { impl CommandRunner for ReplyArgs { async fn run(self, options: CliOptions) -> N34Result<()> { + let nostr_address_path = utils::nostr_address_path()?; let client = NostrClient::init(&options).await; let user_pubk = options.pubkey().await?; - client.add_relays(&options.relays).await; + let repo_naddr = if let Some(naddr) = self.naddr { + client.add_relays(&naddr.relays).await; + Some(naddr.coordinate) + } else if fs::exists(&nostr_address_path).is_ok() { + let naddr = utils::naddr_or_file(None, &nostr_address_path)?; + client.add_relays(&naddr.relays).await; + Some(naddr.coordinate) + } else { + None + }; + client.add_relays(&self.to.relays).await; let relays_list = client.user_relays_list(user_pubk).await?; @@ -128,26 +139,10 @@ impl CommandRunner for ReplyArgs { .ok_or(N34Error::EventNotFound)?; let root = client.find_root(reply_to.clone()).await?; - - let nostr_address_path = utils::nostr_address_path()?; - let repo_naddr = if let Some(naddr) = self.naddr { - client.add_relays(&naddr.relays).await; - naddr.coordinate - } else if fs::exists(&nostr_address_path).is_ok() { - let naddr = utils::naddr_or_file(None, &nostr_address_path)?; - client.add_relays(&naddr.relays).await; - naddr.coordinate + let repo_naddr = if let Some(naddr) = repo_naddr { + naddr } else if let Some(ref root_event) = root { - root_event - .tags - .coordinates() - .find(|c| c.kind == Kind::GitRepoAnnouncement) - .ok_or_else(|| { - N34Error::InvalidEvent( - "The Git issue/patch does not specify a target repository".to_owned(), - ) - })? - .clone() + naddr_from_root(root_event)? } else { return Err(N34Error::NotFoundRepo); }; @@ -247,3 +242,18 @@ async fn quote_reply_to_content(client: &NostrClient, quoted_event: &Event) -> S quoted_event.content.trim().replace("\n", "\n> ") ) } + +/// Gets the repository coordinate from a root Nostr event's tags. +/// The event must contain a coordinate tag with GitRepoAnnouncement kind. +fn naddr_from_root(root: &Event) -> N34Result { + Ok(root + .tags + .coordinates() + .find(|c| c.kind == Kind::GitRepoAnnouncement) + .ok_or_else(|| { + N34Error::InvalidEvent( + "The Git issue/patch does not specify a target repository".to_owned(), + ) + })? + .clone()) +} diff --git a/src/cli/commands/repo/announce.rs b/src/cli/commands/repo/announce.rs index 2bac9fc..3fd762a 100644 --- a/src/cli/commands/repo/announce.rs +++ b/src/cli/commands/repo/announce.rs @@ -61,6 +61,8 @@ pub struct AnnounceArgs { impl CommandRunner for AnnounceArgs { async fn run(mut self, options: CliOptions) -> N34Result<()> { + options.ensure_relays()?; + let client = NostrClient::init(&options).await; let user_pubk = options.pubkey().await?; let relays_list = client.user_relays_list(user_pubk).await?; diff --git a/src/error.rs b/src/error.rs index 9676476..b64f389 100644 --- a/src/error.rs +++ b/src/error.rs @@ -60,6 +60,8 @@ pub enum N34Error { EmptyNostrAddressFile, #[error("Invalid `nostr-address` file content: {0}")] InvalidNostrAddressFileContent(String), + #[error("This command requires at least one relay, but none were provided")] + EmptyRelays, } impl N34Error {