upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/push.rs92
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 @@
1use std::{ 1use 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
87pub fn push_to_remote_url( 103pub 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 {