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/bin/git_remote_nostr/list.rs4
-rw-r--r--src/bin/git_remote_nostr/push.rs6
-rw-r--r--src/bin/git_remote_nostr/utils.rs4
-rw-r--r--src/bin/ngit/sub_commands/list.rs53
-rw-r--r--src/lib/git_events.rs61
5 files changed, 71 insertions, 57 deletions
diff --git a/src/bin/git_remote_nostr/list.rs b/src/bin/git_remote_nostr/list.rs
index 07c6f59..f361272 100644
--- a/src/bin/git_remote_nostr/list.rs
+++ b/src/bin/git_remote_nostr/list.rs
@@ -149,10 +149,10 @@ async fn get_open_proposals_state(
149 let current_user = get_curent_user(git_repo)?; 149 let current_user = get_curent_user(git_repo)?;
150 for (_, (proposal, patches)) in open_proposals { 150 for (_, (proposal, patches)) in open_proposals {
151 if let Ok(cl) = event_to_cover_letter(&proposal) { 151 if let Ok(cl) = event_to_cover_letter(&proposal) {
152 if let Ok(mut branch_name) = cl.get_branch_name() { 152 if let Ok(mut branch_name) = cl.get_branch_name_with_pr_prefix_and_shorthand_id() {
153 branch_name = if let Some(public_key) = current_user { 153 branch_name = if let Some(public_key) = current_user {
154 if proposal.pubkey.eq(&public_key) { 154 if proposal.pubkey.eq(&public_key) {
155 format!("pr/{}", cl.branch_name) 155 format!("pr/{}", cl.branch_name_without_id_or_prefix)
156 } else { 156 } else {
157 branch_name 157 branch_name
158 } 158 }
diff --git a/src/bin/git_remote_nostr/push.rs b/src/bin/git_remote_nostr/push.rs
index 05c8fc2..922808c 100644
--- a/src/bin/git_remote_nostr/push.rs
+++ b/src/bin/git_remote_nostr/push.rs
@@ -1184,7 +1184,8 @@ async fn create_merge_events(
1184 term.write_line( 1184 term.write_line(
1185 format!( 1185 format!(
1186 "applied commits from proposal: create nostr proposal status event for {}", 1186 "applied commits from proposal: create nostr proposal status event for {}",
1187 event_to_cover_letter(&proposal)?.get_branch_name()?, 1187 event_to_cover_letter(&proposal)?
1188 .get_branch_name_with_pr_prefix_and_shorthand_id()?,
1188 ) 1189 )
1189 .as_str(), 1190 .as_str(),
1190 )?; 1191 )?;
@@ -1192,7 +1193,8 @@ async fn create_merge_events(
1192 term.write_line( 1193 term.write_line(
1193 format!( 1194 format!(
1194 "fast-forward merge: create nostr proposal status event for {}", 1195 "fast-forward merge: create nostr proposal status event for {}",
1195 event_to_cover_letter(&proposal)?.get_branch_name()?, 1196 event_to_cover_letter(&proposal)?
1197 .get_branch_name_with_pr_prefix_and_shorthand_id()?,
1196 ) 1198 )
1197 .as_str(), 1199 .as_str(),
1198 )?; 1200 )?;
diff --git a/src/bin/git_remote_nostr/utils.rs b/src/bin/git_remote_nostr/utils.rs
index 15ebb10..316fedb 100644
--- a/src/bin/git_remote_nostr/utils.rs
+++ b/src/bin/git_remote_nostr/utils.rs
@@ -184,10 +184,10 @@ pub async fn get_all_proposals(
184 184
185pub fn find_proposal_and_patches_by_branch_name<'a>( 185pub fn find_proposal_and_patches_by_branch_name<'a>(
186 refstr: &'a str, 186 refstr: &'a str,
187 open_proposals: &'a HashMap<EventId, (Event, Vec<Event>)>, 187 proposals: &'a HashMap<EventId, (Event, Vec<Event>)>,
188 current_user: Option<&PublicKey>, 188 current_user: Option<&PublicKey>,
189) -> Option<(&'a EventId, &'a (Event, Vec<Event>))> { 189) -> Option<(&'a EventId, &'a (Event, Vec<Event>))> {
190 open_proposals.iter().find(|(_, (proposal, _))| { 190 proposals.iter().find(|(_, (proposal, _))| {
191 is_event_proposal_root_for_branch(proposal, refstr, current_user).unwrap_or(false) 191 is_event_proposal_root_for_branch(proposal, refstr, current_user).unwrap_or(false)
192 }) 192 })
193} 193}
diff --git a/src/bin/ngit/sub_commands/list.rs b/src/bin/ngit/sub_commands/list.rs
index 9b84c1b..e8d2e97 100644
--- a/src/bin/ngit/sub_commands/list.rs
+++ b/src/bin/ngit/sub_commands/list.rs
@@ -261,11 +261,15 @@ pub async fn launch() -> Result<()> {
261 .get_local_branch_names() 261 .get_local_branch_names()
262 .context("gitlib2 will not show a list of local branch names")? 262 .context("gitlib2 will not show a list of local branch names")?
263 .iter() 263 .iter()
264 .any(|n| n.eq(&cover_letter.get_branch_name().unwrap())); 264 .any(|n| {
265 n.eq(&cover_letter
266 .get_branch_name_with_pr_prefix_and_shorthand_id()
267 .unwrap())
268 });
265 269
266 let checked_out_proposal_branch = git_repo 270 let checked_out_proposal_branch = git_repo
267 .get_checked_out_branch_name()? 271 .get_checked_out_branch_name()?
268 .eq(&cover_letter.get_branch_name()?); 272 .eq(&cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?);
269 273
270 let proposal_base_commit = str_to_sha1(&tag_value( 274 let proposal_base_commit = str_to_sha1(&tag_value(
271 most_recent_proposal_patch_chain.last().context( 275 most_recent_proposal_patch_chain.last().context(
@@ -327,14 +331,14 @@ pub async fn launch() -> Result<()> {
327 check_clean(&git_repo)?; 331 check_clean(&git_repo)?;
328 let _ = git_repo 332 let _ = git_repo
329 .apply_patch_chain( 333 .apply_patch_chain(
330 &cover_letter.get_branch_name()?, 334 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
331 most_recent_proposal_patch_chain, 335 most_recent_proposal_patch_chain,
332 ) 336 )
333 .context("failed to apply patch chain")?; 337 .context("failed to apply patch chain")?;
334 338
335 println!( 339 println!(
336 "checked out proposal as '{}' branch", 340 "checked out proposal as '{}' branch",
337 cover_letter.get_branch_name()? 341 cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?
338 ); 342 );
339 Ok(()) 343 Ok(())
340 } 344 }
@@ -347,7 +351,8 @@ pub async fn launch() -> Result<()> {
347 }; 351 };
348 } 352 }
349 353
350 let local_branch_tip = git_repo.get_tip_of_branch(&cover_letter.get_branch_name()?)?; 354 let local_branch_tip = git_repo
355 .get_tip_of_branch(&cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?)?;
351 356
352 // up-to-date 357 // up-to-date
353 if proposal_tip.eq(&local_branch_tip) { 358 if proposal_tip.eq(&local_branch_tip) {
@@ -382,10 +387,12 @@ pub async fn launch() -> Result<()> {
382 )? { 387 )? {
383 0 => { 388 0 => {
384 check_clean(&git_repo)?; 389 check_clean(&git_repo)?;
385 git_repo.checkout(&cover_letter.get_branch_name()?)?; 390 git_repo.checkout(
391 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
392 )?;
386 println!( 393 println!(
387 "checked out proposal as '{}' branch", 394 "checked out proposal as '{}' branch",
388 cover_letter.get_branch_name()? 395 cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?
389 ); 396 );
390 Ok(()) 397 Ok(())
391 } 398 }
@@ -419,10 +426,12 @@ pub async fn launch() -> Result<()> {
419 )? { 426 )? {
420 0 => { 427 0 => {
421 check_clean(&git_repo)?; 428 check_clean(&git_repo)?;
422 git_repo.checkout(&cover_letter.get_branch_name()?)?; 429 git_repo.checkout(
430 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
431 )?;
423 let _ = git_repo 432 let _ = git_repo
424 .apply_patch_chain( 433 .apply_patch_chain(
425 &cover_letter.get_branch_name()?, 434 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
426 most_recent_proposal_patch_chain, 435 most_recent_proposal_patch_chain,
427 ) 436 )
428 .context("failed to apply patch chain")?; 437 .context("failed to apply patch chain")?;
@@ -472,14 +481,16 @@ pub async fn launch() -> Result<()> {
472 0 => { 481 0 => {
473 check_clean(&git_repo)?; 482 check_clean(&git_repo)?;
474 git_repo.create_branch_at_commit( 483 git_repo.create_branch_at_commit(
475 &cover_letter.get_branch_name()?, 484 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
476 &proposal_base_commit.to_string(), 485 &proposal_base_commit.to_string(),
477 )?; 486 )?;
478 git_repo.checkout(&cover_letter.get_branch_name()?)?; 487 git_repo.checkout(
488 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
489 )?;
479 let chain_length = most_recent_proposal_patch_chain.len(); 490 let chain_length = most_recent_proposal_patch_chain.len();
480 let _ = git_repo 491 let _ = git_repo
481 .apply_patch_chain( 492 .apply_patch_chain(
482 &cover_letter.get_branch_name()?, 493 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
483 most_recent_proposal_patch_chain, 494 most_recent_proposal_patch_chain,
484 ) 495 )
485 .context("failed to apply patch chain")?; 496 .context("failed to apply patch chain")?;
@@ -494,7 +505,9 @@ pub async fn launch() -> Result<()> {
494 } 505 }
495 1 => { 506 1 => {
496 check_clean(&git_repo)?; 507 check_clean(&git_repo)?;
497 git_repo.checkout(&cover_letter.get_branch_name()?)?; 508 git_repo.checkout(
509 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
510 )?;
498 println!( 511 println!(
499 "checked out old proposal in existing branch ({} ahead {} behind '{main_branch_name}')", 512 "checked out old proposal in existing branch ({} ahead {} behind '{main_branch_name}')",
500 local_ahead_of_main.len(), 513 local_ahead_of_main.len(),
@@ -537,7 +550,9 @@ pub async fn launch() -> Result<()> {
537 ]), 550 ]),
538 )? { 551 )? {
539 0 => { 552 0 => {
540 git_repo.checkout(&cover_letter.get_branch_name()?)?; 553 git_repo.checkout(
554 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
555 )?;
541 println!( 556 println!(
542 "checked out proposal branch with {} unpublished commits ({} ahead {} behind '{main_branch_name}')", 557 "checked out proposal branch with {} unpublished commits ({} ahead {} behind '{main_branch_name}')",
543 local_ahead_of_proposal.len(), 558 local_ahead_of_proposal.len(),
@@ -604,7 +619,8 @@ pub async fn launch() -> Result<()> {
604 )? { 619 )? {
605 0 => { 620 0 => {
606 check_clean(&git_repo)?; 621 check_clean(&git_repo)?;
607 git_repo.checkout(&cover_letter.get_branch_name()?)?; 622 git_repo
623 .checkout(&cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?)?;
608 println!( 624 println!(
609 "checked out old proposal in existing branch ({} ahead {} behind '{main_branch_name}')", 625 "checked out old proposal in existing branch ({} ahead {} behind '{main_branch_name}')",
610 local_ahead_of_main.len(), 626 local_ahead_of_main.len(),
@@ -615,18 +631,19 @@ pub async fn launch() -> Result<()> {
615 1 => { 631 1 => {
616 check_clean(&git_repo)?; 632 check_clean(&git_repo)?;
617 git_repo.create_branch_at_commit( 633 git_repo.create_branch_at_commit(
618 &cover_letter.get_branch_name()?, 634 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
619 &proposal_base_commit.to_string(), 635 &proposal_base_commit.to_string(),
620 )?; 636 )?;
621 let chain_length = most_recent_proposal_patch_chain.len(); 637 let chain_length = most_recent_proposal_patch_chain.len();
622 let _ = git_repo 638 let _ = git_repo
623 .apply_patch_chain( 639 .apply_patch_chain(
624 &cover_letter.get_branch_name()?, 640 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
625 most_recent_proposal_patch_chain, 641 most_recent_proposal_patch_chain,
626 ) 642 )
627 .context("failed to apply patch chain")?; 643 .context("failed to apply patch chain")?;
628 644
629 git_repo.checkout(&cover_letter.get_branch_name()?)?; 645 git_repo
646 .checkout(&cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?)?;
630 println!( 647 println!(
631 "checked out latest version of proposal ({} ahead {} behind '{main_branch_name}'), replacing unpublished version ({} ahead {} behind '{main_branch_name}')", 648 "checked out latest version of proposal ({} ahead {} behind '{main_branch_name}'), replacing unpublished version ({} ahead {} behind '{main_branch_name}')",
632 chain_length, 649 chain_length,
diff --git a/src/lib/git_events.rs b/src/lib/git_events.rs
index af469d3..559155a 100644
--- a/src/lib/git_events.rs
+++ b/src/lib/git_events.rs
@@ -453,15 +453,15 @@ pub async fn generate_cover_letter_and_patch_events(
453pub struct CoverLetter { 453pub struct CoverLetter {
454 pub title: String, 454 pub title: String,
455 pub description: String, 455 pub description: String,
456 pub branch_name: String, 456 pub branch_name_without_id_or_prefix: String,
457 pub event_id: Option<nostr::EventId>, 457 pub event_id: Option<nostr::EventId>,
458} 458}
459 459
460impl CoverLetter { 460impl CoverLetter {
461 pub fn get_branch_name(&self) -> Result<String> { 461 pub fn get_branch_name_with_pr_prefix_and_shorthand_id(&self) -> Result<String> {
462 Ok(format!( 462 Ok(format!(
463 "pr/{}({})", 463 "pr/{}({})",
464 self.branch_name, 464 self.branch_name_without_id_or_prefix,
465 &self 465 &self
466 .event_id 466 .event_id
467 .context("proposal root event_id must be know to get it's branch name")? 467 .context("proposal root event_id must be know to get it's branch name")?
@@ -520,39 +520,33 @@ pub fn event_to_cover_letter(event: &nostr::Event) -> Result<CoverLetter> {
520 Ok(CoverLetter { 520 Ok(CoverLetter {
521 title: title.clone(), 521 title: title.clone(),
522 description, 522 description,
523 // TODO should this be prefixed by format!("{}-"e.id.to_string()[..5]?) 523 branch_name_without_id_or_prefix: if let Ok(name) = tag_value(event, "branch-name") {
524 branch_name: if let Ok(name) = match tag_value(event, "branch-name") { 524 if !name.eq("main") && !name.eq("master") {
525 Ok(name) => { 525 safe_branch_name_for_pr(&name)
526 if !name.eq("main") && !name.eq("master") { 526 } else {
527 Ok(name.chars().take(60).collect::<String>()) 527 safe_branch_name_for_pr(&title)
528 } else {
529 Err(())
530 }
531 } 528 }
532 _ => Err(()),
533 } {
534 name
535 } else { 529 } else {
536 let s = title 530 safe_branch_name_for_pr(&title)
537 .replace(' ', "-") 531 },
538 .chars()
539 .map(|c| {
540 if c.is_ascii_alphanumeric() || c.eq(&'/') {
541 c
542 } else {
543 '-'
544 }
545 })
546 .collect();
547 s
548 }
549 .chars()
550 .take(60)
551 .collect(),
552 event_id: Some(event.id), 532 event_id: Some(event.id),
553 }) 533 })
554} 534}
555 535
536fn safe_branch_name_for_pr(s: &str) -> String {
537 s.replace(' ', "-")
538 .chars()
539 .map(|c| {
540 if c.is_ascii_alphanumeric() || c.eq(&'/') {
541 c
542 } else {
543 '-'
544 }
545 })
546 .take(60)
547 .collect()
548}
549
556pub fn get_most_recent_patch_with_ancestors( 550pub fn get_most_recent_patch_with_ancestors(
557 mut patches: Vec<nostr::Event>, 551 mut patches: Vec<nostr::Event>,
558) -> Result<Vec<nostr::Event>> { 552) -> Result<Vec<nostr::Event>> {
@@ -622,9 +616,10 @@ pub fn is_event_proposal_root_for_branch(
622 let branch_name = branch_name_or_refstr.replace("refs/heads/", ""); 616 let branch_name = branch_name_or_refstr.replace("refs/heads/", "");
623 Ok(event_to_cover_letter(e).is_ok_and(|cl| { 617 Ok(event_to_cover_letter(e).is_ok_and(|cl| {
624 (logged_in_user.is_some_and(|public_key| e.pubkey.eq(public_key)) 618 (logged_in_user.is_some_and(|public_key| e.pubkey.eq(public_key))
625 && (branch_name.eq(&format!("pr/{}", cl.branch_name)) 619 && branch_name.eq(&format!("pr/{}", cl.branch_name_without_id_or_prefix)))
626 || cl.branch_name.eq(&branch_name))) 620 || cl
627 || cl.get_branch_name().is_ok_and(|s| s.eq(&branch_name)) 621 .get_branch_name_with_pr_prefix_and_shorthand_id()
622 .is_ok_and(|s| s.eq(&branch_name))
628 }) && !event_is_revision_root(e)) 623 }) && !event_is_revision_root(e))
629} 624}
630 625