From 57321aa9136293b24757a6695a5c92087af539ab Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Wed, 1 Nov 2023 00:00:00 +0000 Subject: feat(prs-create) send to repo relays fetch repository reference events to identify repository relays send pr events to repository relays alongside user relays --- src/repo_ref.rs | 105 ++++++++++++++++++++++++++++++++++++++++- src/sub_commands/prs/create.rs | 23 +++++---- 2 files changed, 116 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/repo_ref.rs b/src/repo_ref.rs index 3b0b1b4..a92b5b3 100644 --- a/src/repo_ref.rs +++ b/src/repo_ref.rs @@ -1,6 +1,12 @@ -use anyhow::{Context, Result}; +use anyhow::{bail, Context, Result}; use nostr::Tag; +#[cfg(not(test))] +use crate::client::Client; +use crate::client::Connect; +#[cfg(test)] +use crate::client::MockConnect; + #[derive(Default)] pub struct RepoRef { pub name: String, @@ -12,10 +18,43 @@ pub struct RepoRef { // code languages and hashtags } +impl TryFrom for RepoRef { + type Error = anyhow::Error; + + fn try_from(event: nostr::Event) -> Result { + if !event.kind.as_u64().eq(&REPO_REF_KIND) { + bail!("incorrect kind"); + } + let mut r = Self::default(); + + if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("name")) { + r.name = t.as_vec()[1].clone(); + } + + if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("description")) { + r.description = t.as_vec()[1].clone(); + } + + if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("d")) { + r.root_commit = t.as_vec()[1].clone(); + } + + r.relays = event + .tags + .iter() + .filter(|t| t.as_vec()[0].eq("relay")) + .map(|t| t.as_vec()[1].clone()) + .collect(); + + Ok(r) + } +} +static REPO_REF_KIND: u64 = 300_317; + impl RepoRef { pub fn to_event(&self, keys: &nostr::Keys) -> Result { nostr_sdk::EventBuilder::new( - nostr::event::Kind::Custom(30017), + nostr::event::Kind::Custom(REPO_REF_KIND), "", &[ vec![ @@ -36,6 +75,36 @@ impl RepoRef { } } +pub async fn fetch( + root_commit: String, + #[cfg(test)] client: &MockConnect, + #[cfg(not(test))] client: &Client, + // TODO: more rubust way of finding repo events + relays: Vec, +) -> Result { + // TODO: fetch relay information from file + + let events: Vec = client + .get_events( + relays, + vec![ + nostr::Filter::default() + .kind(nostr::Kind::Custom(REPO_REF_KIND)) + .identifier(root_commit), + ], + ) + .await?; + + RepoRef::try_from( + events + .iter() + .filter(|e| e.kind.as_u64() == REPO_REF_KIND) + .max_by_key(|e| e.created_at) + .context("cannot find repository reference event")? + .clone(), + ) +} + #[cfg(test)] mod tests { use test_utils::*; @@ -52,6 +121,38 @@ mod tests { .to_event(&TEST_KEY_1_KEYS) .unwrap() } + mod try_from { + use super::*; + + #[test] + fn name() { + assert_eq!(RepoRef::try_from(create()).unwrap().name, "test name",) + } + + #[test] + fn description() { + assert_eq!( + RepoRef::try_from(create()).unwrap().description, + "test description", + ) + } + + #[test] + fn root_commit() { + assert_eq!( + RepoRef::try_from(create()).unwrap().root_commit, + "23471389461", + ) + } + + #[test] + fn relays() { + assert_eq!( + RepoRef::try_from(create()).unwrap().relays, + vec!["ws://relay1.io".to_string(), "ws://relay2.io".to_string()], + ) + } + } mod to_event { use super::*; diff --git a/src/sub_commands/prs/create.rs b/src/sub_commands/prs/create.rs index d82f53e..e85611f 100644 --- a/src/sub_commands/prs/create.rs +++ b/src/sub_commands/prs/create.rs @@ -13,7 +13,7 @@ use crate::{ cli_interactor::{Interactor, InteractorPrompt, PromptConfirmParms, PromptInputParms}, client::Connect, git::{Repo, RepoActions}, - login, Cli, + login, repo_ref, Cli, }; #[derive(Debug, clap::Args)] @@ -99,11 +99,16 @@ pub async fn launch( let events = generate_pr_and_patch_events(&title, &description, &to_branch, &git_repo, &ahead, &keys)?; - // TODO: get relays from repo event - let repo_read_relays: Vec = vec![ - "ws://localhost:8055".to_string(), - "ws://localhost:8056".to_string(), - ]; + let repo_ref = repo_ref::fetch( + git_repo + .get_root_commit(&to_branch) + .context("failed to get root commit of the repository")? + .to_string(), + &client, + // TODO: get relay list from local yaml file + user_ref.relays.write(), + ) + .await?; println!( "posting 1 pull request with {} commits...", @@ -114,12 +119,11 @@ pub async fn launch( &client, events, user_ref.relays.write(), - repo_read_relays, + repo_ref.relays.clone(), !cli_args.disable_cli_spinners, ) .await?; - // TODO check if there is already a similarly named PR - + // TODO check if there is already a similarly named Ok(()) } @@ -212,7 +216,6 @@ pub async fn send_events( } })) .await; - client.disconnect().await?; Ok(()) } -- cgit v1.2.3