From 24125936adb6c152cdb16d55f2639dd374dfee1d Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Thu, 1 Aug 2024 10:17:01 +0100 Subject: feat(remote): `push` to all `clone` servers initially we push to the first server, if successful update the state event, then siliently push to the others and silently fail --- src/git_remote_helper.rs | 18 ++++++ test_utils/src/git.rs | 2 +- test_utils/src/lib.rs | 6 +- tests/git_remote_helper.rs | 137 ++++++++++++++++++++++++++++++++++++++------- 4 files changed, 140 insertions(+), 23 deletions(-) diff --git a/src/git_remote_helper.rs b/src/git_remote_helper.rs index de49275..d0c0005 100644 --- a/src/git_remote_helper.rs +++ b/src/git_remote_helper.rs @@ -270,6 +270,24 @@ async fn push( ) .await?; + // silently push to any other git servers + for (i, git_server_url) in repo_ref.git_server.iter().enumerate() { + // we have already pushed to the first one + if i.gt(&0) { + if let Ok(mut git_server_remote) = git_repo.git_repo.remote_anonymous(git_server_url) { + let auth = GitAuthenticator::default(); + let git_config = git_repo.git_repo.config()?; + let mut push_options = git2::PushOptions::new(); + let mut remote_callbacks = git2::RemoteCallbacks::new(); + remote_callbacks.credentials(auth.credentials(&git_config)); + push_options.remote_callbacks(remote_callbacks); + let _ = git_server_remote.push(&refspecs, Some(&mut push_options)); + let _ = git_server_remote.disconnect(); + } + } + } + // todo report on errors + println!(); Ok(()) } diff --git a/test_utils/src/git.rs b/test_utils/src/git.rs index 4a4aaa8..e522ffd 100644 --- a/test_utils/src/git.rs +++ b/test_utils/src/git.rs @@ -62,7 +62,7 @@ impl GitTestRepo { Self::new("main").unwrap() } - fn duplicate(existing_repo: &GitTestRepo) -> Result { + pub fn duplicate(existing_repo: &GitTestRepo) -> Result { let path = current_dir()?.join(format!("tmpgit-{}", rand::random::())); // function source: https://stackoverflow.com/a/65192210 fn copy_dir_all(src: impl AsRef, dst: impl AsRef) -> std::io::Result<()> { diff --git a/test_utils/src/lib.rs b/test_utils/src/lib.rs index 7a2bf35..2e7a4e8 100644 --- a/test_utils/src/lib.rs +++ b/test_utils/src/lib.rs @@ -150,10 +150,10 @@ pub fn make_event_old_or_change_user( } pub fn generate_repo_ref_event() -> nostr::Event { - generate_repo_ref_event_with_git_server("git:://123.gitexample.com/test") + generate_repo_ref_event_with_git_server(vec!["git:://123.gitexample.com/test".to_string()]) } -pub fn generate_repo_ref_event_with_git_server(git_server: &str) -> nostr::Event { +pub fn generate_repo_ref_event_with_git_server(git_servers: Vec) -> nostr::Event { // taken from test git_repo // TODO - this may not be consistant across computers as it might take the // author and committer from global git config @@ -171,7 +171,7 @@ pub fn generate_repo_ref_event_with_git_server(git_server: &str) -> nostr::Event Tag::from_standardized(TagStandard::Description("example description".into())), Tag::custom( nostr::TagKind::Custom(std::borrow::Cow::Borrowed("clone")), - vec![git_server.to_string()], + git_servers, ), Tag::custom( nostr::TagKind::Custom(std::borrow::Cow::Borrowed("web")), diff --git a/tests/git_remote_helper.rs b/tests/git_remote_helper.rs index 20ecad7..69f290a 100644 --- a/tests/git_remote_helper.rs +++ b/tests/git_remote_helper.rs @@ -63,7 +63,9 @@ async fn generate_repo_with_state_event() -> Result<(nostr::Event, GitTestRepo)> let events = vec![ generate_test_key_1_metadata_event("fred"), generate_test_key_1_relay_list_event(), - generate_repo_ref_event_with_git_server(source_git_repo.dir.to_str().unwrap()), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + ]), ]; // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = ( @@ -136,7 +138,9 @@ mod initially_runs_fetch { let events = vec![ generate_test_key_1_metadata_event("fred"), generate_test_key_1_relay_list_event(), - generate_repo_ref_event_with_git_server(source_git_repo.dir.to_str().unwrap()), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + ]), ]; // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = ( @@ -203,7 +207,9 @@ mod list { let events = vec![ generate_test_key_1_metadata_event("fred"), generate_test_key_1_relay_list_event(), - generate_repo_ref_event_with_git_server(source_git_repo.dir.to_str().unwrap()), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + ]), ]; // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = ( @@ -276,7 +282,9 @@ mod list { let events = vec![ generate_test_key_1_metadata_event("fred"), generate_test_key_1_relay_list_event(), - generate_repo_ref_event_with_git_server(source_git_repo.dir.to_str().unwrap()), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + ]), state_event, ]; // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) @@ -357,7 +365,9 @@ mod list { let events = vec![ generate_test_key_1_metadata_event("fred"), generate_test_key_1_relay_list_event(), - generate_repo_ref_event_with_git_server(source_git_repo.dir.to_str().unwrap()), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + ]), state_event, ]; // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) @@ -433,7 +443,9 @@ mod fetch { let events = vec![ generate_test_key_1_metadata_event("fred"), generate_test_key_1_relay_list_event(), - generate_repo_ref_event_with_git_server(source_git_repo.dir.to_str().unwrap()), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + ]), ]; // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = ( @@ -513,7 +525,9 @@ mod push { let events = vec![ generate_test_key_1_metadata_event("fred"), generate_test_key_1_relay_list_event(), - generate_repo_ref_event_with_git_server(source_git_repo.dir.to_str().unwrap()), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + ]), ]; // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = ( @@ -595,7 +609,9 @@ mod push { let events = vec![ generate_test_key_1_metadata_event("fred"), generate_test_key_1_relay_list_event(), - generate_repo_ref_event_with_git_server(source_git_repo.dir.to_str().unwrap()), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + ]), ]; // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = ( @@ -688,9 +704,9 @@ mod push { let events = vec![ generate_test_key_1_metadata_event("fred"), generate_test_key_1_relay_list_event(), - generate_repo_ref_event_with_git_server( - source_git_repo.dir.to_str().unwrap(), - ), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + ]), ]; // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = ( @@ -788,9 +804,9 @@ mod push { let events = vec![ generate_test_key_1_metadata_event("fred"), generate_test_key_1_relay_list_event(), - generate_repo_ref_event_with_git_server( - source_git_repo.dir.to_str().unwrap(), - ), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + ]), state_event.clone(), ]; @@ -918,7 +934,9 @@ mod push { let events = vec![ generate_test_key_1_metadata_event("fred"), generate_test_key_1_relay_list_event(), - generate_repo_ref_event_with_git_server(source_git_repo.dir.to_str().unwrap()), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + ]), ]; // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = ( @@ -1003,7 +1021,9 @@ mod push { let events = vec![ generate_test_key_1_metadata_event("fred"), generate_test_key_1_relay_list_event(), - generate_repo_ref_event_with_git_server(source_git_repo.dir.to_str().unwrap()), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + ]), ]; // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = ( @@ -1083,9 +1103,9 @@ mod push { let events = vec![ generate_test_key_1_metadata_event("fred"), generate_test_key_1_relay_list_event(), - generate_repo_ref_event_with_git_server( - source_git_repo.dir.to_str().unwrap(), - ), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + ]), state_event.clone(), ]; @@ -1155,4 +1175,83 @@ mod push { } } } + + mod pushes_to_all_git_servers_listed { + use super::*; + async fn async_run_test() -> Result<()> { + let (state_event, source_git_repo) = generate_repo_with_state_event().await?; + let second_source_git_repo = GitTestRepo::duplicate(&source_git_repo)?; + + // uppdate announcement with extra git server + + let git_repo = prep_git_repo()?; + + std::fs::write(git_repo.dir.join("new.md"), "some content")?; + let main_commit_id = git_repo.stage_and_commit("new.md")?; + + let events = vec![ + generate_test_key_1_metadata_event("fred"), + generate_test_key_1_relay_list_event(), + generate_repo_ref_event_with_git_server(vec![ + source_git_repo.dir.to_str().unwrap().to_string(), + second_source_git_repo.dir.to_str().unwrap().to_string(), + ]), + state_event.clone(), + ]; + + // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) + let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = ( + Relay::new(8051, None, None), + Relay::new(8052, None, None), + Relay::new(8053, None, None), + Relay::new(8055, None, None), + Relay::new(8056, None, None), + Relay::new(8057, None, None), + ); + r51.events = events.clone(); + r55.events = events; + + let cli_tester_handle = std::thread::spawn(move || -> Result<()> { + let mut p = cli_tester_after_fetch(&git_repo)?; + p.send_line("push refs/heads/main:refs/heads/main")?; + p.send_line("")?; + p.expect("ok refs/heads/main\r\n")?; + p.expect("\r\n")?; + p.exit()?; + for p in [51, 52, 53, 55, 56, 57] { + relay::shutdown_relay(8000 + p)?; + } + Ok(()) + }); + // launch relays + let _ = join!( + r51.listen_until_close(), + r52.listen_until_close(), + r53.listen_until_close(), + r55.listen_until_close(), + r56.listen_until_close(), + r57.listen_until_close(), + ); + + cli_tester_handle.join().unwrap()?; + + // git_server updated + assert_eq!( + source_git_repo.get_tip_of_local_branch("main")?, + main_commit_id + ); + assert_eq!( + second_source_git_repo.get_tip_of_local_branch("main")?, + main_commit_id + ); + + Ok(()) + } + + #[tokio::test] + #[serial] + async fn second_git_server_uptodate() -> Result<()> { + async_run_test().await + } + } } -- cgit v1.2.3