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:
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}