diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2025-09-04 12:09:06 +0100 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2025-09-04 12:09:06 +0100 |
| commit | 8527646022abdb290222a45314d090eef0871cae (patch) | |
| tree | 16b92960553c8da5c30e7c0059d2a82a2a366c68 /src/bin/git_remote_nostr | |
| parent | 4bd46c3cf7bacb062d45d3c99d3edfadc95cb139 (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')
| -rw-r--r-- | src/bin/git_remote_nostr/push.rs | 66 |
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)] |
| 283 | async fn process_proposal_refspecs( | 284 | async 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(¤t_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)] | ||
| 444 | async fn generate_patches_or_pr_event_or_pr_updates( | 449 | async 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, |