diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/git_remote_helper.rs | 90 |
1 files changed, 64 insertions, 26 deletions
diff --git a/src/git_remote_helper.rs b/src/git_remote_helper.rs index be230b1..ff053f6 100644 --- a/src/git_remote_helper.rs +++ b/src/git_remote_helper.rs | |||
| @@ -287,10 +287,19 @@ async fn list( | |||
| 287 | state.retain(|k, _| !k.starts_with("refs/heads/prs/")); | 287 | state.retain(|k, _| !k.starts_with("refs/heads/prs/")); |
| 288 | 288 | ||
| 289 | let open_proposals = get_open_proposals(git_repo, repo_ref).await?; | 289 | let open_proposals = get_open_proposals(git_repo, repo_ref).await?; |
| 290 | 290 | let current_user = get_curent_user(git_repo)?; | |
| 291 | for (_, (proposal, patches)) in open_proposals { | 291 | for (_, (proposal, patches)) in open_proposals { |
| 292 | if let Ok(cl) = event_to_cover_letter(&proposal) { | 292 | if let Ok(cl) = event_to_cover_letter(&proposal) { |
| 293 | if let Ok(branch_name) = cl.get_branch_name() { | 293 | if let Ok(mut branch_name) = cl.get_branch_name() { |
| 294 | branch_name = if let Some(public_key) = current_user { | ||
| 295 | if proposal.author().eq(&public_key) { | ||
| 296 | cl.branch_name.to_string() | ||
| 297 | } else { | ||
| 298 | branch_name | ||
| 299 | } | ||
| 300 | } else { | ||
| 301 | branch_name | ||
| 302 | }; | ||
| 294 | if let Some(patch) = patches.first() { | 303 | if let Some(patch) = patches.first() { |
| 295 | // TODO this isn't resilient because the commit id stated may not be correct | 304 | // TODO this isn't resilient because the commit id stated may not be correct |
| 296 | // we will need to check whether the commit id exists in the repo or apply the | 305 | // we will need to check whether the commit id exists in the repo or apply the |
| @@ -435,6 +444,20 @@ async fn get_open_proposals( | |||
| 435 | Ok(open_proposals) | 444 | Ok(open_proposals) |
| 436 | } | 445 | } |
| 437 | 446 | ||
| 447 | fn get_curent_user(git_repo: &Repo) -> Result<Option<PublicKey>> { | ||
| 448 | Ok( | ||
| 449 | if let Some(npub) = git_repo.get_git_config_item("nostr.npub", None)? { | ||
| 450 | if let Ok(public_key) = PublicKey::parse(npub) { | ||
| 451 | Some(public_key) | ||
| 452 | } else { | ||
| 453 | None | ||
| 454 | } | ||
| 455 | } else { | ||
| 456 | None | ||
| 457 | }, | ||
| 458 | ) | ||
| 459 | } | ||
| 460 | |||
| 438 | async fn fetch( | 461 | async fn fetch( |
| 439 | git_repo: &Repo, | 462 | git_repo: &Repo, |
| 440 | repo_ref: &RepoRef, | 463 | repo_ref: &RepoRef, |
| @@ -487,32 +510,36 @@ async fn fetch( | |||
| 487 | ); | 510 | ); |
| 488 | } | 511 | } |
| 489 | 512 | ||
| 490 | let open_proposals = get_open_proposals(git_repo, repo_ref).await?; | ||
| 491 | |||
| 492 | fetch_batch.retain(|refstr, _| refstr.contains("refs/heads/prs/")); | 513 | fetch_batch.retain(|refstr, _| refstr.contains("refs/heads/prs/")); |
| 493 | 514 | ||
| 494 | for (refstr, oid) in fetch_batch { | 515 | if !fetch_batch.is_empty() { |
| 495 | if let Some((_, (_, patches))) = | 516 | let open_proposals = get_open_proposals(git_repo, repo_ref).await?; |
| 496 | find_proposal_and_patches_by_branch_name(&refstr, &open_proposals) | 517 | |
| 497 | { | 518 | let current_user = get_curent_user(git_repo)?; |
| 498 | if !git_repo.does_commit_exist(&oid)? { | 519 | |
| 499 | let mut patches_ancestor_first = patches.clone(); | 520 | for (refstr, oid) in fetch_batch { |
| 500 | patches_ancestor_first.reverse(); | 521 | if let Some((_, (_, patches))) = |
| 501 | if git_repo.does_commit_exist(&tag_value( | 522 | find_proposal_and_patches_by_branch_name(&refstr, &open_proposals, ¤t_user) |
| 502 | patches_ancestor_first.first().unwrap(), | 523 | { |
| 503 | "parent-commit", | 524 | if !git_repo.does_commit_exist(&oid)? { |
| 504 | )?)? { | 525 | let mut patches_ancestor_first = patches.clone(); |
| 505 | for patch in &patches_ancestor_first { | 526 | patches_ancestor_first.reverse(); |
| 506 | git_repo.create_commit_from_patch(patch)?; | 527 | if git_repo.does_commit_exist(&tag_value( |
| 528 | patches_ancestor_first.first().unwrap(), | ||
| 529 | "parent-commit", | ||
| 530 | )?)? { | ||
| 531 | for patch in &patches_ancestor_first { | ||
| 532 | git_repo.create_commit_from_patch(patch)?; | ||
| 533 | } | ||
| 534 | } else { | ||
| 535 | term.write_line( | ||
| 536 | format!("WARNING: cannot find parent commit for {refstr}").as_str(), | ||
| 537 | )?; | ||
| 507 | } | 538 | } |
| 508 | } else { | ||
| 509 | term.write_line( | ||
| 510 | format!("WARNING: cannot find parent commit for {refstr}").as_str(), | ||
| 511 | )?; | ||
| 512 | } | 539 | } |
| 540 | } else { | ||
| 541 | term.write_line(format!("WARNING: cannot find proposal for {refstr}").as_str())?; | ||
| 513 | } | 542 | } |
| 514 | } else { | ||
| 515 | term.write_line(format!("WARNING: cannot find proposal for {refstr}").as_str())?; | ||
| 516 | } | 543 | } |
| 517 | } | 544 | } |
| 518 | 545 | ||
| @@ -524,10 +551,20 @@ async fn fetch( | |||
| 524 | fn find_proposal_and_patches_by_branch_name<'a>( | 551 | fn find_proposal_and_patches_by_branch_name<'a>( |
| 525 | refstr: &'a str, | 552 | refstr: &'a str, |
| 526 | open_proposals: &'a HashMap<EventId, (Event, Vec<Event>)>, | 553 | open_proposals: &'a HashMap<EventId, (Event, Vec<Event>)>, |
| 554 | current_user: &Option<PublicKey>, | ||
| 527 | ) -> Option<(&'a EventId, &'a (Event, Vec<Event>))> { | 555 | ) -> Option<(&'a EventId, &'a (Event, Vec<Event>))> { |
| 528 | open_proposals.iter().find(|(_, (proposal, _))| { | 556 | open_proposals.iter().find(|(_, (proposal, _))| { |
| 529 | if let Ok(cl) = event_to_cover_letter(proposal) { | 557 | if let Ok(cl) = event_to_cover_letter(proposal) { |
| 530 | if let Ok(branch_name) = cl.get_branch_name() { | 558 | if let Ok(mut branch_name) = cl.get_branch_name() { |
| 559 | branch_name = if let Some(public_key) = current_user { | ||
| 560 | if proposal.author().eq(public_key) { | ||
| 561 | cl.branch_name.to_string() | ||
| 562 | } else { | ||
| 563 | branch_name | ||
| 564 | } | ||
| 565 | } else { | ||
| 566 | branch_name | ||
| 567 | }; | ||
| 531 | branch_name.eq(&refstr.replace("refs/heads/", "")) | 568 | branch_name.eq(&refstr.replace("refs/heads/", "")) |
| 532 | } else { | 569 | } else { |
| 533 | false | 570 | false |
| @@ -652,18 +689,19 @@ async fn push( | |||
| 652 | let mut rejected_proposal_refspecs = vec![]; | 689 | let mut rejected_proposal_refspecs = vec![]; |
| 653 | if !proposal_refspecs.is_empty() { | 690 | if !proposal_refspecs.is_empty() { |
| 654 | let open_proposals = get_open_proposals(git_repo, repo_ref).await?; | 691 | let open_proposals = get_open_proposals(git_repo, repo_ref).await?; |
| 692 | let current_user = get_curent_user(git_repo)?; | ||
| 655 | 693 | ||
| 656 | for refspec in &proposal_refspecs { | 694 | for refspec in &proposal_refspecs { |
| 657 | let (from, to) = refspec_to_from_to(refspec).unwrap(); | 695 | let (from, to) = refspec_to_from_to(refspec).unwrap(); |
| 696 | let tip_of_pushed_branch = git_repo.get_commit_or_tip_of_reference(from)?; | ||
| 658 | 697 | ||
| 659 | if let Some((_, (proposal, patches))) = | 698 | if let Some((_, (proposal, patches))) = |
| 660 | find_proposal_and_patches_by_branch_name(to, &open_proposals) | 699 | find_proposal_and_patches_by_branch_name(to, &open_proposals, ¤t_user) |
| 661 | { | 700 | { |
| 662 | if [repo_ref.maintainers.clone(), vec![proposal.author()]] | 701 | if [repo_ref.maintainers.clone(), vec![proposal.author()]] |
| 663 | .concat() | 702 | .concat() |
| 664 | .contains(&user_ref.public_key) | 703 | .contains(&user_ref.public_key) |
| 665 | { | 704 | { |
| 666 | let tip_of_pushed_branch = git_repo.get_commit_or_tip_of_reference(from)?; | ||
| 667 | if refspec.starts_with('+') { | 705 | if refspec.starts_with('+') { |
| 668 | // force push | 706 | // force push |
| 669 | let (_, main_tip) = git_repo.get_main_or_master_branch()?; | 707 | let (_, main_tip) = git_repo.get_main_or_master_branch()?; |