upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-09-10 16:32:18 +0100
committerDanConwayDev <DanConwayDev@protonmail.com>2025-09-10 16:32:18 +0100
commit732567f85383782851d3c0dd43283d29df0c098f (patch)
tree706d3088eef39a8d701c8360ce0291e5f615abc2 /src/bin
parent8527646022abdb290222a45314d090eef0871cae (diff)
fix(init): when existing origin matches tip
when an existing origin exists and local branch is up-to-date `git push` wont successfully publish state event and push refs to other git servers listed. we now publish the state event during this init function and use sync to push all refs in state are to all git servers.
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/ngit/sub_commands/init.rs126
1 files changed, 118 insertions, 8 deletions
diff --git a/src/bin/ngit/sub_commands/init.rs b/src/bin/ngit/sub_commands/init.rs
index 98daee4..1b8268c 100644
--- a/src/bin/ngit/sub_commands/init.rs
+++ b/src/bin/ngit/sub_commands/init.rs
@@ -15,12 +15,14 @@ use ngit::{
15 PromptChoiceParms, PromptConfirmParms, multi_select_with_custom_value, 15 PromptChoiceParms, PromptConfirmParms, multi_select_with_custom_value,
16 show_multi_input_prompt_success, 16 show_multi_input_prompt_success,
17 }, 17 },
18 client::{Params, send_events}, 18 client::{Params, get_state_from_cache, send_events},
19 git::nostr_url::{CloneUrl, NostrUrlDecoded}, 19 git::nostr_url::{CloneUrl, NostrUrlDecoded},
20 list::list_from_remote,
20 repo_ref::{ 21 repo_ref::{
21 detect_existing_grasp_servers, extract_npub, extract_pks, 22 detect_existing_grasp_servers, extract_npub, extract_pks,
22 format_grasp_server_url_as_relay_url, normalize_grasp_server_url, save_repo_config_to_yaml, 23 format_grasp_server_url_as_relay_url, normalize_grasp_server_url, save_repo_config_to_yaml,
23 }, 24 },
25 repo_state::RepoState,
24}; 26};
25use nostr::{ 27use nostr::{
26 FromBech32, PublicKey, ToBech32, 28 FromBech32, PublicKey, ToBech32,
@@ -754,12 +756,67 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {
754 }; 756 };
755 let repo_event = repo_ref.to_event(&signer).await?; 757 let repo_event = repo_ref.to_event(&signer).await?;
756 758
759 let nostr_url_decoded = repo_ref.to_nostr_git_url(&Some(&git_repo));
760
761 let mut events = vec![repo_event];
762
763 let (need_push, need_sync) = if std::env::var("NGITTEST").is_ok() || no_state {
764 // dont push or sync during tests as git-remote-nostr isn't installed during
765 // ngit binary tests
766 (false, false)
767 } else if let Ok(nostr_state) =
768 &get_state_from_cache(Some(git_repo.get_path()?), &repo_ref).await
769 {
770 // issue fresh state event with same state to all (inc. new) repo relays
771 let new_state_event = RepoState::build(
772 repo_ref.identifier.clone(),
773 nostr_state.state.clone(),
774 &signer,
775 )
776 .await?
777 .event;
778 events.push(new_state_event);
779 println!("publishing repostory state to nostr...");
780 (false, true)
781 } else if let Ok(remote) = git_repo.git_repo.find_remote("origin") {
782 if let Some(url) = remote.url() {
783 // issue a state event with origin state, to all (inc. new) repo relays
784 if let Ok(mut origin_state) =
785 list_from_remote(&Term::stdout(), &git_repo, url, &nostr_url_decoded, false)
786 {
787 origin_state.retain(|key, _| {
788 key.starts_with("refs/heads/")
789 || key.starts_with("refs/tags/")
790 || key.starts_with("HEAD")
791 });
792 // TODO ngit sync will error if any of these remote refs are not available
793 // locally
794 let new_state_event =
795 RepoState::build(repo_ref.identifier.clone(), origin_state, &signer)
796 .await?
797 .event;
798 events.push(new_state_event);
799 println!("publishing repostory state to nostr...");
800 (false, true)
801 } else {
802 // cant reach existing origin so just try push
803 (true, false)
804 }
805 } else {
806 // origin never connected so just try push
807 (true, false)
808 }
809 } else {
810 // no origin so we need to just push
811 (true, false)
812 };
813
757 client.set_signer(signer).await; 814 client.set_signer(signer).await;
758 815
759 send_events( 816 send_events(
760 &client, 817 &client,
761 Some(git_repo_path), 818 Some(git_repo_path),
762 vec![repo_event], 819 events,
763 user_ref.relays.write(), 820 user_ref.relays.write(),
764 relays.clone(), 821 relays.clone(),
765 !cli_args.disable_cli_spinners, 822 !cli_args.disable_cli_spinners,
@@ -783,7 +840,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {
783 )?; 840 )?;
784 841
785 // set origin remote 842 // set origin remote
786 let nostr_url = repo_ref.to_nostr_git_url(&Some(&git_repo)).to_string(); 843 let nostr_url = nostr_url_decoded.to_string();
787 844
788 if git_repo.git_repo.find_remote("origin").is_ok() { 845 if git_repo.git_repo.find_remote("origin").is_ok() {
789 git_repo.git_repo.remote_set_url("origin", &nostr_url)?; 846 git_repo.git_repo.remote_set_url("origin", &nostr_url)?;
@@ -792,12 +849,9 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {
792 } 849 }
793 println!("set remote origin to nostr url"); 850 println!("set remote origin to nostr url");
794 851
795 if std::env::var("NGITTEST").is_err() { 852 if need_push {
796 // ignore during tests as git-remote-nostr isn't installed during ngit binary
797 // tests
798
799 if selected_grasp_servers.is_empty() { 853 if selected_grasp_servers.is_empty() {
800 println!("running `git push` to publish your repository data"); 854 println!("running `ngit push` to publish your repository data");
801 } else { 855 } else {
802 let countdown_start = 5; 856 let countdown_start = 5;
803 println!( 857 println!(
@@ -818,6 +872,31 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {
818 ); 872 );
819 } 873 }
820 } 874 }
875 if need_sync {
876 if selected_grasp_servers.is_empty() {
877 println!(
878 "running `ngit sync` to ensure your repository data is available on repository git servers"
879 );
880 } else {
881 let countdown_start = 5;
882 println!(
883 "waiting {countdown_start}s for any new grasp servers to create your repo before we sync your data"
884 );
885 let term = Term::stdout();
886 for i in (1..=countdown_start).rev() {
887 term.write_line(format!("\rrunning `ngit sync` in {i}s").as_str())?;
888 thread::sleep(Duration::new(1, 0)); // Sleep for 1 second
889 term.clear_last_lines(1)?;
890 }
891 term.flush().unwrap(); // Ensure the output is flushed to the terminal
892 }
893
894 if let Err(err) = run_ngit_sync() {
895 println!(
896 "your repository announcement was published to nostr but 'ngit sync' exited with an error: {err}"
897 );
898 }
899 }
821 900
822 // println!( 901 // println!(
823 // "any remote branches beginning with `pr/` are open PRs from contributors. 902 // "any remote branches beginning with `pr/` are open PRs from contributors.
@@ -951,3 +1030,34 @@ fn push_main_or_master_branch(git_repo: &Repo) -> Result<()> {
951 bail!("git push process exited with an error: {}", exit_status); 1030 bail!("git push process exited with an error: {}", exit_status);
952 } 1031 }
953} 1032}
1033
1034fn run_ngit_sync() -> Result<()> {
1035 println!("========================================");
1036 println!(" NGIT SYNC COMMAND ");
1037 println!("========================================");
1038
1039 let command = "ngit";
1040 let args = ["sync"];
1041
1042 // Spawn the process
1043 let mut child = Command::new(command)
1044 .args(args)
1045 .stdout(Stdio::inherit()) // Redirect stdout to the console
1046 .stderr(Stdio::inherit()) // Redirect stderr to the console
1047 .spawn()
1048 .context("Failed to start ngit sync process")?;
1049
1050 // Wait for the process to finish
1051 let exit_status = child.wait().context("Failed to start ngit sync process")?;
1052
1053 println!("========================================");
1054 println!(" END OF NGIT SYNC OUTPUT");
1055 println!("========================================");
1056
1057 // Check the exit status
1058 if exit_status.success() {
1059 Ok(())
1060 } else {
1061 bail!("ngit sync process exited with an error: {}", exit_status);
1062 }
1063}