upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/bin/ngit
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/ngit')
-rw-r--r--src/bin/ngit/sub_commands/list.rs157
1 files changed, 107 insertions, 50 deletions
diff --git a/src/bin/ngit/sub_commands/list.rs b/src/bin/ngit/sub_commands/list.rs
index 0330be1..a90b28e 100644
--- a/src/bin/ngit/sub_commands/list.rs
+++ b/src/bin/ngit/sub_commands/list.rs
@@ -3,10 +3,12 @@ use std::{io::Write, ops::Add};
3use anyhow::{Context, Result, bail}; 3use anyhow::{Context, Result, bail};
4use ngit::{ 4use ngit::{
5 client::{ 5 client::{
6 Params, get_all_proposal_patch_events_from_cache, get_proposals_and_revisions_from_cache, 6 Params, get_all_proposal_patch_pr_pr_update_events_from_cache,
7 get_proposals_and_revisions_from_cache,
7 }, 8 },
8 git_events::{ 9 git_events::{
9 get_commit_id_from_patch, get_most_recent_patch_with_ancestors, status_kinds, tag_value, 10 KIND_PULL_REQUEST, KIND_PULL_REQUEST_UPDATE, get_commit_id_from_patch,
11 get_pr_tip_event_or_most_recent_patch_with_ancestors, status_kinds, tag_value,
10 }, 12 },
11}; 13};
12use nostr_sdk::Kind; 14use nostr_sdk::Kind;
@@ -184,21 +186,22 @@ pub async fn launch() -> Result<()> {
184 let cover_letter = event_to_cover_letter(proposals_for_status[selected_index]) 186 let cover_letter = event_to_cover_letter(proposals_for_status[selected_index])
185 .context("failed to extract proposal details from proposal root event")?; 187 .context("failed to extract proposal details from proposal root event")?;
186 188
187 let commits_events: Vec<nostr::Event> = get_all_proposal_patch_events_from_cache( 189 let commits_events: Vec<nostr::Event> =
188 git_repo_path, 190 get_all_proposal_patch_pr_pr_update_events_from_cache(
189 &repo_ref, 191 git_repo_path,
190 &proposals_for_status[selected_index].id, 192 &repo_ref,
191 ) 193 &proposals_for_status[selected_index].id,
192 .await?; 194 )
195 .await?;
193 196
194 let Ok(most_recent_proposal_patch_chain) = 197 let Ok(most_recent_proposal_patch_chain_or_pr_or_pr_update) =
195 get_most_recent_patch_with_ancestors(commits_events.clone()) 198 get_pr_tip_event_or_most_recent_patch_with_ancestors(commits_events.clone())
196 else { 199 else {
197 if Interactor::default().confirm( 200 if Interactor::default().confirm(
198 PromptConfirmParms::default() 201 PromptConfirmParms::default()
199 .with_default(true) 202 .with_default(true)
200 .with_prompt( 203 .with_prompt(
201 "failed to find any patches on this proposal. choose another proposal?", 204 "failed to find any PR or patch events on this proposal. choose another proposal?",
202 ), 205 ),
203 )? { 206 )? {
204 continue; 207 continue;
@@ -208,15 +211,37 @@ pub async fn launch() -> Result<()> {
208 // for commit in &most_recent_proposal_patch_chain { 211 // for commit in &most_recent_proposal_patch_chain {
209 // println!("recent_event: {:?}", commit.as_json()); 212 // println!("recent_event: {:?}", commit.as_json());
210 // } 213 // }
214 if most_recent_proposal_patch_chain_or_pr_or_pr_update
215 .iter()
216 .any(|e| [KIND_PULL_REQUEST, KIND_PULL_REQUEST_UPDATE].contains(&e.kind))
217 {
218 match Interactor::default().choice(
219 PromptChoiceParms::default()
220 .with_prompt("this is new PR event kind which ngit doesnt yet support")
221 .with_default(0)
222 .with_choices(vec!["back to proposals".to_string()]),
223 )? {
224 0 => continue,
225 _ => {
226 bail!("unexpected choice")
227 }
228 };
229 }
211 230
212 let binding_patch_text_ref = format!("{} commits", most_recent_proposal_patch_chain.len()); 231 let binding_patch_text_ref = format!(
213 let patch_text_ref = if most_recent_proposal_patch_chain.len().gt(&1) { 232 "{} commits",
233 most_recent_proposal_patch_chain_or_pr_or_pr_update.len()
234 );
235 let patch_text_ref = if most_recent_proposal_patch_chain_or_pr_or_pr_update
236 .len()
237 .gt(&1)
238 {
214 binding_patch_text_ref.as_str() 239 binding_patch_text_ref.as_str()
215 } else { 240 } else {
216 "1 commit" 241 "1 commit"
217 }; 242 };
218 243
219 let no_support_for_patches_as_branch = most_recent_proposal_patch_chain 244 let no_support_for_patches_as_branch = most_recent_proposal_patch_chain_or_pr_or_pr_update
220 .iter() 245 .iter()
221 .any(|event| !patch_supports_commit_ids(event)); 246 .any(|event| !patch_supports_commit_ids(event));
222 247
@@ -253,8 +278,13 @@ pub async fn launch() -> Result<()> {
253 )?; 278 )?;
254 continue; 279 continue;
255 } 280 }
256 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 281 1 => {
257 2 => save_patches_to_dir(most_recent_proposal_patch_chain, &git_repo), 282 launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update)
283 }
284 2 => save_patches_to_dir(
285 most_recent_proposal_patch_chain_or_pr_or_pr_update,
286 &git_repo,
287 ),
258 3 => continue, 288 3 => continue,
259 _ => { 289 _ => {
260 bail!("unexpected choice") 290 bail!("unexpected choice")
@@ -277,9 +307,11 @@ pub async fn launch() -> Result<()> {
277 .eq(&cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?); 307 .eq(&cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?);
278 308
279 let proposal_base_commit = str_to_sha1(&tag_value( 309 let proposal_base_commit = str_to_sha1(&tag_value(
280 most_recent_proposal_patch_chain.last().context( 310 most_recent_proposal_patch_chain_or_pr_or_pr_update
281 "there should be at least one patch as we have already checked for this", 311 .last()
282 )?, 312 .context(
313 "there should be at least one patch as we have already checked for this",
314 )?,
283 "parent-commit", 315 "parent-commit",
284 )?) 316 )?)
285 .context("failed to get valid parent commit id from patch")?; 317 .context("failed to get valid parent commit id from patch")?;
@@ -300,8 +332,8 @@ pub async fn launch() -> Result<()> {
300 ], 332 ],
301 ))? { 333 ))? {
302 0 | 3 => continue, 334 0 | 3 => continue,
303 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 335 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update),
304 2 => save_patches_to_dir(most_recent_proposal_patch_chain, &git_repo), 336 2 => save_patches_to_dir(most_recent_proposal_patch_chain_or_pr_or_pr_update, &git_repo),
305 _ => { 337 _ => {
306 bail!("unexpected choice") 338 bail!("unexpected choice")
307 } 339 }
@@ -309,9 +341,13 @@ pub async fn launch() -> Result<()> {
309 } 341 }
310 342
311 let proposal_tip = str_to_sha1( 343 let proposal_tip = str_to_sha1(
312 &get_commit_id_from_patch(most_recent_proposal_patch_chain.first().context( 344 &get_commit_id_from_patch(
313 "there should be at least one patch as we have already checked for this", 345 most_recent_proposal_patch_chain_or_pr_or_pr_update
314 )?) 346 .first()
347 .context(
348 "there should be at least one patch as we have already checked for this",
349 )?,
350 )
315 .context("failed to get valid commit_id from patch")?, 351 .context("failed to get valid commit_id from patch")?,
316 ) 352 )
317 .context("failed to get valid commit_id from patch")?; 353 .context("failed to get valid commit_id from patch")?;
@@ -325,7 +361,7 @@ pub async fn launch() -> Result<()> {
325 .choice(PromptChoiceParms::default().with_default(0).with_choices(vec![ 361 .choice(PromptChoiceParms::default().with_default(0).with_choices(vec![
326 format!( 362 format!(
327 "create and checkout proposal branch ({} ahead {} behind '{main_branch_name}')", 363 "create and checkout proposal branch ({} ahead {} behind '{main_branch_name}')",
328 most_recent_proposal_patch_chain.len(), 364 most_recent_proposal_patch_chain_or_pr_or_pr_update.len(),
329 proposal_behind_main.len(), 365 proposal_behind_main.len(),
330 ), 366 ),
331 format!("apply to current branch with `git am`"), 367 format!("apply to current branch with `git am`"),
@@ -337,7 +373,7 @@ pub async fn launch() -> Result<()> {
337 let _ = git_repo 373 let _ = git_repo
338 .apply_patch_chain( 374 .apply_patch_chain(
339 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, 375 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
340 most_recent_proposal_patch_chain, 376 most_recent_proposal_patch_chain_or_pr_or_pr_update,
341 ) 377 )
342 .context("failed to apply patch chain")?; 378 .context("failed to apply patch chain")?;
343 379
@@ -347,8 +383,8 @@ pub async fn launch() -> Result<()> {
347 ); 383 );
348 Ok(()) 384 Ok(())
349 } 385 }
350 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 386 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update),
351 2 => save_patches_to_dir(most_recent_proposal_patch_chain, &git_repo), 387 2 => save_patches_to_dir(most_recent_proposal_patch_chain_or_pr_or_pr_update, &git_repo),
352 3 => continue, 388 3 => continue,
353 _ => { 389 _ => {
354 bail!("unexpected choice") 390 bail!("unexpected choice")
@@ -382,7 +418,7 @@ pub async fn launch() -> Result<()> {
382 .with_choices(vec![ 418 .with_choices(vec![
383 format!( 419 format!(
384 "checkout proposal branch ({} ahead {} behind '{main_branch_name}')", 420 "checkout proposal branch ({} ahead {} behind '{main_branch_name}')",
385 most_recent_proposal_patch_chain.len(), 421 most_recent_proposal_patch_chain_or_pr_or_pr_update.len(),
386 proposal_behind_main.len(), 422 proposal_behind_main.len(),
387 ), 423 ),
388 format!("apply to current branch with `git am`"), 424 format!("apply to current branch with `git am`"),
@@ -401,8 +437,13 @@ pub async fn launch() -> Result<()> {
401 ); 437 );
402 Ok(()) 438 Ok(())
403 } 439 }
404 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 440 1 => {
405 2 => save_patches_to_dir(most_recent_proposal_patch_chain, &git_repo), 441 launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update)
442 }
443 2 => save_patches_to_dir(
444 most_recent_proposal_patch_chain_or_pr_or_pr_update,
445 &git_repo,
446 ),
406 3 => continue, 447 3 => continue,
407 _ => { 448 _ => {
408 bail!("unexpected choice") 449 bail!("unexpected choice")
@@ -414,11 +455,14 @@ pub async fn launch() -> Result<()> {
414 git_repo.get_commits_ahead_behind(&master_tip, &local_branch_tip)?; 455 git_repo.get_commits_ahead_behind(&master_tip, &local_branch_tip)?;
415 456
416 // new appendments to proposal 457 // new appendments to proposal
417 if let Some(index) = most_recent_proposal_patch_chain.iter().position(|patch| { 458 if let Some(index) = most_recent_proposal_patch_chain_or_pr_or_pr_update
418 get_commit_id_from_patch(patch) 459 .iter()
419 .unwrap_or_default() 460 .position(|patch| {
420 .eq(&local_branch_tip.to_string()) 461 get_commit_id_from_patch(patch)
421 }) { 462 .unwrap_or_default()
463 .eq(&local_branch_tip.to_string())
464 })
465 {
422 return match Interactor::default().choice( 466 return match Interactor::default().choice(
423 PromptChoiceParms::default() 467 PromptChoiceParms::default()
424 .with_default(0) 468 .with_default(0)
@@ -437,7 +481,7 @@ pub async fn launch() -> Result<()> {
437 let _ = git_repo 481 let _ = git_repo
438 .apply_patch_chain( 482 .apply_patch_chain(
439 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, 483 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
440 most_recent_proposal_patch_chain, 484 most_recent_proposal_patch_chain_or_pr_or_pr_update,
441 ) 485 )
442 .context("failed to apply patch chain")?; 486 .context("failed to apply patch chain")?;
443 println!( 487 println!(
@@ -448,8 +492,13 @@ pub async fn launch() -> Result<()> {
448 ); 492 );
449 Ok(()) 493 Ok(())
450 } 494 }
451 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 495 1 => {
452 2 => save_patches_to_dir(most_recent_proposal_patch_chain, &git_repo), 496 launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update)
497 }
498 2 => save_patches_to_dir(
499 most_recent_proposal_patch_chain_or_pr_or_pr_update,
500 &git_repo,
501 ),
453 3 => continue, 502 3 => continue,
454 _ => { 503 _ => {
455 bail!("unexpected choice") 504 bail!("unexpected choice")
@@ -467,7 +516,7 @@ pub async fn launch() -> Result<()> {
467 }) { 516 }) {
468 println!( 517 println!(
469 "updated proposal available ({} ahead {} behind '{main_branch_name}'). existing version is {} ahead {} behind '{main_branch_name}'", 518 "updated proposal available ({} ahead {} behind '{main_branch_name}'). existing version is {} ahead {} behind '{main_branch_name}'",
470 most_recent_proposal_patch_chain.len(), 519 most_recent_proposal_patch_chain_or_pr_or_pr_update.len(),
471 proposal_behind_main.len(), 520 proposal_behind_main.len(),
472 local_ahead_of_main.len(), 521 local_ahead_of_main.len(),
473 local_beind_main.len(), 522 local_beind_main.len(),
@@ -492,11 +541,11 @@ pub async fn launch() -> Result<()> {
492 git_repo.checkout( 541 git_repo.checkout(
493 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, 542 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
494 )?; 543 )?;
495 let chain_length = most_recent_proposal_patch_chain.len(); 544 let chain_length = most_recent_proposal_patch_chain_or_pr_or_pr_update.len();
496 let _ = git_repo 545 let _ = git_repo
497 .apply_patch_chain( 546 .apply_patch_chain(
498 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, 547 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
499 most_recent_proposal_patch_chain, 548 most_recent_proposal_patch_chain_or_pr_or_pr_update,
500 ) 549 )
501 .context("failed to apply patch chain")?; 550 .context("failed to apply patch chain")?;
502 println!( 551 println!(
@@ -520,8 +569,13 @@ pub async fn launch() -> Result<()> {
520 ); 569 );
521 Ok(()) 570 Ok(())
522 } 571 }
523 2 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 572 2 => {
524 3 => save_patches_to_dir(most_recent_proposal_patch_chain, &git_repo), 573 launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update)
574 }
575 3 => save_patches_to_dir(
576 most_recent_proposal_patch_chain_or_pr_or_pr_update,
577 &git_repo,
578 ),
525 4 => continue, 579 4 => continue,
526 _ => { 580 _ => {
527 bail!("unexpected choice") 581 bail!("unexpected choice")
@@ -581,7 +635,7 @@ pub async fn launch() -> Result<()> {
581 if git_repo.does_commit_exist(&proposal_tip.to_string())? { 635 if git_repo.does_commit_exist(&proposal_tip.to_string())? {
582 println!( 636 println!(
583 "you have previously applied the latest version of the proposal ({} ahead {} behind '{main_branch_name}') but your local proposal branch has amended or rebased it ({} ahead {} behind '{main_branch_name}')", 637 "you have previously applied the latest version of the proposal ({} ahead {} behind '{main_branch_name}') but your local proposal branch has amended or rebased it ({} ahead {} behind '{main_branch_name}')",
584 most_recent_proposal_patch_chain.len(), 638 most_recent_proposal_patch_chain_or_pr_or_pr_update.len(),
585 proposal_behind_main.len(), 639 proposal_behind_main.len(),
586 local_ahead_of_main.len(), 640 local_ahead_of_main.len(),
587 local_beind_main.len(), 641 local_beind_main.len(),
@@ -594,7 +648,7 @@ pub async fn launch() -> Result<()> {
594 "your local proposal branch ({} ahead {} behind '{main_branch_name}') has conflicting changes with the latest published proposal ({} ahead {} behind '{main_branch_name}')", 648 "your local proposal branch ({} ahead {} behind '{main_branch_name}') has conflicting changes with the latest published proposal ({} ahead {} behind '{main_branch_name}')",
595 local_ahead_of_main.len(), 649 local_ahead_of_main.len(),
596 local_beind_main.len(), 650 local_beind_main.len(),
597 most_recent_proposal_patch_chain.len(), 651 most_recent_proposal_patch_chain_or_pr_or_pr_update.len(),
598 proposal_behind_main.len(), 652 proposal_behind_main.len(),
599 ); 653 );
600 654
@@ -639,11 +693,11 @@ pub async fn launch() -> Result<()> {
639 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, 693 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
640 &proposal_base_commit.to_string(), 694 &proposal_base_commit.to_string(),
641 )?; 695 )?;
642 let chain_length = most_recent_proposal_patch_chain.len(); 696 let chain_length = most_recent_proposal_patch_chain_or_pr_or_pr_update.len();
643 let _ = git_repo 697 let _ = git_repo
644 .apply_patch_chain( 698 .apply_patch_chain(
645 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, 699 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
646 most_recent_proposal_patch_chain, 700 most_recent_proposal_patch_chain_or_pr_or_pr_update,
647 ) 701 )
648 .context("failed to apply patch chain")?; 702 .context("failed to apply patch chain")?;
649 703
@@ -658,8 +712,11 @@ pub async fn launch() -> Result<()> {
658 ); 712 );
659 Ok(()) 713 Ok(())
660 } 714 }
661 2 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 715 2 => launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update),
662 3 => save_patches_to_dir(most_recent_proposal_patch_chain, &git_repo), 716 3 => save_patches_to_dir(
717 most_recent_proposal_patch_chain_or_pr_or_pr_update,
718 &git_repo,
719 ),
663 4 => continue, 720 4 => continue,
664 _ => { 721 _ => {
665 bail!("unexpected choice") 722 bail!("unexpected choice")