chore: Improve maintainers handling

Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
Awiteb
2025-06-14 10:30:11 +00:00
parent a9a2cb2b16
commit ec08a1febc
7 changed files with 59 additions and 69 deletions

View File

@@ -16,7 +16,6 @@
use clap::{ArgGroup, Args}; use clap::{ArgGroup, Args};
use futures::future;
use nostr::event::{EventBuilder, Tag}; use nostr::event::{EventBuilder, Tag};
use crate::{ use crate::{
@@ -103,10 +102,11 @@ impl CommandRunner for NewArgs {
let relays = options.relays.clone().flat_relays(&options.config.sets)?; let relays = options.relays.clone().flat_relays(&options.config.sets)?;
let client = NostrClient::init(&options, &relays).await; let client = NostrClient::init(&options, &relays).await;
let user_pubk = options.pubkey().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; 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?; let relays_list = client.user_relays_list(user_pubk).await?;
client client
.add_relays(&utils::add_read_relays(relays_list.as_ref())) .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 (subject, content) = self.issue_content()?;
let content_details = client.parse_content(&content).await; let content_details = client.parse_content(&content).await;
let event = EventBuilder::new_git_issue( let event =
naddrs_iter EventBuilder::new_git_issue(coordinates.as_slice(), content, subject, self.label)?
.next() .dedup_tags()
.expect("There is at least one address") .pow(options.pow.unwrap_or_default())
.coordinate .tags(maintainers.iter().map(|p| Tag::public_key(*p)))
.clone(), .tags(content_details.clone().into_tags())
content, .build(user_pubk);
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_id = event.id.expect("There is an id"); let event_id = event.id.expect("There is an id");
let write_relays = [ let write_relays = [
@@ -143,12 +132,8 @@ impl CommandRunner for NewArgs {
.fetch_repos(&naddrs.into_coordinates()) .fetch_repos(&naddrs.into_coordinates())
.await? .await?
.extract_relays(), .extract_relays(),
// Include read relays for each repository owner (if found) // Include read relays for each maintainer (if found)
future::join_all(naddrs_iter.map(|c| client.read_relays_from_user(c.public_key))) client.read_relays_from_users(&maintainers).await,
.await
.into_iter()
.flatten()
.collect(),
content_details.write_relays.clone().into_iter().collect(), content_details.write_relays.clone().into_iter().collect(),
] ]
.concat(); .concat();

View File

@@ -88,17 +88,15 @@ impl CommandRunner for SendArgs {
client client
.add_relays(&utils::add_read_relays(relays_list.as_ref())) .add_relays(&utils::add_read_relays(relays_list.as_ref()))
.await; .await;
let repos_relays = client let repos = client.fetch_repos(&repo_coordinates).await?;
.fetch_repos(&repo_coordinates) let maintainers = repos.extract_maintainers();
.await? client.add_relays(&repos.extract_relays()).await;
.extract_relays();
client.add_relays(&repos_relays).await;
let (events, events_write_relays) = make_patch_series( let (events, events_write_relays) = make_patch_series(
&client, &client,
self.patches, self.patches,
self.original_patch.as_ref().map(|e| e.event_id), self.original_patch.as_ref().map(|e| e.event_id),
repos_relays.first().cloned(), repos.extract_relays().first().cloned(),
repo_coordinates, repo_coordinates,
&self.euc, &self.euc,
user_pubk, user_pubk,
@@ -107,20 +105,12 @@ impl CommandRunner for SendArgs {
let write_relays = [ let write_relays = [
relays, relays,
repos_relays, repos.extract_relays(),
events_write_relays, events_write_relays,
naddrs.extract_relays(), naddrs.extract_relays(),
self.original_patch.map(|e| e.relays).unwrap_or_default(), self.original_patch.map(|e| e.relays).unwrap_or_default(),
utils::add_write_relays(relays_list.as_ref()), utils::add_write_relays(relays_list.as_ref()),
future::join_all( client.read_relays_from_users(&maintainers).await,
naddrs
.iter()
.map(|c| client.read_relays_from_user(c.public_key)),
)
.await
.into_iter()
.flatten()
.collect(),
] ]
.concat(); .concat();

View File

@@ -113,6 +113,7 @@ impl CommandRunner for ReplyArgs {
}; };
let repos = client.fetch_repos(&repos_coordinate).await?; let repos = client.fetch_repos(&repos_coordinate).await?;
let maintainers = repos.extract_maintainers();
let quoted_content = if self.quote_to { let quoted_content = if self.quote_to {
Some(quote_reply_to_content(&client, &reply_to).await) 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()), utils::add_write_relays(relays_list.as_ref()),
// Merge repository announcement relays into write relays // Merge repository announcement relays into write relays
repos.extract_relays(), repos.extract_relays(),
// Include read relays for each repository owner (if found) // Include read relays for each repository maintainer (if found)
future::join_all( client.read_relays_from_users(&maintainers).await,
repos_coordinate
.iter()
.map(|c| client.read_relays_from_user(c.public_key)),
)
.await
.into_iter()
.flatten()
.collect(),
// read relays of the root event and the reply to event // read relays of the root event and the reply to event
{ {
let (r1, r2) = future::join( let (r1, r2) = future::join(

View File

@@ -56,7 +56,7 @@ pub async fn issue_status_command(
let coordinates = naddrs.clone().into_coordinates(); let coordinates = naddrs.clone().into_coordinates();
let repos = client.fetch_repos(&coordinates).await?; 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(); let relay_hint = repos.extract_relays().first().cloned();
client.add_relays(&repos.extract_relays()).await; client.add_relays(&repos.extract_relays()).await;
@@ -99,17 +99,7 @@ pub async fn issue_status_command(
repos.extract_relays(), repos.extract_relays(),
utils::add_write_relays(user_relays_list.as_ref()), utils::add_write_relays(user_relays_list.as_ref()),
client.read_relays_from_user(issue_event.pubkey).await, client.read_relays_from_user(issue_event.pubkey).await,
// TODO: Make this a function and use it elsewhere. client.read_relays_from_users(&maintainers).await,
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(),
] ]
.concat(); .concat();

View File

@@ -99,6 +99,8 @@ pub enum N34Error {
RevisionRootNotFound, RevisionRootNotFound,
#[error("Invalid status for the issue/patch: {0}")] #[error("Invalid status for the issue/patch: {0}")]
InvalidStatus(String), InvalidStatus(String),
#[error("One naddr is required for this command")]
EmptyNaddrs,
} }
impl N34Error { impl N34Error {

View File

@@ -342,6 +342,21 @@ impl NostrClient {
utils::add_read_relays(self.user_relays_list(user).await.ok().flatten().as_ref()) 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<RelayUrl> {
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 /// Parse the given content and returns the details that inside it
pub async fn parse_content(&self, content: &str) -> ContentDetails { pub async fn parse_content(&self, content: &str) -> ContentDetails {
let mut write_relays = Vec::new(); let mut write_relays = Vec::new();

View File

@@ -111,18 +111,27 @@ impl EventBuilder {
/// Creates a new [`GitIssue`] event builder with the given /// Creates a new [`GitIssue`] event builder with the given
/// issue details. /// issue details.
pub fn new_git_issue( pub fn new_git_issue(
repository: Coordinate, coordinates: &[Coordinate],
content: String, content: String,
subject: Option<String>, subject: Option<String>,
labels: Vec<String>, labels: Vec<String>,
) -> N34Result<EventBuilder> { ) -> N34Result<EventBuilder> {
let mut coordinates = coordinates.iter();
let first_coordinate = coordinates.next().ok_or(N34Error::EmptyNaddrs)?;
let mut event_builder = EventBuilder::git_issue(GitIssue { let mut event_builder = EventBuilder::git_issue(GitIssue {
repository, repository: first_coordinate.clone(),
content, content,
subject: subject.clone(), subject: subject.clone(),
labels: labels.into_iter().map(|l| l.trim().to_owned()).collect(), 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 { if let Some(issue_subject) = subject {
event_builder = event_builder =
@@ -196,4 +205,10 @@ impl Vec<GitRepositoryAnnouncement> {
pub fn extract_relays(&self) -> Vec<RelayUrl> { pub fn extract_relays(&self) -> Vec<RelayUrl> {
self.iter().flat_map(|n| n.relays.clone()).collect() self.iter().flat_map(|n| n.relays.clone()).collect()
} }
/// Extract all the maintainers from these repositories
pub fn extract_maintainers(&self) -> Vec<PublicKey> {
self.iter().flat_map(|r| r.maintainers.clone()).collect()
}
}
} }