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 +++++---- test_utils/src/lib.rs | 23 ++++++++- tests/claim.rs | 2 - tests/prs_create.rs | 52 ++++++++++++++++++-- 5 files changed, 186 insertions(+), 19 deletions(-) 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(()) } diff --git a/test_utils/src/lib.rs b/test_utils/src/lib.rs index 3cb5d65..e867a7b 100644 --- a/test_utils/src/lib.rs +++ b/test_utils/src/lib.rs @@ -3,7 +3,7 @@ use std::{ffi::OsStr, path::PathBuf}; use anyhow::{ensure, Context, Result}; use dialoguer::theme::{ColorfulTheme, Theme}; use directories::ProjectDirs; -use nostr::{self, prelude::FromSkStr}; +use nostr::{self, prelude::FromSkStr, Tag}; use once_cell::sync::Lazy; use rexpect::session::{Options, PtySession}; use strip_ansi_escapes::strip_str; @@ -120,6 +120,27 @@ pub fn make_event_old_or_change_user( unsigned.sign(keys).unwrap() } +pub static REPOSITORY_KIND: u64 = 300317; + +pub fn generate_repo_ref_event() -> nostr::Event { + // taken from test git_repo + let root_commit = "9ee507fc4357d7ee16a5d8901bedcd103f23c17d"; + nostr::event::EventBuilder::new( + nostr::Kind::Custom(REPOSITORY_KIND), + "", + &[ + Tag::Identifier(root_commit.to_string()), + Tag::Reference(format!("r-{}", root_commit)), + Tag::Name("example name".to_string()), + Tag::Description("example description".to_string()), + Tag::Relay("ws://localhost:8055".into()), + Tag::Relay("ws://localhost:8056".into()), + ], + ) + .to_event(&TEST_KEY_1_KEYS) + .unwrap() +} + /// wrapper for a cli testing tool - currently wraps rexpect and dialoguer /// /// 1. allow more accurate articulation of expected behaviour diff --git a/tests/claim.rs b/tests/claim.rs index 914b12e..61be68b 100644 --- a/tests/claim.rs +++ b/tests/claim.rs @@ -17,8 +17,6 @@ mod sends_repoistory_to_relays { use super::*; - static REPOSITORY_KIND: u64 = 30017; - fn prep_git_repo() -> Result { let test_repo = GitTestRepo::default(); test_repo.populate()?; diff --git a/tests/prs_create.rs b/tests/prs_create.rs index 3a28016..3b8aa31 100644 --- a/tests/prs_create.rs +++ b/tests/prs_create.rs @@ -218,7 +218,18 @@ mod sends_pr_and_2_patches_to_3_relays { ), Relay::new(8052, None, None), Relay::new(8053, None, None), - Relay::new(8055, None, None), + Relay::new( + 8055, + None, + Some(&|relay, client_id, subscription_id, _| -> Result<()> { + relay.respond_events( + client_id, + &subscription_id, + &vec![generate_repo_ref_event()], + )?; + Ok(()) + }), + ), Relay::new(8056, None, None), ); @@ -521,7 +532,18 @@ mod sends_pr_and_2_patches_to_3_relays { ), Relay::new(8052, None, None), Relay::new(8053, None, None), - Relay::new(8055, None, None), + Relay::new( + 8055, + None, + Some(&|relay, client_id, subscription_id, _| -> Result<()> { + relay.respond_events( + client_id, + &subscription_id, + &vec![generate_repo_ref_event()], + )?; + Ok(()) + }), + ), Relay::new(8056, None, None), ); @@ -592,7 +614,18 @@ mod sends_pr_and_2_patches_to_3_relays { ), Relay::new(8052, None, None), Relay::new(8053, None, None), - Relay::new(8055, None, None), + Relay::new( + 8055, + None, + Some(&|relay, client_id, subscription_id, _| -> Result<()> { + relay.respond_events( + client_id, + &subscription_id, + &vec![generate_repo_ref_event()], + )?; + Ok(()) + }), + ), Relay::new( 8056, Some(&|relay, client_id, event| -> Result<()> { @@ -660,7 +693,18 @@ mod sends_pr_and_2_patches_to_3_relays { ), Relay::new(8052, None, None), Relay::new(8053, None, None), - Relay::new(8055, None, None), + Relay::new( + 8055, + None, + Some(&|relay, client_id, subscription_id, _| -> Result<()> { + relay.respond_events( + client_id, + &subscription_id, + &vec![generate_repo_ref_event()], + )?; + Ok(()) + }), + ), Relay::new( 8056, Some(&|relay, client_id, event| -> Result<()> { -- cgit v1.2.3