diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/push.rs | 92 |
1 files changed, 58 insertions, 34 deletions
diff --git a/src/lib/push.rs b/src/lib/push.rs index c202397..2aafc1d 100644 --- a/src/lib/push.rs +++ b/src/lib/push.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | use std::{ | 1 | use std::{ |
| 2 | collections::HashSet, | 2 | collections::{HashMap, HashSet}, |
| 3 | sync::{Arc, Mutex}, | 3 | sync::{Arc, Mutex}, |
| 4 | time::Instant, | 4 | time::Instant, |
| 5 | }; | 5 | }; |
| @@ -52,18 +52,33 @@ pub fn push_to_remote( | |||
| 52 | 52 | ||
| 53 | let formatted_url = server_url.format_as(protocol, &decoded_nostr_url.user)?; | 53 | let formatted_url = server_url.format_as(protocol, &decoded_nostr_url.user)?; |
| 54 | 54 | ||
| 55 | if let Err(error) = push_to_remote_url(git_repo, &formatted_url, remote_refspecs, term) { | 55 | match push_to_remote_url(git_repo, &formatted_url, remote_refspecs, term) { |
| 56 | term.write_line( | 56 | Err(error) => { |
| 57 | format!("push: {formatted_url} failed over {protocol}: {error}").as_str(), | 57 | term.write_line( |
| 58 | )?; | 58 | format!("push: {formatted_url} failed over {protocol}: {error}").as_str(), |
| 59 | failed_protocols.push(protocol); | 59 | )?; |
| 60 | } else { | 60 | failed_protocols.push(protocol); |
| 61 | success = true; | 61 | } |
| 62 | if !failed_protocols.is_empty() { | 62 | Ok(failed_refs) => { |
| 63 | term.write_line(format!("push: succeeded over {protocol}").as_str())?; | 63 | if let Some((_, error)) = failed_refs.iter().next() { |
| 64 | let _ = set_protocol_preference(git_repo, protocol, &server_url, &Direction::Push); | 64 | term.write_line( |
| 65 | format!("push: {formatted_url} failed over {protocol}: {error}").as_str(), | ||
| 66 | )?; | ||
| 67 | failed_protocols.push(protocol); | ||
| 68 | } else { | ||
| 69 | success = true; | ||
| 70 | if !failed_protocols.is_empty() { | ||
| 71 | term.write_line(format!("push: succeeded over {protocol}").as_str())?; | ||
| 72 | let _ = set_protocol_preference( | ||
| 73 | git_repo, | ||
| 74 | protocol, | ||
| 75 | &server_url, | ||
| 76 | &Direction::Push, | ||
| 77 | ); | ||
| 78 | } | ||
| 79 | break; | ||
| 80 | } | ||
| 65 | } | 81 | } |
| 66 | break; | ||
| 67 | } | 82 | } |
| 68 | } | 83 | } |
| 69 | if success { | 84 | if success { |
| @@ -84,12 +99,13 @@ pub fn push_to_remote( | |||
| 84 | } | 99 | } |
| 85 | } | 100 | } |
| 86 | 101 | ||
| 102 | // returns failed refs as a HashMaps of failed refspec and their error | ||
| 87 | pub fn push_to_remote_url( | 103 | pub fn push_to_remote_url( |
| 88 | git_repo: &Repo, | 104 | git_repo: &Repo, |
| 89 | git_server_url: &str, | 105 | git_server_url: &str, |
| 90 | remote_refspecs: &[String], | 106 | remote_refspecs: &[String], |
| 91 | term: &Term, | 107 | term: &Term, |
| 92 | ) -> Result<()> { | 108 | ) -> Result<HashMap<String, String>> { |
| 93 | let git_config = git_repo.git_repo.config()?; | 109 | let git_config = git_repo.git_repo.config()?; |
| 94 | let mut git_server_remote = git_repo.git_repo.remote_anonymous(git_server_url)?; | 110 | let mut git_server_remote = git_repo.git_repo.remote_anonymous(git_server_url)?; |
| 95 | let auth = GitAuthenticator::default(); | 111 | let auth = GitAuthenticator::default(); |
| @@ -105,6 +121,9 @@ pub fn push_to_remote_url( | |||
| 105 | let mut reporter = push_reporter.lock().unwrap(); | 121 | let mut reporter = push_reporter.lock().unwrap(); |
| 106 | if let Some(error) = error { | 122 | if let Some(error) = error { |
| 107 | let existing_lines = reporter.count_all_existing_lines(); | 123 | let existing_lines = reporter.count_all_existing_lines(); |
| 124 | reporter | ||
| 125 | .failed_refs | ||
| 126 | .insert(name.to_string(), error.to_string()); | ||
| 108 | reporter.update_reference_errors.push(format!( | 127 | reporter.update_reference_errors.push(format!( |
| 109 | "WARNING: {} failed to push {name} error: {error}", | 128 | "WARNING: {} failed to push {name} error: {error}", |
| 110 | get_short_git_server_name(git_repo, git_server_url), | 129 | get_short_git_server_name(git_repo, git_server_url), |
| @@ -186,7 +205,8 @@ pub fn push_to_remote_url( | |||
| 186 | push_options.remote_callbacks(remote_callbacks); | 205 | push_options.remote_callbacks(remote_callbacks); |
| 187 | git_server_remote.push(remote_refspecs, Some(&mut push_options))?; | 206 | git_server_remote.push(remote_refspecs, Some(&mut push_options))?; |
| 188 | let _ = git_server_remote.disconnect(); | 207 | let _ = git_server_remote.disconnect(); |
| 189 | Ok(()) | 208 | let reporter = push_reporter.lock().unwrap(); |
| 209 | Ok(reporter.failed_refs.clone()) | ||
| 190 | } | 210 | } |
| 191 | 211 | ||
| 192 | #[allow(clippy::cast_precision_loss)] | 212 | #[allow(clippy::cast_precision_loss)] |
| @@ -235,6 +255,7 @@ pub struct PushReporter<'a> { | |||
| 235 | negotiation: Vec<String>, | 255 | negotiation: Vec<String>, |
| 236 | transfer_progress_msgs: Vec<String>, | 256 | transfer_progress_msgs: Vec<String>, |
| 237 | update_reference_errors: Vec<String>, | 257 | update_reference_errors: Vec<String>, |
| 258 | failed_refs: HashMap<String, String>, | ||
| 238 | term: &'a console::Term, | 259 | term: &'a console::Term, |
| 239 | start_time: Option<Instant>, | 260 | start_time: Option<Instant>, |
| 240 | end_time: Option<Instant>, | 261 | end_time: Option<Instant>, |
| @@ -246,6 +267,7 @@ impl<'a> PushReporter<'a> { | |||
| 246 | negotiation: vec![], | 267 | negotiation: vec![], |
| 247 | transfer_progress_msgs: vec![], | 268 | transfer_progress_msgs: vec![], |
| 248 | update_reference_errors: vec![], | 269 | update_reference_errors: vec![], |
| 270 | failed_refs: HashMap::new(), | ||
| 249 | term, | 271 | term, |
| 250 | start_time: None, | 272 | start_time: None, |
| 251 | end_time: None, | 273 | end_time: None, |
| @@ -334,7 +356,7 @@ pub async fn push_refs_and_generate_pr_or_pr_update_event( | |||
| 334 | signer: &Arc<dyn NostrSigner>, | 356 | signer: &Arc<dyn NostrSigner>, |
| 335 | term: &Term, | 357 | term: &Term, |
| 336 | ) -> Result<(Option<Vec<Event>>, Vec<(String, Result<()>)>)> { | 358 | ) -> Result<(Option<Vec<Event>>, Vec<(String, Result<()>)>)> { |
| 337 | let mut responses = vec![]; | 359 | let mut responses: Vec<(String, Result<()>)> = vec![]; |
| 338 | 360 | ||
| 339 | let mut unsigned_pr_event: Option<UnsignedEvent> = None; | 361 | let mut unsigned_pr_event: Option<UnsignedEvent> = None; |
| 340 | for clone_url in servers { | 362 | for clone_url in servers { |
| @@ -360,25 +382,27 @@ pub async fn push_refs_and_generate_pr_or_pr_update_event( | |||
| 360 | 382 | ||
| 361 | let refspec = format!("{tip}:{git_ref_used}"); | 383 | let refspec = format!("{tip}:{git_ref_used}"); |
| 362 | 384 | ||
| 363 | if let Err(error) = push_to_remote_url(git_repo, clone_url, &[refspec], term) { | 385 | match push_to_remote_url(git_repo, clone_url, &[refspec], term) { |
| 364 | term.write_line( | 386 | Err(error) => { |
| 365 | format!( | 387 | let normalized_url = normalize_grasp_server_url(clone_url)?; |
| 366 | "push: error sending commit data to {}: {error}", | 388 | term.write_line(&format!( |
| 367 | normalize_grasp_server_url(clone_url)? | 389 | "push: error sending commit data to {normalized_url}: {error}" |
| 368 | ) | 390 | ))?; |
| 369 | .as_str(), | 391 | responses.push((clone_url.clone(), Err(anyhow!(error)))); |
| 370 | )?; | 392 | } |
| 371 | responses.push((clone_url.clone(), Err(error))); | 393 | Ok(failed_refs) => { |
| 372 | } else { | 394 | let normalized_url = normalize_grasp_server_url(clone_url)?; |
| 373 | responses.push((clone_url.clone(), Ok(()))); | 395 | if let Some((_, error)) = failed_refs.iter().next() { |
| 374 | term.write_line( | 396 | term.write_line(&format!( |
| 375 | format!( | 397 | "push: error sending commit data to {normalized_url}: {error}" |
| 376 | "push: commit data sent to {}", | 398 | ))?; |
| 377 | normalize_grasp_server_url(clone_url)? | 399 | responses.push((clone_url.clone(), Err(anyhow!(error.clone())))); |
| 378 | ) | 400 | } else { |
| 379 | .as_str(), | 401 | responses.push((clone_url.clone(), Ok(()))); |
| 380 | )?; | 402 | term.write_line(&format!("push: commit data sent to {normalized_url}"))?; |
| 381 | unsigned_pr_event = Some(draft_pr_event); | 403 | unsigned_pr_event = Some(draft_pr_event); |
| 404 | } | ||
| 405 | } | ||
| 382 | } | 406 | } |
| 383 | } | 407 | } |
| 384 | if let Some(unsigned_pr_event) = unsigned_pr_event { | 408 | if let Some(unsigned_pr_event) = unsigned_pr_event { |