From ec08a1febcd35878132cebea6295abbbb2fcc111 Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Sat, 14 Jun 2025 10:30:11 +0000
Subject: [PATCH] chore: Improve maintainers handling
Signed-off-by: Awiteb
---
src/cli/commands/issue/new.rs | 41 +++++++++++-----------------------
src/cli/commands/patch/send.rs | 22 +++++-------------
src/cli/commands/reply.rs | 13 +++--------
src/cli/common_commands.rs | 14 ++----------
src/error.rs | 2 ++
src/nostr_utils/mod.rs | 15 +++++++++++++
src/nostr_utils/traits.rs | 21 ++++++++++++++---
7 files changed, 59 insertions(+), 69 deletions(-)
diff --git a/src/cli/commands/issue/new.rs b/src/cli/commands/issue/new.rs
index 205b3a8..ce69856 100644
--- a/src/cli/commands/issue/new.rs
+++ b/src/cli/commands/issue/new.rs
@@ -16,7 +16,6 @@
use clap::{ArgGroup, Args};
-use futures::future;
use nostr::event::{EventBuilder, Tag};
use crate::{
@@ -103,10 +102,11 @@ impl CommandRunner for NewArgs {
let relays = options.relays.clone().flat_relays(&options.config.sets)?;
let client = NostrClient::init(&options, &relays).await;
let user_pubk = options.pubkey().await?;
- let mut naddrs_iter = naddrs.clone().into_iter();
-
+ let coordinates = naddrs.clone().into_coordinates();
client.add_relays(&naddrs.extract_relays()).await;
-
+ let repos = client.fetch_repos(coordinates.as_slice()).await?;
+ let maintainers = repos.extract_maintainers();
+ client.add_relays(&repos.extract_relays()).await;
let relays_list = client.user_relays_list(user_pubk).await?;
client
.add_relays(&utils::add_read_relays(relays_list.as_ref()))
@@ -115,24 +115,13 @@ impl CommandRunner for NewArgs {
let (subject, content) = self.issue_content()?;
let content_details = client.parse_content(&content).await;
- let event = EventBuilder::new_git_issue(
- naddrs_iter
- .next()
- .expect("There is at least one address")
- .coordinate
- .clone(),
- content,
- subject,
- self.label,
- )?
- .dedup_tags()
- .pow(options.pow.unwrap_or_default())
- .tags(content_details.clone().into_tags())
- // p-tag the reset of the reposotoies owners
- .tags(naddrs_iter.clone().map(|n| Tag::public_key(n.public_key)))
- // a-tag the reset of the reposotoies
- .tags(naddrs_iter.clone().map(|n| Tag::coordinate(n.coordinate, n.relays.first().cloned())))
- .build(user_pubk);
+ let event =
+ EventBuilder::new_git_issue(coordinates.as_slice(), content, subject, self.label)?
+ .dedup_tags()
+ .pow(options.pow.unwrap_or_default())
+ .tags(maintainers.iter().map(|p| Tag::public_key(*p)))
+ .tags(content_details.clone().into_tags())
+ .build(user_pubk);
let event_id = event.id.expect("There is an id");
let write_relays = [
@@ -143,12 +132,8 @@ impl CommandRunner for NewArgs {
.fetch_repos(&naddrs.into_coordinates())
.await?
.extract_relays(),
- // Include read relays for each repository owner (if found)
- future::join_all(naddrs_iter.map(|c| client.read_relays_from_user(c.public_key)))
- .await
- .into_iter()
- .flatten()
- .collect(),
+ // Include read relays for each maintainer (if found)
+ client.read_relays_from_users(&maintainers).await,
content_details.write_relays.clone().into_iter().collect(),
]
.concat();
diff --git a/src/cli/commands/patch/send.rs b/src/cli/commands/patch/send.rs
index 20b5953..015a8e4 100644
--- a/src/cli/commands/patch/send.rs
+++ b/src/cli/commands/patch/send.rs
@@ -88,17 +88,15 @@ impl CommandRunner for SendArgs {
client
.add_relays(&utils::add_read_relays(relays_list.as_ref()))
.await;
- let repos_relays = client
- .fetch_repos(&repo_coordinates)
- .await?
- .extract_relays();
- client.add_relays(&repos_relays).await;
+ let repos = client.fetch_repos(&repo_coordinates).await?;
+ let maintainers = repos.extract_maintainers();
+ client.add_relays(&repos.extract_relays()).await;
let (events, events_write_relays) = make_patch_series(
&client,
self.patches,
self.original_patch.as_ref().map(|e| e.event_id),
- repos_relays.first().cloned(),
+ repos.extract_relays().first().cloned(),
repo_coordinates,
&self.euc,
user_pubk,
@@ -107,20 +105,12 @@ impl CommandRunner for SendArgs {
let write_relays = [
relays,
- repos_relays,
+ repos.extract_relays(),
events_write_relays,
naddrs.extract_relays(),
self.original_patch.map(|e| e.relays).unwrap_or_default(),
utils::add_write_relays(relays_list.as_ref()),
- future::join_all(
- naddrs
- .iter()
- .map(|c| client.read_relays_from_user(c.public_key)),
- )
- .await
- .into_iter()
- .flatten()
- .collect(),
+ client.read_relays_from_users(&maintainers).await,
]
.concat();
diff --git a/src/cli/commands/reply.rs b/src/cli/commands/reply.rs
index 6e9deab..1c56641 100644
--- a/src/cli/commands/reply.rs
+++ b/src/cli/commands/reply.rs
@@ -113,6 +113,7 @@ impl CommandRunner for ReplyArgs {
};
let repos = client.fetch_repos(&repos_coordinate).await?;
+ let maintainers = repos.extract_maintainers();
let quoted_content = if self.quote_to {
Some(quote_reply_to_content(&client, &reply_to).await)
@@ -140,16 +141,8 @@ impl CommandRunner for ReplyArgs {
utils::add_write_relays(relays_list.as_ref()),
// Merge repository announcement relays into write relays
repos.extract_relays(),
- // Include read relays for each repository owner (if found)
- future::join_all(
- repos_coordinate
- .iter()
- .map(|c| client.read_relays_from_user(c.public_key)),
- )
- .await
- .into_iter()
- .flatten()
- .collect(),
+ // Include read relays for each repository maintainer (if found)
+ client.read_relays_from_users(&maintainers).await,
// read relays of the root event and the reply to event
{
let (r1, r2) = future::join(
diff --git a/src/cli/common_commands.rs b/src/cli/common_commands.rs
index 689b09a..b64ae92 100644
--- a/src/cli/common_commands.rs
+++ b/src/cli/common_commands.rs
@@ -56,7 +56,7 @@ pub async fn issue_status_command(
let coordinates = naddrs.clone().into_coordinates();
let repos = client.fetch_repos(&coordinates).await?;
- let maintainers = utils::dedup(repos.iter().flat_map(|r| r.maintainers.clone()));
+ let maintainers = repos.extract_maintainers();
let relay_hint = repos.extract_relays().first().cloned();
client.add_relays(&repos.extract_relays()).await;
@@ -99,17 +99,7 @@ pub async fn issue_status_command(
repos.extract_relays(),
utils::add_write_relays(user_relays_list.as_ref()),
client.read_relays_from_user(issue_event.pubkey).await,
- // TODO: Make this a function and use it elsewhere.
- client
- .fetch_events(
- Filter::new()
- .kind(nostr::event::Kind::RelayList)
- .authors(maintainers),
- )
- .await?
- .into_iter()
- .flat_map(|e| utils::add_read_relays(Some(&e)))
- .collect(),
+ client.read_relays_from_users(&maintainers).await,
]
.concat();
diff --git a/src/error.rs b/src/error.rs
index 25fa6f6..0a884ab 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -99,6 +99,8 @@ pub enum N34Error {
RevisionRootNotFound,
#[error("Invalid status for the issue/patch: {0}")]
InvalidStatus(String),
+ #[error("One naddr is required for this command")]
+ EmptyNaddrs,
}
impl N34Error {
diff --git a/src/nostr_utils/mod.rs b/src/nostr_utils/mod.rs
index 54d3b65..8f060a1 100644
--- a/src/nostr_utils/mod.rs
+++ b/src/nostr_utils/mod.rs
@@ -342,6 +342,21 @@ impl NostrClient {
utils::add_read_relays(self.user_relays_list(user).await.ok().flatten().as_ref())
}
+ /// Returns the read relays of the given users if found, otherwise empty
+ /// vector
+ pub async fn read_relays_from_users(&self, users: &[PublicKey]) -> Vec {
+ self.fetch_events(
+ Filter::new()
+ .kind(nostr::event::Kind::RelayList)
+ .authors(utils::dedup(users.iter().copied())),
+ )
+ .await
+ .unwrap_or_default()
+ .into_iter()
+ .flat_map(|e| utils::add_read_relays(Some(&e)))
+ .collect()
+ }
+
/// Parse the given content and returns the details that inside it
pub async fn parse_content(&self, content: &str) -> ContentDetails {
let mut write_relays = Vec::new();
diff --git a/src/nostr_utils/traits.rs b/src/nostr_utils/traits.rs
index 777dcd3..e80bb03 100644
--- a/src/nostr_utils/traits.rs
+++ b/src/nostr_utils/traits.rs
@@ -111,18 +111,27 @@ impl EventBuilder {
/// Creates a new [`GitIssue`] event builder with the given
/// issue details.
pub fn new_git_issue(
- repository: Coordinate,
+ coordinates: &[Coordinate],
content: String,
subject: Option,
labels: Vec,
) -> N34Result {
+ let mut coordinates = coordinates.iter();
+ let first_coordinate = coordinates.next().ok_or(N34Error::EmptyNaddrs)?;
+
let mut event_builder = EventBuilder::git_issue(GitIssue {
- repository,
+ repository: first_coordinate.clone(),
content,
subject: subject.clone(),
labels: labels.into_iter().map(|l| l.trim().to_owned()).collect(),
})
- .map_err(N34Error::from)?;
+ .map_err(N34Error::from)?
+ .tags(
+ coordinates
+ .clone()
+ .map(|c| Tag::coordinate(c.clone(), None)),
+ )
+ .tags(coordinates.map(|c| Tag::public_key(c.public_key)));
if let Some(issue_subject) = subject {
event_builder =
@@ -196,4 +205,10 @@ impl Vec {
pub fn extract_relays(&self) -> Vec {
self.iter().flat_map(|n| n.relays.clone()).collect()
}
+
+ /// Extract all the maintainers from these repositories
+ pub fn extract_maintainers(&self) -> Vec {
+ self.iter().flat_map(|r| r.maintainers.clone()).collect()
+ }
+}
}