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 {