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/init.rs16
-rw-r--r--src/bin/ngit/sub_commands/list.rs211
2 files changed, 145 insertions, 82 deletions
diff --git a/src/bin/ngit/sub_commands/init.rs b/src/bin/ngit/sub_commands/init.rs
index 1242e45..eaaf83d 100644
--- a/src/bin/ngit/sub_commands/init.rs
+++ b/src/bin/ngit/sub_commands/init.rs
@@ -229,7 +229,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {
229 .map(std::string::ToString::to_string) 229 .map(std::string::ToString::to_string)
230 .collect::<Vec<String>>() 230 .collect::<Vec<String>>()
231 } else { 231 } else {
232 client.get_fallback_relays().clone() 232 client.get_relay_default_set().clone()
233 } 233 }
234 } else { 234 } else {
235 args.relays.clone() 235 args.relays.clone()
@@ -252,14 +252,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {
252 args.blossoms.clone() 252 args.blossoms.clone()
253 }; 253 };
254 254
255 let fallback_grasp_servers = 255 let fallback_grasp_servers = client.get_grasp_default_set();
256 if let Ok(Some(s)) = git_repo.get_git_config_item("nostr.grasp-default-set", None) {
257 s.split(';')
258 .filter_map(|url| normalize_grasp_server_url(url).ok()) // Attempt to parse and filter out errors
259 .collect()
260 } else {
261 vec!["relay.ngit.dev".to_string(), "gitnostr.com".to_string()]
262 };
263 256
264 let selected_grasp_servers = if has_server_and_relay_flags { 257 let selected_grasp_servers = if has_server_and_relay_flags {
265 // ignore so a script running `ngit init` can contiue without prompts 258 // ignore so a script running `ngit init` can contiue without prompts
@@ -269,14 +262,13 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {
269 repo_ref.as_ref(), 262 repo_ref.as_ref(),
270 &args.relays, 263 &args.relays,
271 &args.clone_url, 264 &args.clone_url,
272 &args.blossoms,
273 &identifier, 265 &identifier,
274 ); 266 );
275 let mut selections: Vec<bool> = vec![true; options.len()]; // Initialize selections based on existing options 267 let mut selections: Vec<bool> = vec![true; options.len()]; // Initialize selections based on existing options
276 let empty = options.is_empty(); 268 let empty = options.is_empty();
277 for fallback in fallback_grasp_servers { 269 for fallback in fallback_grasp_servers {
278 // Check if any option contains the fallback as a substring 270 // Check if any option contains the fallback as a substring
279 if !options.iter().any(|option| option.contains(&fallback)) { 271 if !options.iter().any(|option| option.contains(fallback)) {
280 options.push(fallback.clone()); // Add fallback if not found 272 options.push(fallback.clone()); // Add fallback if not found
281 selections.push(empty); // mark as selected if no existing ngit relay otherwise not 273 selections.push(empty); // mark as selected if no existing ngit relay otherwise not
282 } 274 }
@@ -464,7 +456,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {
464 let mut selections: Vec<bool> = vec![true; options.len()]; 456 let mut selections: Vec<bool> = vec![true; options.len()];
465 457
466 // add fallback relays as options 458 // add fallback relays as options
467 for relay in client.get_fallback_relays().clone() { 459 for relay in client.get_relay_default_set().clone() {
468 if !options.iter().any(|r| r.contains(&relay)) 460 if !options.iter().any(|r| r.contains(&relay))
469 && !formatted_selected_grasp_servers 461 && !formatted_selected_grasp_servers
470 .iter() 462 .iter()
diff --git a/src/bin/ngit/sub_commands/list.rs b/src/bin/ngit/sub_commands/list.rs
index 0330be1..0083c91 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, get_status, status_kinds, tag_value,
10 }, 12 },
11}; 13};
12use nostr_sdk::Kind; 14use nostr_sdk::Kind;
@@ -70,26 +72,15 @@ pub async fn launch() -> Result<()> {
70 72
71 let proposals: Vec<nostr::Event> = proposals_and_revisions 73 let proposals: Vec<nostr::Event> = proposals_and_revisions
72 .iter() 74 .iter()
73 .filter(|e| !event_is_revision_root(e)) 75 .filter(|e|
76 // If we wanted to treat to list Pull Requests that revise a Patch we would do this:
77 // e.kind.eq(&KIND_PULL_REQUEST) ||
78 !event_is_revision_root(e))
74 .cloned() 79 .cloned()
75 .collect(); 80 .collect();
76 81
77 for proposal in &proposals { 82 for proposal in &proposals {
78 let status = if let Some(e) = statuses 83 let status = get_status(proposal, &repo_ref, &statuses, &proposals);
79 .iter()
80 .filter(|e| {
81 status_kinds().contains(&e.kind)
82 && e.tags.iter().any(|t| {
83 t.as_slice().len() > 1 && t.as_slice()[1].eq(&proposal.id.to_string())
84 })
85 })
86 .collect::<Vec<&nostr::Event>>()
87 .first()
88 {
89 e.kind
90 } else {
91 Kind::GitStatusOpen
92 };
93 if status.eq(&Kind::GitStatusOpen) { 84 if status.eq(&Kind::GitStatusOpen) {
94 open_proposals.push(proposal); 85 open_proposals.push(proposal);
95 } else if status.eq(&Kind::GitStatusClosed) { 86 } else if status.eq(&Kind::GitStatusClosed) {
@@ -184,21 +175,22 @@ pub async fn launch() -> Result<()> {
184 let cover_letter = event_to_cover_letter(proposals_for_status[selected_index]) 175 let cover_letter = event_to_cover_letter(proposals_for_status[selected_index])
185 .context("failed to extract proposal details from proposal root event")?; 176 .context("failed to extract proposal details from proposal root event")?;
186 177
187 let commits_events: Vec<nostr::Event> = get_all_proposal_patch_events_from_cache( 178 let commits_events: Vec<nostr::Event> =
188 git_repo_path, 179 get_all_proposal_patch_pr_pr_update_events_from_cache(
189 &repo_ref, 180 git_repo_path,
190 &proposals_for_status[selected_index].id, 181 &repo_ref,
191 ) 182 &proposals_for_status[selected_index].id,
192 .await?; 183 )
184 .await?;
193 185
194 let Ok(most_recent_proposal_patch_chain) = 186 let Ok(most_recent_proposal_patch_chain_or_pr_or_pr_update) =
195 get_most_recent_patch_with_ancestors(commits_events.clone()) 187 get_pr_tip_event_or_most_recent_patch_with_ancestors(commits_events.clone())
196 else { 188 else {
197 if Interactor::default().confirm( 189 if Interactor::default().confirm(
198 PromptConfirmParms::default() 190 PromptConfirmParms::default()
199 .with_default(true) 191 .with_default(true)
200 .with_prompt( 192 .with_prompt(
201 "failed to find any patches on this proposal. choose another proposal?", 193 "failed to find any PR or patch events on this proposal. choose another proposal?",
202 ), 194 ),
203 )? { 195 )? {
204 continue; 196 continue;
@@ -208,15 +200,60 @@ pub async fn launch() -> Result<()> {
208 // for commit in &most_recent_proposal_patch_chain { 200 // for commit in &most_recent_proposal_patch_chain {
209 // println!("recent_event: {:?}", commit.as_json()); 201 // println!("recent_event: {:?}", commit.as_json());
210 // } 202 // }
203 if most_recent_proposal_patch_chain_or_pr_or_pr_update
204 .iter()
205 .any(|e| [KIND_PULL_REQUEST, KIND_PULL_REQUEST_UPDATE].contains(&e.kind))
206 {
207 match Interactor::default().choice(
208 PromptChoiceParms::default()
209 .with_prompt(
210 "this is new PR event kind which isn't supported in `ngit list` yet",
211 )
212 .with_default(0)
213 .with_choices(
214 if [Kind::GitStatusOpen, Kind::GitStatusDraft].contains(&selected_status)
215 && git_repo
216 .get_first_nostr_remote_when_in_ngit_binary()
217 .await
218 .is_ok_and(|r| r.is_some())
219 {
220 vec![
221 format!(
222 "I'll manually checkout the proposal at remote branch '{}'",
223 cover_letter
224 .get_branch_name_with_pr_prefix_and_shorthand_id()
225 .unwrap()
226 ),
227 // TODO fetch oids and follow similar logic for dealing with
228 // conflcts as with patches below
229 "back to proposals".to_string(),
230 ]
231 } else {
232 vec!["back to proposals".to_string()]
233 },
234 ),
235 )? {
236 0 => continue,
237 _ => {
238 bail!("unexpected choice")
239 }
240 };
241 }
211 242
212 let binding_patch_text_ref = format!("{} commits", most_recent_proposal_patch_chain.len()); 243 let binding_patch_text_ref = format!(
213 let patch_text_ref = if most_recent_proposal_patch_chain.len().gt(&1) { 244 "{} commits",
245 most_recent_proposal_patch_chain_or_pr_or_pr_update.len()
246 );
247 let patch_text_ref = if most_recent_proposal_patch_chain_or_pr_or_pr_update
248 .len()
249 .gt(&1)
250 {
214 binding_patch_text_ref.as_str() 251 binding_patch_text_ref.as_str()
215 } else { 252 } else {
216 "1 commit" 253 "1 commit"
217 }; 254 };
218 255
219 let no_support_for_patches_as_branch = most_recent_proposal_patch_chain 256 let no_support_for_patches_as_branch = most_recent_proposal_patch_chain_or_pr_or_pr_update
220 .iter() 257 .iter()
221 .any(|event| !patch_supports_commit_ids(event)); 258 .any(|event| !patch_supports_commit_ids(event));
222 259
@@ -226,16 +263,18 @@ pub async fn launch() -> Result<()> {
226 PromptChoiceParms::default() 263 PromptChoiceParms::default()
227 .with_default(0) 264 .with_default(0)
228 .with_choices(vec![ 265 .with_choices(vec![
229 "learn why 'patch only' proposals can't be checked out".to_string(), 266 "learn why this proposals can't be checked out".to_string(),
230 format!("apply to current branch with `git am`"), 267 format!("apply to current branch with `git am`"),
231 format!("download to ./patches"), 268 format!("download to ./patches"),
232 "back".to_string(), 269 "back".to_string(),
233 ]), 270 ]),
234 )? { 271 )? {
235 0 => { 272 0 => {
236 println!("Some proposals are posted as 'patch only'\n");
237 println!( 273 println!(
238 "they are not anchored against a particular state of the code base like a standard proposal or a GitHub Pull Request can be\n" 274 "Some proposals are posted as patch without listing a parent commit\n"
275 );
276 println!(
277 "they are not anchored against a particular state of the code base like a standard patch or a pull request can be\n"
239 ); 278 );
240 println!( 279 println!(
241 "they are designed to reviewed by studying the diff (in a tool like gitworkshop.dev) and if acceptable by a maintainer, applied to the latest version of master with any conflicts resolved as the do so\n" 280 "they are designed to reviewed by studying the diff (in a tool like gitworkshop.dev) and if acceptable by a maintainer, applied to the latest version of master with any conflicts resolved as the do so\n"
@@ -244,7 +283,7 @@ pub async fn launch() -> Result<()> {
244 "this has proven to be a smoother workflow for large scale projects with a high frequency of changes, even when patches are exchanged via email\n" 283 "this has proven to be a smoother workflow for large scale projects with a high frequency of changes, even when patches are exchanged via email\n"
245 ); 284 );
246 println!( 285 println!(
247 "by default ngit posts proposals that support both the branch and patch model so either workflow can be used" 286 "by default ngit posts proposals with a parent commit so either workflow can be used"
248 ); 287 );
249 Interactor::default().choice( 288 Interactor::default().choice(
250 PromptChoiceParms::default() 289 PromptChoiceParms::default()
@@ -253,8 +292,13 @@ pub async fn launch() -> Result<()> {
253 )?; 292 )?;
254 continue; 293 continue;
255 } 294 }
256 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 295 1 => {
257 2 => save_patches_to_dir(most_recent_proposal_patch_chain, &git_repo), 296 launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update)
297 }
298 2 => save_patches_to_dir(
299 most_recent_proposal_patch_chain_or_pr_or_pr_update,
300 &git_repo,
301 ),
258 3 => continue, 302 3 => continue,
259 _ => { 303 _ => {
260 bail!("unexpected choice") 304 bail!("unexpected choice")
@@ -277,9 +321,11 @@ pub async fn launch() -> Result<()> {
277 .eq(&cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?); 321 .eq(&cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?);
278 322
279 let proposal_base_commit = str_to_sha1(&tag_value( 323 let proposal_base_commit = str_to_sha1(&tag_value(
280 most_recent_proposal_patch_chain.last().context( 324 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", 325 .last()
282 )?, 326 .context(
327 "there should be at least one patch as we have already checked for this",
328 )?,
283 "parent-commit", 329 "parent-commit",
284 )?) 330 )?)
285 .context("failed to get valid parent commit id from patch")?; 331 .context("failed to get valid parent commit id from patch")?;
@@ -300,8 +346,8 @@ pub async fn launch() -> Result<()> {
300 ], 346 ],
301 ))? { 347 ))? {
302 0 | 3 => continue, 348 0 | 3 => continue,
303 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 349 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), 350 2 => save_patches_to_dir(most_recent_proposal_patch_chain_or_pr_or_pr_update, &git_repo),
305 _ => { 351 _ => {
306 bail!("unexpected choice") 352 bail!("unexpected choice")
307 } 353 }
@@ -309,9 +355,13 @@ pub async fn launch() -> Result<()> {
309 } 355 }
310 356
311 let proposal_tip = str_to_sha1( 357 let proposal_tip = str_to_sha1(
312 &get_commit_id_from_patch(most_recent_proposal_patch_chain.first().context( 358 &get_commit_id_from_patch(
313 "there should be at least one patch as we have already checked for this", 359 most_recent_proposal_patch_chain_or_pr_or_pr_update
314 )?) 360 .first()
361 .context(
362 "there should be at least one patch as we have already checked for this",
363 )?,
364 )
315 .context("failed to get valid commit_id from patch")?, 365 .context("failed to get valid commit_id from patch")?,
316 ) 366 )
317 .context("failed to get valid commit_id from patch")?; 367 .context("failed to get valid commit_id from patch")?;
@@ -325,7 +375,7 @@ pub async fn launch() -> Result<()> {
325 .choice(PromptChoiceParms::default().with_default(0).with_choices(vec![ 375 .choice(PromptChoiceParms::default().with_default(0).with_choices(vec![
326 format!( 376 format!(
327 "create and checkout proposal branch ({} ahead {} behind '{main_branch_name}')", 377 "create and checkout proposal branch ({} ahead {} behind '{main_branch_name}')",
328 most_recent_proposal_patch_chain.len(), 378 most_recent_proposal_patch_chain_or_pr_or_pr_update.len(),
329 proposal_behind_main.len(), 379 proposal_behind_main.len(),
330 ), 380 ),
331 format!("apply to current branch with `git am`"), 381 format!("apply to current branch with `git am`"),
@@ -337,7 +387,7 @@ pub async fn launch() -> Result<()> {
337 let _ = git_repo 387 let _ = git_repo
338 .apply_patch_chain( 388 .apply_patch_chain(
339 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, 389 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
340 most_recent_proposal_patch_chain, 390 most_recent_proposal_patch_chain_or_pr_or_pr_update,
341 ) 391 )
342 .context("failed to apply patch chain")?; 392 .context("failed to apply patch chain")?;
343 393
@@ -347,8 +397,8 @@ pub async fn launch() -> Result<()> {
347 ); 397 );
348 Ok(()) 398 Ok(())
349 } 399 }
350 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 400 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), 401 2 => save_patches_to_dir(most_recent_proposal_patch_chain_or_pr_or_pr_update, &git_repo),
352 3 => continue, 402 3 => continue,
353 _ => { 403 _ => {
354 bail!("unexpected choice") 404 bail!("unexpected choice")
@@ -382,7 +432,7 @@ pub async fn launch() -> Result<()> {
382 .with_choices(vec![ 432 .with_choices(vec![
383 format!( 433 format!(
384 "checkout proposal branch ({} ahead {} behind '{main_branch_name}')", 434 "checkout proposal branch ({} ahead {} behind '{main_branch_name}')",
385 most_recent_proposal_patch_chain.len(), 435 most_recent_proposal_patch_chain_or_pr_or_pr_update.len(),
386 proposal_behind_main.len(), 436 proposal_behind_main.len(),
387 ), 437 ),
388 format!("apply to current branch with `git am`"), 438 format!("apply to current branch with `git am`"),
@@ -401,8 +451,13 @@ pub async fn launch() -> Result<()> {
401 ); 451 );
402 Ok(()) 452 Ok(())
403 } 453 }
404 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 454 1 => {
405 2 => save_patches_to_dir(most_recent_proposal_patch_chain, &git_repo), 455 launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update)
456 }
457 2 => save_patches_to_dir(
458 most_recent_proposal_patch_chain_or_pr_or_pr_update,
459 &git_repo,
460 ),
406 3 => continue, 461 3 => continue,
407 _ => { 462 _ => {
408 bail!("unexpected choice") 463 bail!("unexpected choice")
@@ -414,11 +469,14 @@ pub async fn launch() -> Result<()> {
414 git_repo.get_commits_ahead_behind(&master_tip, &local_branch_tip)?; 469 git_repo.get_commits_ahead_behind(&master_tip, &local_branch_tip)?;
415 470
416 // new appendments to proposal 471 // new appendments to proposal
417 if let Some(index) = most_recent_proposal_patch_chain.iter().position(|patch| { 472 if let Some(index) = most_recent_proposal_patch_chain_or_pr_or_pr_update
418 get_commit_id_from_patch(patch) 473 .iter()
419 .unwrap_or_default() 474 .position(|patch| {
420 .eq(&local_branch_tip.to_string()) 475 get_commit_id_from_patch(patch)
421 }) { 476 .unwrap_or_default()
477 .eq(&local_branch_tip.to_string())
478 })
479 {
422 return match Interactor::default().choice( 480 return match Interactor::default().choice(
423 PromptChoiceParms::default() 481 PromptChoiceParms::default()
424 .with_default(0) 482 .with_default(0)
@@ -437,7 +495,7 @@ pub async fn launch() -> Result<()> {
437 let _ = git_repo 495 let _ = git_repo
438 .apply_patch_chain( 496 .apply_patch_chain(
439 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, 497 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
440 most_recent_proposal_patch_chain, 498 most_recent_proposal_patch_chain_or_pr_or_pr_update,
441 ) 499 )
442 .context("failed to apply patch chain")?; 500 .context("failed to apply patch chain")?;
443 println!( 501 println!(
@@ -448,8 +506,13 @@ pub async fn launch() -> Result<()> {
448 ); 506 );
449 Ok(()) 507 Ok(())
450 } 508 }
451 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 509 1 => {
452 2 => save_patches_to_dir(most_recent_proposal_patch_chain, &git_repo), 510 launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update)
511 }
512 2 => save_patches_to_dir(
513 most_recent_proposal_patch_chain_or_pr_or_pr_update,
514 &git_repo,
515 ),
453 3 => continue, 516 3 => continue,
454 _ => { 517 _ => {
455 bail!("unexpected choice") 518 bail!("unexpected choice")
@@ -467,7 +530,7 @@ pub async fn launch() -> Result<()> {
467 }) { 530 }) {
468 println!( 531 println!(
469 "updated proposal available ({} ahead {} behind '{main_branch_name}'). existing version is {} ahead {} behind '{main_branch_name}'", 532 "updated proposal available ({} ahead {} behind '{main_branch_name}'). existing version is {} ahead {} behind '{main_branch_name}'",
470 most_recent_proposal_patch_chain.len(), 533 most_recent_proposal_patch_chain_or_pr_or_pr_update.len(),
471 proposal_behind_main.len(), 534 proposal_behind_main.len(),
472 local_ahead_of_main.len(), 535 local_ahead_of_main.len(),
473 local_beind_main.len(), 536 local_beind_main.len(),
@@ -492,11 +555,11 @@ pub async fn launch() -> Result<()> {
492 git_repo.checkout( 555 git_repo.checkout(
493 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, 556 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
494 )?; 557 )?;
495 let chain_length = most_recent_proposal_patch_chain.len(); 558 let chain_length = most_recent_proposal_patch_chain_or_pr_or_pr_update.len();
496 let _ = git_repo 559 let _ = git_repo
497 .apply_patch_chain( 560 .apply_patch_chain(
498 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, 561 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
499 most_recent_proposal_patch_chain, 562 most_recent_proposal_patch_chain_or_pr_or_pr_update,
500 ) 563 )
501 .context("failed to apply patch chain")?; 564 .context("failed to apply patch chain")?;
502 println!( 565 println!(
@@ -520,8 +583,13 @@ pub async fn launch() -> Result<()> {
520 ); 583 );
521 Ok(()) 584 Ok(())
522 } 585 }
523 2 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 586 2 => {
524 3 => save_patches_to_dir(most_recent_proposal_patch_chain, &git_repo), 587 launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update)
588 }
589 3 => save_patches_to_dir(
590 most_recent_proposal_patch_chain_or_pr_or_pr_update,
591 &git_repo,
592 ),
525 4 => continue, 593 4 => continue,
526 _ => { 594 _ => {
527 bail!("unexpected choice") 595 bail!("unexpected choice")
@@ -581,7 +649,7 @@ pub async fn launch() -> Result<()> {
581 if git_repo.does_commit_exist(&proposal_tip.to_string())? { 649 if git_repo.does_commit_exist(&proposal_tip.to_string())? {
582 println!( 650 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}')", 651 "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(), 652 most_recent_proposal_patch_chain_or_pr_or_pr_update.len(),
585 proposal_behind_main.len(), 653 proposal_behind_main.len(),
586 local_ahead_of_main.len(), 654 local_ahead_of_main.len(),
587 local_beind_main.len(), 655 local_beind_main.len(),
@@ -594,7 +662,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}')", 662 "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(), 663 local_ahead_of_main.len(),
596 local_beind_main.len(), 664 local_beind_main.len(),
597 most_recent_proposal_patch_chain.len(), 665 most_recent_proposal_patch_chain_or_pr_or_pr_update.len(),
598 proposal_behind_main.len(), 666 proposal_behind_main.len(),
599 ); 667 );
600 668
@@ -639,11 +707,11 @@ pub async fn launch() -> Result<()> {
639 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, 707 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
640 &proposal_base_commit.to_string(), 708 &proposal_base_commit.to_string(),
641 )?; 709 )?;
642 let chain_length = most_recent_proposal_patch_chain.len(); 710 let chain_length = most_recent_proposal_patch_chain_or_pr_or_pr_update.len();
643 let _ = git_repo 711 let _ = git_repo
644 .apply_patch_chain( 712 .apply_patch_chain(
645 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, 713 &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?,
646 most_recent_proposal_patch_chain, 714 most_recent_proposal_patch_chain_or_pr_or_pr_update,
647 ) 715 )
648 .context("failed to apply patch chain")?; 716 .context("failed to apply patch chain")?;
649 717
@@ -658,8 +726,11 @@ pub async fn launch() -> Result<()> {
658 ); 726 );
659 Ok(()) 727 Ok(())
660 } 728 }
661 2 => launch_git_am_with_patches(most_recent_proposal_patch_chain), 729 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), 730 3 => save_patches_to_dir(
731 most_recent_proposal_patch_chain_or_pr_or_pr_update,
732 &git_repo,
733 ),
663 4 => continue, 734 4 => continue,
664 _ => { 735 _ => {
665 bail!("unexpected choice") 736 bail!("unexpected choice")