From 518e573467afa9c29c3039e02f6f0aa2f47acbb5 Mon Sep 17 00:00:00 2001 From: Awiteb Date: Mon, 25 Aug 2025 12:54:05 +0000 Subject: [PATCH] chore: Move `issue-view` run block to `common_commands::view_pr_issue` Signed-off-by: Awiteb --- src/cli/commands/issue/view.rs | 54 ++--------------- src/cli/common_commands.rs | 106 ++++++++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 52 deletions(-) diff --git a/src/cli/commands/issue/view.rs b/src/cli/commands/issue/view.rs index 4e9d46d..8512844 100644 --- a/src/cli/commands/issue/view.rs +++ b/src/cli/commands/issue/view.rs @@ -15,20 +15,14 @@ // along with this program. If not, see . use clap::Args; -use nostr::{event::Kind, filter::Filter}; use crate::{ cli::{ CliOptions, - traits::{CommandRunner, OptionNaddrOrSetVecExt, RelayOrSetVecExt}, + traits::CommandRunner, types::{NaddrOrSet, NostrEvent}, }, - error::{N34Error, N34Result}, - nostr_utils::{ - NostrClient, - traits::{GitIssuePrMetadata, NaddrsUtils, ReposUtils}, - utils, - }, + error::N34Result, }; #[derive(Debug, Args)] @@ -53,47 +47,7 @@ impl CommandRunner for ViewArgs { const NEED_SIGNER: bool = false; async fn run(self, options: CliOptions) -> N34Result<()> { - let naddrs = utils::naddrs_or_file( - self.naddrs.flat_naddrs(&options.config.sets)?, - &utils::nostr_address_path()?, - )?; - let relays = options.relays.clone().flat_relays(&options.config.sets)?; - let client = NostrClient::init(&options, &relays).await; - - client.add_relays(&naddrs.extract_relays()).await; - client.add_relays(&self.issue_id.relays).await; - client - .add_relays( - &client - .fetch_repos(&naddrs.into_coordinates()) - .await? - .extract_relays(), - ) - .await; - - let issue = client - .fetch_event( - Filter::new() - .id(self.issue_id.event_id) - .kind(Kind::GitIssue), - ) - .await? - .ok_or(N34Error::CanNotFoundIssue)?; - - let issue_subject = utils::smart_wrap(issue.extract_event_subject(), 70); - let issue_author = client.get_username(issue.pubkey).await; - let mut issue_labels = utils::smart_wrap(&issue.extract_event_labels(), 70); - - if issue_labels.is_empty() { - issue_labels = "\n".to_owned(); - } else { - issue_labels = format!("{issue_labels}\n\n") - } - - println!( - "{issue_subject} - [by {issue_author}]\n{issue_labels}{}", - utils::smart_wrap(&issue.content, 80) - ); - Ok(()) + crate::cli::common_commands::view_pr_issue::(options, self.naddrs, self.issue_id) + .await } } diff --git a/src/cli/common_commands.rs b/src/cli/common_commands.rs index 349b4e6..0c3b24c 100644 --- a/src/cli/common_commands.rs +++ b/src/cli/common_commands.rs @@ -20,7 +20,7 @@ use either::Either; use futures::future; use nostr::{ event::{Event, EventBuilder, EventId, Kind, Tag, TagKind}, - filter::Filter, + filter::{Alphabet, Filter, SingleLetterTag}, hashes::sha1::Hash as Sha1Hash, nips::{nip10::Marker, nip19::ToBech32}, types::RelayUrl, @@ -33,7 +33,11 @@ use super::{ }; use crate::{ cli::traits::{OptionNaddrOrSetVecExt, RelayOrSetVecExt}, - nostr_utils::{NostrClient, traits::NaddrsUtils, utils}, + nostr_utils::{ + NostrClient, + traits::{NaddrsUtils, TagsExt}, + utils, + }, }; use crate::{ cli::{CliOptions, patch::GitPatch}, @@ -436,3 +440,101 @@ async fn build_patches_quote( })) .await } + +pub async fn view_pr_issue( + options: CliOptions, + naddrs: Option>, + event_id: NostrEvent, +) -> N34Result<()> { + let naddrs = utils::naddrs_or_file( + naddrs.flat_naddrs(&options.config.sets)?, + &utils::nostr_address_path()?, + )?; + let relays = options.relays.clone().flat_relays(&options.config.sets)?; + let client = NostrClient::init(&options, &relays).await; + + client.add_relays(&naddrs.extract_relays()).await; + client.add_relays(&event_id.relays).await; + client + .add_relays( + &client + .fetch_repos(&naddrs.into_coordinates()) + .await? + .extract_relays(), + ) + .await; + + let event = client + .fetch_event(Filter::new().id(event_id.event_id).kind( + const { + if IS_PR { + crate::cli::pr::PR_KIND + } else { + Kind::GitIssue + } + }, + )) + .await? + .ok_or(N34Error::CanNotFoundIssue)?; + + let event_subject = utils::smart_wrap(event.extract_event_subject(), 70); + let event_author = client.get_username(event.pubkey).await; + let mut event_labels = utils::smart_wrap(&event.extract_event_labels(), 70); + + if event_labels.is_empty() { + event_labels = "\n".to_owned(); + } else { + event_labels = format!("{event_labels}\n\n") + } + + let pr_data = if IS_PR { + // Check if there is an update + let pr_update = client + .fetch_events( + Filter::new() + .kind(crate::cli::pr::PR_UPDATE_KIND) + .custom_tag(SingleLetterTag::uppercase(Alphabet::E), event.id) + .author(event.pubkey), + ) + .await? + .into_iter() + .max_by_key(|e| e.created_at.as_u64()); + + let commit = pr_update + .as_ref() + .unwrap_or(&event) + .tags + .find(TagKind::single_letter(Alphabet::C, false)) + .and_then(|t| t.content()) + .unwrap_or("N/A"); + let branch = event + .tags + .find(TagKind::custom("branch-name")) + .and_then(|t| t.content()) + .unwrap_or("N/A"); + let clones = pr_update + .as_ref() + .unwrap_or(&event) + .tags + .map_tag(TagKind::Clone, |t| { + match t { + nostr::event::TagStandard::GitClone(urls) => urls.clone(), + _ => unreachable!(), + } + }) + .unwrap_or_default(); + + format!( + "\nCommit: {commit}\nBranch: {branch}\nClone:\n{}", + utils::format_iter(clones) + ) + } else { + String::new() + }; + + println!( + "{event_subject} - [by {event_author}]\n{event_labels}{}{pr_data}", + utils::smart_wrap(&event.content, 80) + ); + Ok(()) +}