diff options
Diffstat (limited to 'src/bin')
| -rw-r--r-- | src/bin/ngit/sub_commands/init.rs | 126 |
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 | }; |
| 25 | use nostr::{ | 27 | use 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 | |||
| 1034 | fn 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 | } | ||