upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/bin/git_remote_nostr/push.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-09-04 12:09:06 +0100
committerDanConwayDev <DanConwayDev@protonmail.com>2025-09-04 12:09:06 +0100
commit8527646022abdb290222a45314d090eef0871cae (patch)
tree16b92960553c8da5c30e7c0059d2a82a2a366c68 /src/bin/git_remote_nostr/push.rs
parent4bd46c3cf7bacb062d45d3c99d3edfadc95cb139 (diff)
feat(remote): use push PR non-interactive fallback
move the PR push code in 'ngit send' into lib. reuse the non-interactive fallbacks in git-remote-nostr
Diffstat (limited to 'src/bin/git_remote_nostr/push.rs')
-rw-r--r--src/bin/git_remote_nostr/push.rs66
1 files changed, 23 insertions, 43 deletions
diff --git a/src/bin/git_remote_nostr/push.rs b/src/bin/git_remote_nostr/push.rs
index df895b1..8c102ee 100644
--- a/src/bin/git_remote_nostr/push.rs
+++ b/src/bin/git_remote_nostr/push.rs
@@ -19,7 +19,7 @@ use ngit::{
19 git_events::{self, KIND_PULL_REQUEST, event_to_cover_letter, get_event_root}, 19 git_events::{self, KIND_PULL_REQUEST, event_to_cover_letter, get_event_root},
20 list::list_from_remotes, 20 list::list_from_remotes,
21 login::{self, user::UserRef}, 21 login::{self, user::UserRef},
22 push::{push_refs_and_generate_pr_or_pr_update_event, push_to_remote}, 22 push::{push_to_remote, select_servers_push_refs_and_generate_pr_or_pr_update_event},
23 repo_ref::{self, get_repo_config_from_yaml, is_grasp_server_in_list}, 23 repo_ref::{self, get_repo_config_from_yaml, is_grasp_server_in_list},
24 repo_state, 24 repo_state,
25 utils::{ 25 utils::{
@@ -173,7 +173,7 @@ async fn create_and_publish_events_and_proposals(
173 existing_state: HashMap<String, String>, 173 existing_state: HashMap<String, String>,
174 term: &Term, 174 term: &Term,
175) -> Result<(Vec<String>, bool)> { 175) -> Result<(Vec<String>, bool)> {
176 let (signer, user_ref, _) = 176 let (signer, mut user_ref, _) =
177 login::login_or_signup(&Some(git_repo), &None, &None, Some(client), true).await?; 177 login::login_or_signup(&Some(git_repo), &None, &None, Some(client), true).await?;
178 178
179 if !repo_ref.maintainers.contains(&user_ref.public_key) { 179 if !repo_ref.maintainers.contains(&user_ref.public_key) {
@@ -249,10 +249,11 @@ async fn create_and_publish_events_and_proposals(
249 } 249 }
250 250
251 let (proposal_events, rejected_proposal_refspecs) = process_proposal_refspecs( 251 let (proposal_events, rejected_proposal_refspecs) = process_proposal_refspecs(
252 client,
252 git_repo, 253 git_repo,
253 repo_ref, 254 repo_ref,
254 proposal_refspecs, 255 proposal_refspecs,
255 &user_ref, 256 &mut user_ref,
256 &signer, 257 &signer,
257 term, 258 term,
258 ) 259 )
@@ -281,10 +282,11 @@ async fn create_and_publish_events_and_proposals(
281 282
282#[allow(clippy::too_many_lines)] 283#[allow(clippy::too_many_lines)]
283async fn process_proposal_refspecs( 284async fn process_proposal_refspecs(
285 client: &Client,
284 git_repo: &Repo, 286 git_repo: &Repo,
285 repo_ref: &RepoRef, 287 repo_ref: &RepoRef,
286 proposal_refspecs: &Vec<String>, 288 proposal_refspecs: &Vec<String>,
287 user_ref: &UserRef, 289 user_ref: &mut UserRef,
288 signer: &Arc<dyn NostrSigner>, 290 signer: &Arc<dyn NostrSigner>,
289 term: &Term, 291 term: &Term,
290) -> Result<(Vec<Event>, Vec<String>)> { 292) -> Result<(Vec<Event>, Vec<String>)> {
@@ -294,7 +296,7 @@ async fn process_proposal_refspecs(
294 return Ok((events, rejected_proposal_refspecs)); 296 return Ok((events, rejected_proposal_refspecs));
295 } 297 }
296 let all_proposals = get_all_proposals(git_repo, repo_ref).await?; 298 let all_proposals = get_all_proposals(git_repo, repo_ref).await?;
297 let current_user = &user_ref.public_key; 299 let current_user = user_ref.public_key;
298 300
299 for refspec in proposal_refspecs { 301 for refspec in proposal_refspecs {
300 let (from, to) = refspec_to_from_to(refspec).unwrap(); 302 let (from, to) = refspec_to_from_to(refspec).unwrap();
@@ -302,7 +304,7 @@ async fn process_proposal_refspecs(
302 304
303 // this failed to find existing PR from user 305 // this failed to find existing PR from user
304 if let Some((_, (proposal, patches))) = 306 if let Some((_, (proposal, patches))) =
305 find_proposal_and_patches_by_branch_name(to, &all_proposals, Some(current_user)) 307 find_proposal_and_patches_by_branch_name(to, &all_proposals, Some(&current_user))
306 { 308 {
307 if [repo_ref.maintainers.clone(), vec![proposal.pubkey]] 309 if [repo_ref.maintainers.clone(), vec![proposal.pubkey]]
308 .concat() 310 .concat()
@@ -320,6 +322,7 @@ async fn process_proposal_refspecs(
320 ); 322 );
321 } 323 }
322 for patch in generate_patches_or_pr_event_or_pr_updates( 324 for patch in generate_patches_or_pr_event_or_pr_updates(
325 client,
323 git_repo, 326 git_repo,
324 repo_ref, 327 repo_ref,
325 &ahead, 328 &ahead,
@@ -359,6 +362,7 @@ async fn process_proposal_refspecs(
359 || git_repo.are_commits_too_big_for_patches(&ahead) 362 || git_repo.are_commits_too_big_for_patches(&ahead)
360 { 363 {
361 for event in generate_patches_or_pr_event_or_pr_updates( 364 for event in generate_patches_or_pr_event_or_pr_updates(
365 client,
362 git_repo, 366 git_repo,
363 repo_ref, 367 repo_ref,
364 &ahead, 368 &ahead,
@@ -428,7 +432,7 @@ async fn process_proposal_refspecs(
428 ); 432 );
429 } 433 }
430 for event in generate_patches_or_pr_event_or_pr_updates( 434 for event in generate_patches_or_pr_event_or_pr_updates(
431 git_repo, repo_ref, &ahead, user_ref, None, signer, term, 435 client, git_repo, repo_ref, &ahead, user_ref, None, signer, term,
432 ) 436 )
433 .await? 437 .await?
434 { 438 {
@@ -441,11 +445,13 @@ async fn process_proposal_refspecs(
441} 445}
442 446
443#[allow(clippy::too_many_lines)] 447#[allow(clippy::too_many_lines)]
448#[allow(clippy::too_many_arguments)]
444async fn generate_patches_or_pr_event_or_pr_updates( 449async fn generate_patches_or_pr_event_or_pr_updates(
450 client: &Client,
445 git_repo: &Repo, 451 git_repo: &Repo,
446 repo_ref: &RepoRef, 452 repo_ref: &RepoRef,
447 ahead: &[Sha1Hash], 453 ahead: &[Sha1Hash],
448 user_ref: &UserRef, 454 user_ref: &mut UserRef,
449 root_proposal: Option<&Event>, 455 root_proposal: Option<&Event>,
450 signer: &Arc<dyn NostrSigner>, 456 signer: &Arc<dyn NostrSigner>,
451 term: &Term, 457 term: &Term,
@@ -454,53 +460,27 @@ async fn generate_patches_or_pr_event_or_pr_updates(
454 let use_pr = parent_is_pr || git_repo.are_commits_too_big_for_patches(ahead); 460 let use_pr = parent_is_pr || git_repo.are_commits_too_big_for_patches(ahead);
455 461
456 if use_pr { 462 if use_pr {
457 let repo_grasps = repo_ref.grasp_servers(); 463 select_servers_push_refs_and_generate_pr_or_pr_update_event(
458 let repo_grasp_clone_urls: Vec<String> = repo_ref 464 client,
459 .git_server
460 .iter()
461 .filter(|s| is_grasp_server_in_list(s, &repo_grasps))
462 .cloned()
463 .collect();
464
465 if repo_grasp_clone_urls.is_empty() {
466 // TODO get grasp_default_set servers that aren't in repo_grasps
467 // cycle through until one succeeds TODO create
468 // personal-fork announcement with grasp servers and
469 // push, after a few seconds push ref/nostr/eventid. if
470 // one success break out of for loop and continue
471
472 bail!(
473 "The repository doesnt list a grasp server which would otherwise be used to submit your proposal as nostr Pull Request. Soon ngit will support pushing your changes to a different git / grasp git server."
474 );
475 }
476
477 if let (Some(events), _) = push_refs_and_generate_pr_or_pr_update_event(
478 git_repo, 465 git_repo,
479 repo_ref, 466 repo_ref,
480 ahead.first().context("no commits to push")?, 467 ahead.first().context("no commits to push")?,
481 user_ref, 468 user_ref,
482 root_proposal, 469 root_proposal,
483 &None, 470 &None,
484 &repo_grasp_clone_urls,
485 None,
486 signer, 471 signer,
472 false,
487 term, 473 term,
488 ) 474 )
489 .await.context( 475 .await
476 .context(format!(
477 "{} run `ngit send` for more options.",
490 if parent_is_pr { 478 if parent_is_pr {
491 "couldn't generate PR update event" 479 "couldn't generate PR update event."
492 } else { 480 } else {
493 "a commit in your proposal is too big for a nostr patch so we tried to create it as a nostr PR instead. Unfortunately this failed." 481 "a commit in your proposal is too big for a nostr patch so we tried to create it as a nostr PR instead. Unfortunately this failed."
494 } 482 },
495 )? { 483 ))
496 Ok(events)
497 } else {
498 bail!(
499 "a commit in your proposal is too big for a nostr patch. tried to use submit as a nostr Pull Request but could not find a grasp server that would accept your changes"
500 );
501 // TODO suggest `ngit send` where user could specify their own clone
502 // url to push to once that feature is added
503 }
504 } else { 484 } else {
505 generate_cover_letter_and_patch_events( 485 generate_cover_letter_and_patch_events(
506 None, 486 None,