diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2025-08-07 12:55:14 +0100 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2025-08-07 17:40:33 +0100 |
| commit | 3b5c48f5a2a4b9be5d14baa8f5e801fefd5c1166 (patch) | |
| tree | 3e04a7aa639fa716765cf673d8ac99488c5d92bc /src | |
| parent | 646d05e44946c5a248cb8c5b7d852ed316b9592e (diff) | |
fix(send):server not confirming acceptance
don't treat this as accepted
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/push.rs | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/src/lib/push.rs b/src/lib/push.rs index a5a29a2..0ee66cf 100644 --- a/src/lib/push.rs +++ b/src/lib/push.rs | |||
| @@ -32,7 +32,7 @@ use crate::{ | |||
| 32 | }, | 32 | }, |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | // returns failed refs as a HashMaps of failed refspec and their error | 35 | // returns a HashMap of refs responded to and any related cancellation reasons |
| 36 | pub fn push_to_remote( | 36 | pub fn push_to_remote( |
| 37 | git_repo: &Repo, | 37 | git_repo: &Repo, |
| 38 | git_server_url: &str, | 38 | git_server_url: &str, |
| @@ -40,14 +40,14 @@ pub fn push_to_remote( | |||
| 40 | remote_refspecs: &[String], | 40 | remote_refspecs: &[String], |
| 41 | term: &Term, | 41 | term: &Term, |
| 42 | is_grasp_server: bool, | 42 | is_grasp_server: bool, |
| 43 | ) -> Result<HashMap<String, String>> { | 43 | ) -> Result<HashMap<String, Option<String>>> { |
| 44 | let server_url = git_server_url.parse::<CloneUrl>()?; | 44 | let server_url = git_server_url.parse::<CloneUrl>()?; |
| 45 | let protocols_to_attempt = | 45 | let protocols_to_attempt = |
| 46 | get_write_protocols_to_try(git_repo, &server_url, decoded_nostr_url, is_grasp_server); | 46 | get_write_protocols_to_try(git_repo, &server_url, decoded_nostr_url, is_grasp_server); |
| 47 | 47 | ||
| 48 | let mut failed_protocols = vec![]; | 48 | let mut failed_protocols = vec![]; |
| 49 | let mut success = false; | 49 | let mut success = false; |
| 50 | let mut failed_refs = HashMap::new(); | 50 | let mut ref_updates = HashMap::new(); |
| 51 | 51 | ||
| 52 | for protocol in &protocols_to_attempt { | 52 | for protocol in &protocols_to_attempt { |
| 53 | term.write_line(format!("push: {} over {protocol}...", server_url.short_name(),).as_str())?; | 53 | term.write_line(format!("push: {} over {protocol}...", server_url.short_name(),).as_str())?; |
| @@ -61,9 +61,13 @@ pub fn push_to_remote( | |||
| 61 | )?; | 61 | )?; |
| 62 | failed_protocols.push(protocol); | 62 | failed_protocols.push(protocol); |
| 63 | } | 63 | } |
| 64 | Ok(failed_refs_on_protocol) => { | 64 | Ok(ref_updates_on_protocol) => { |
| 65 | success = true; | 65 | success = true; |
| 66 | if failed_refs_on_protocol.is_empty() { | 66 | if remote_refspecs.len() == ref_updates_on_protocol.len() |
| 67 | && ref_updates_on_protocol | ||
| 68 | .values() | ||
| 69 | .all(|error| error.is_none()) | ||
| 70 | { | ||
| 67 | if !failed_protocols.is_empty() { | 71 | if !failed_protocols.is_empty() { |
| 68 | term.write_line(format!("push: succeeded over {protocol}").as_str())?; | 72 | term.write_line(format!("push: succeeded over {protocol}").as_str())?; |
| 69 | let _ = set_protocol_preference( | 73 | let _ = set_protocol_preference( |
| @@ -80,19 +84,22 @@ pub fn push_to_remote( | |||
| 80 | "push: {formatted_url} with {protocol} complete but {}ref{} not accepted:", | 84 | "push: {formatted_url} with {protocol} complete but {}ref{} not accepted:", |
| 81 | if remote_refspecs.len() != failed_protocols.len() { "some " } else {""}, | 85 | if remote_refspecs.len() != failed_protocols.len() { "some " } else {""}, |
| 82 | if remote_refspecs.len() == 1 { "s"} else {""}, | 86 | if remote_refspecs.len() == 1 { "s"} else {""}, |
| 83 | ).as_str(), | 87 | ).as_str(), |
| 84 | )?; | 88 | )?; |
| 85 | for (git_ref, error) in &failed_refs_on_protocol { | 89 | for (git_ref, error) in &ref_updates_on_protocol { |
| 86 | term.write_line(format!("push: - {git_ref}: {error}").as_str())?; | 90 | if let Some(error) = error { |
| 91 | term.write_line(format!("push: - {git_ref}: {error}").as_str())?; | ||
| 92 | } | ||
| 87 | } | 93 | } |
| 88 | failed_refs = failed_refs_on_protocol; | 94 | // TODO do we want to report on the refs that weren't responded to? |
| 95 | ref_updates = ref_updates_on_protocol; | ||
| 89 | } | 96 | } |
| 90 | break; | 97 | break; |
| 91 | } | 98 | } |
| 92 | } | 99 | } |
| 93 | } | 100 | } |
| 94 | if success { | 101 | if success { |
| 95 | Ok(failed_refs) | 102 | Ok(ref_updates) |
| 96 | } else { | 103 | } else { |
| 97 | let error = anyhow!( | 104 | let error = anyhow!( |
| 98 | "{} failed over {}{}", | 105 | "{} failed over {}{}", |
| @@ -109,13 +116,13 @@ pub fn push_to_remote( | |||
| 109 | } | 116 | } |
| 110 | } | 117 | } |
| 111 | 118 | ||
| 112 | // returns failed refs as a HashMaps of failed refspec and their error | 119 | // returns HashMaps of refspecs responded to and any failure message |
| 113 | pub fn push_to_remote_url( | 120 | pub fn push_to_remote_url( |
| 114 | git_repo: &Repo, | 121 | git_repo: &Repo, |
| 115 | git_server_url: &str, | 122 | git_server_url: &str, |
| 116 | remote_refspecs: &[String], | 123 | remote_refspecs: &[String], |
| 117 | term: &Term, | 124 | term: &Term, |
| 118 | ) -> Result<HashMap<String, String>> { | 125 | ) -> Result<HashMap<String, Option<String>>> { |
| 119 | let git_config = git_repo.git_repo.config()?; | 126 | let git_config = git_repo.git_repo.config()?; |
| 120 | let mut git_server_remote = git_repo.git_repo.remote_anonymous(git_server_url)?; | 127 | let mut git_server_remote = git_repo.git_repo.remote_anonymous(git_server_url)?; |
| 121 | let auth = GitAuthenticator::default(); | 128 | let auth = GitAuthenticator::default(); |
| @@ -129,11 +136,11 @@ pub fn push_to_remote_url( | |||
| 129 | let push_reporter = Arc::clone(&push_reporter); | 136 | let push_reporter = Arc::clone(&push_reporter); |
| 130 | move |name, error| { | 137 | move |name, error| { |
| 131 | let mut reporter = push_reporter.lock().unwrap(); | 138 | let mut reporter = push_reporter.lock().unwrap(); |
| 139 | reporter | ||
| 140 | .ref_updates | ||
| 141 | .insert(name.to_string(), error.map(|s| s.to_string())); | ||
| 132 | if let Some(error) = error { | 142 | if let Some(error) = error { |
| 133 | let existing_lines = reporter.count_all_existing_lines(); | 143 | let existing_lines = reporter.count_all_existing_lines(); |
| 134 | reporter | ||
| 135 | .failed_refs | ||
| 136 | .insert(name.to_string(), error.to_string()); | ||
| 137 | reporter.update_reference_errors.push(format!( | 144 | reporter.update_reference_errors.push(format!( |
| 138 | "WARNING: {} failed to push {name} error: {error}", | 145 | "WARNING: {} failed to push {name} error: {error}", |
| 139 | get_short_git_server_name(git_repo, git_server_url), | 146 | get_short_git_server_name(git_repo, git_server_url), |
| @@ -156,7 +163,11 @@ pub fn push_to_remote_url( | |||
| 156 | .unwrap_or("") | 163 | .unwrap_or("") |
| 157 | .replace("refs/heads/", "") | 164 | .replace("refs/heads/", "") |
| 158 | .replace("refs/tags/", "tags/"); | 165 | .replace("refs/tags/", "tags/"); |
| 159 | let msg = if update.dst().is_zero() { | 166 | let msg = if let Some(Some(_)) = |
| 167 | reporter.ref_updates.get(update.dst_refname().unwrap_or("")) | ||
| 168 | { | ||
| 169 | format!("push: - [failed] {dst_refname}") | ||
| 170 | } else if update.dst().is_zero() { | ||
| 160 | format!("push: - [delete] {dst_refname}") | 171 | format!("push: - [delete] {dst_refname}") |
| 161 | } else if update.src().is_zero() { | 172 | } else if update.src().is_zero() { |
| 162 | if update.dst_refname().unwrap_or("").contains("refs/tags") { | 173 | if update.dst_refname().unwrap_or("").contains("refs/tags") { |
| @@ -216,7 +227,7 @@ pub fn push_to_remote_url( | |||
| 216 | git_server_remote.push(remote_refspecs, Some(&mut push_options))?; | 227 | git_server_remote.push(remote_refspecs, Some(&mut push_options))?; |
| 217 | let _ = git_server_remote.disconnect(); | 228 | let _ = git_server_remote.disconnect(); |
| 218 | let reporter = push_reporter.lock().unwrap(); | 229 | let reporter = push_reporter.lock().unwrap(); |
| 219 | Ok(reporter.failed_refs.clone()) | 230 | Ok(reporter.ref_updates.clone()) |
| 220 | } | 231 | } |
| 221 | 232 | ||
| 222 | #[allow(clippy::cast_precision_loss)] | 233 | #[allow(clippy::cast_precision_loss)] |
| @@ -265,7 +276,7 @@ pub struct PushReporter<'a> { | |||
| 265 | negotiation: Vec<String>, | 276 | negotiation: Vec<String>, |
| 266 | transfer_progress_msgs: Vec<String>, | 277 | transfer_progress_msgs: Vec<String>, |
| 267 | update_reference_errors: Vec<String>, | 278 | update_reference_errors: Vec<String>, |
| 268 | failed_refs: HashMap<String, String>, | 279 | ref_updates: HashMap<String, Option<String>>, |
| 269 | term: &'a console::Term, | 280 | term: &'a console::Term, |
| 270 | start_time: Option<Instant>, | 281 | start_time: Option<Instant>, |
| 271 | end_time: Option<Instant>, | 282 | end_time: Option<Instant>, |
| @@ -277,7 +288,7 @@ impl<'a> PushReporter<'a> { | |||
| 277 | negotiation: vec![], | 288 | negotiation: vec![], |
| 278 | transfer_progress_msgs: vec![], | 289 | transfer_progress_msgs: vec![], |
| 279 | update_reference_errors: vec![], | 290 | update_reference_errors: vec![], |
| 280 | failed_refs: HashMap::new(), | 291 | ref_updates: HashMap::new(), |
| 281 | term, | 292 | term, |
| 282 | start_time: None, | 293 | start_time: None, |
| 283 | end_time: None, | 294 | end_time: None, |
| @@ -426,13 +437,21 @@ pub async fn push_refs_and_generate_pr_or_pr_update_event( | |||
| 426 | ))?; | 437 | ))?; |
| 427 | responses.push((clone_url.clone(), Err(anyhow!(error)))); | 438 | responses.push((clone_url.clone(), Err(anyhow!(error)))); |
| 428 | } | 439 | } |
| 429 | Ok(failed_refs) => { | 440 | Ok(ref_updates) => { |
| 430 | let normalized_url = normalize_grasp_server_url(clone_url)?; | 441 | let normalized_url = normalize_grasp_server_url(clone_url)?; |
| 431 | if let Some((_, error)) = failed_refs.iter().next() { | 442 | if let Some((_, Some(error))) = ref_updates.iter().next() { |
| 432 | term.write_line(&format!( | 443 | term.write_line(&format!( |
| 433 | "push: error sending commit data to {normalized_url}: {error}" | 444 | "push: error sending commit data to {normalized_url}: {error}" |
| 434 | ))?; | 445 | ))?; |
| 435 | responses.push((clone_url.clone(), Err(anyhow!(error.clone())))); | 446 | responses.push((clone_url.clone(), Err(anyhow!(error.clone())))); |
| 447 | } else if ref_updates.is_empty() { | ||
| 448 | term.write_line(&format!( | ||
| 449 | "push: error sending commit data to {normalized_url}: server didn't confirm acceptance" | ||
| 450 | ))?; | ||
| 451 | responses.push(( | ||
| 452 | clone_url.clone(), | ||
| 453 | Err(anyhow!("server didn't confirm acceptance")), | ||
| 454 | )); | ||
| 436 | } else { | 455 | } else { |
| 437 | responses.push((clone_url.clone(), Ok(()))); | 456 | responses.push((clone_url.clone(), Ok(()))); |
| 438 | term.write_line(&format!("push: commit data sent to {normalized_url}"))?; | 457 | term.write_line(&format!("push: commit data sent to {normalized_url}"))?; |